IT门户, 中国互联网人工智能物联网行业资讯平台--公众IT
新闻来源:互联网资料整理       发布时间:2023/4/7 4:52:55       共计:4595 浏览

简述Boot Loader的功能和启动过程?

作用原理

编辑

⒈ Boot Loader 所支持的 CPU 和嵌入式板

每种不同的 CPU 体系结构都有不同的Boot Loader。有些 Boot Loader 也支持多种体系结构的 CPU,比如 U-Boot 就同时支持 ARM 体系结构和MIPS 体系结构。除了依赖于 CPU的体系结构外,Boot Loader 实际上也依赖于具体的嵌入式板级设备的配置。这也就是说,对于两块不同的嵌入式板而言,即使它们是基于同一种 CPU 而构建的,要想让运行在一块板子上的 Boot Loader 程序也能运行在另一块板子上,通常也都需要修改 Boot Loader 的源程序。

⒉ Boot Loader 的安装媒介(Installation Medium)

系统加电或复位后,所有的CPU 通常都从某个由 CPU 制造商预先安排的地址上取指令。比如,基于 ARM7TDMI core 的 CPU 在复位时通常都从地址 0x00000000 取它的第一条指令。而基于CPU 构建的嵌入式系统通常都有某种类型的固态存储设备(比如:ROM、EEPROM 或 FLASH 等)被映射到这个预先安排的地址上。因此在系统加电后,CPU 将首先执行Boot Loader 程序。

⒊ 用来控制 Boot Loader 的设备或机制

主机和目标机之间一般通过串口建立连接,Boot Loader 软件在执行时通常会通过串口来进行输入、输出,比如:输出打印信息到串口,从串口读取用户控制字符等。

⒋ Boot Loader 的启动过程

BootLoader 的启动过程可分为单阶段(Single-Stage)和多阶段(Multi-Stage)两种。通常多阶段的Boot Loader 具有更复杂的功能,更好的可移植性。从固态存储设备上启动的Boot Loader 大多采用两阶段,即启动过程可以分为 stage1和stage2:stage1完成初始化硬件,为stage2准备内存空间,并将stage2复制到内存中,设置堆栈,然后跳转到stage2。

⒌ Boot Loader 的操作模式 (Operation Mode)

大多数Boot Loader都包含两种不同的操作模式。启动加载模式和下载模式。

(1)启动加载(Boot loading)模式:这种模式也称为“自主”模式,也即Boot Loader从目标机上的某个固态存储设备上将操作系统加载到RAM中运行,整个过程并没有用户的介入。这种模式是Boot Loader的正常工作模式。

(2)下载(Down loading)模式:在这种模式下目标机上的Boot Loader将通过串口连接或网络连接等通信手段从主机下载文件。从主机下载的文件通常首先被Boot Loader保存到目标机的RAM中然后再被Boot Loader写到目标机上的固态存储设备中。

⒍ Boot Loader 与主机之间进行文件传输所用的通信设备及协议

分为两种情况。一种是目标机使用串口与主机相连。这时的传输协议通常是xmodem/ymodem/zmodem中的一种。第二种可以用网络连接的方式传输文件,这时使用的协议多为tftp。


解析

编辑

网上关于Linux的BOOTLOADER文章不少了,但是大都是vivi,blob等比较庞大的程序,读起来不太方便,编译出的文件也比较大,而且更多的是面向开发用的引导代码,做成产品时还要裁减,这一定程度影响了开发速度,对初学者学习开销也比较大,在此分析一种简单的BOOTLOADER,是在三星公司提供的2410 BOOTLOADER上稍微修改后的结果,编译出来的文件大小不超过4k,希望对大家有所帮助.


重要概念

COMPRESSED KERNEL and DECOMPRESSED KERNEL

压缩后的KERNEL,按照文档资料,现在不提倡使用DECOMPRESSED KERNEL,而要使用COMPRESSED KERNEL,它包括了解压器.因此要在ram分配时给压缩和解压的KERNEL提供足够空间,这样它们不会相互覆盖.

当执行指令跳转到COMPRESSED KERNEL后,解压器就开始工作,如果解压器探测到解压的代码会覆盖掉COMPRESSED KERNEL,那它会直接跳到COMPRESSED KERNEL后存放数据,并且重新定位KERNEL,所以如果没有足够空间,就会出错.

Jffs2 File System

可以使armlinux应用中产生的数据保存在FLASH上,我的板子还没用到这个.

RAMDISK

使用RAMDISK可以使ROOT FILE SYSTEM在没有其他设备的情况下启动.一般有两种加载方式,最常用的一种是,把COMPRESSED RAMDISK IMAGE放到指定地址,然后由BOOTLOADER把这个地址通过启动参数的方式ATAG_INITRD2传递给KERNEL.具体看代码分析.

启动参数(摘自IBM developer)

在调用内核之前,应该作一步准备工作,即:设置 Linux 内核的启动参数。Linux 2.4.x 以后的内核都期望以标记列表(tagged list)的形式来传递启动参数。启动参数标记列表以标记 ATAG_CORE 开始,以标记 ATAG_NONE 结束。每个标记由标识被传递参数的 tag_header 结构以及随后的参数值数据结构来组成。数据结构 tag 和 tag_header 定义在 Linux 内核源码的include/asm/setup.h 头文件中.

在嵌入式 Linux 系统中,通常需要由 BOOTLOADER 设置的常见启动参数有:ATAG_CORE、ATAG_MEM、ATAG_CMDLINE、ATAG_RAMDISK、ATAG_INITRD等。

(注)参数也可以用COMMANDLINE来设定,在我的BOOTLOADER里,我两种都用了.


开发环境

CPU:S3C2410,BANK6上有64M的SDRAM(两块),BANK0上有32M NOR FLASH,串口当然是逃不掉的.这样,按照数据手册,地址分配如下:

0x4000_0000开始是4k的片内DRAM.

0x0000_0000开始是32M FLASH 16bit宽度

0x3000_0000开始是64M SDRAM 32bit宽度

注意:控制寄存器中的BANK6和BANK7部分必须相同.

0x4000_0000(片内DRAM)存放4k以内的BOOTLOADER IMAGE

0x3000_0100开始存放启动参数

0x3120_0000 存放COMPRESSED KERNEL IMAGE

0x3200_0000 存放COMPRESSED RAMDISK

0x3000_8000 指定为DECOMPRESSED KERNEL IMAGE ADDRESS

0x3040_0000 指定为DECOMPRESSED RAMDISK IMAGE ADDRESS

开发环境:Redhat Linux,armgcc toolchain,armlinux KERNEL

如何建立armgcc的编译环境:建议使用toolchain,而不要自己去编译armgcc,偶试过好多次,都以失败告终.

先下载arm-gcc 3.3.2 toolchain

将arm-linux-gcc-3.3.2.tar.bz2 解压到 /toolchain

tar jxvf arm-linux-gcc-3.3.2.tar.bz2

mv /usr/local/arm/3.3.2 /toolchain

在makefile 中在把arch=arm CROSS_COMPILE设置成toolchain的路径

还有就是INCLUDE = -I ../include -I /root/my/usr/local/arm/3.3.2/include.,否则库函数就不能用了


启动方式

可以放在FLASH里启动,或者用Jtag仿真器.由于使用NOR FLASH,根据2410的手册,片内的4K DRAM在不需要设置便可以直接使用,而其他存储器必须先初始化,比如告诉memory controller,BANK6里有两块SDRAM,数据宽度是32bit,= =.否则memory control会按照复位后的默认值来处理存储器.这样读写就会产生错误.

所以第一步,通过仿真器把执行代码放到0x4000_0000,(在编译的时候,设定TEXT_BAS

E=0x40000000)

第二步,通过 AxD把linux KERNEL IMAGE放到目标地址(SDRAM)中,等待调用

第三步,执行BOOTLOADER代码,从串口得到调试数据,引导armlinux


代码分析

讲了那么多执行的步骤,是想让大家对启动有个大概印象,接着就是BOOTLOADER内部的代码分析了,BOOTLOADER文章内容网上很多,我这里精简了下,删除了不必要的功能.

BOOTLOADER一般分为2部分,汇编部分和c语言部分,汇编部分执行简单的硬件初始化,C部分负责复制数据,设置启动参数,串口通信等功能.

BOOTLOADER的生命周期:

⒈ 初始化硬件,比如设置UART(至少设置一个),检测存储器= =.

⒉ 设置启动参数,这是为了告诉内核硬件的信息,比如用哪个启动界面,波特率 = =.

⒊ 跳转到Linux KERNEL的首地址.

⒋ 消亡

同时在linux中 GRUB(GRand Unified Bootloader)是一个系统默认自带的多重启动管理器。它可以在多个操作系统共存时选择引导哪个系统。尽管引导操作系统看上去是件平凡且琐碎的任务,但它实际上很重要。如果引导装入器不能很好地完成工作或者不具有弹性,那么就可能锁住系统或者无法引导计算机……

如何从根本解决嵌入式Linux系统突然断电后无法启动问题?

首先你的断电是指什么?现在的手持设备都有超过3种供电电源。

那我猜的说的断电是同时切断包括电池和USB在内的所有外部电源了。那么不论你的挂载点在哪里,kernel肯定是直接down掉的,cpu状态也不会被保存,内存清空,所有进程都不存在了,已经在读的进程不再持有文件句柄(没影响),已经在写的进程就写到某个字符停住,但是这些都不会影响到硬盘啊。所以对文件系统不会有损坏,但是对硬件会有些许伤害。但现在手持设备都维持在2.5~3V,断电对硬件的影响实际也不大。至于你说的“怎么才能再以可读写属性挂载该磁盘呢”。我不理解这个“再”字。重新上电后一切重新开始,kernel boot重跑一遍,跟断电前你的挂载已经没有关系了。另一种情况,你可以在linux控制台启动句柄里面设置,把你的挂载命令写在那里面,那么每次启动时就自动挂载了

版权说明:
本网站凡注明“公众IT 原创”的皆为本站原创文章,如需转载请注明出处!
本网转载皆注明出处,遵循行业规范,如发现作品内容版权或其它问题的,请与我们联系处理!
您可以扫描右侧微信二维码联系我们。
网站首页 关于我们 联系我们 合作联系 会员说明 新闻投稿 隐私协议 网站地图