什么是Boot loader?
Boot loader(系统引导程序),操作系统内核运行之前运行的一段程序。它首先完成系统硬件的初始化,包括时钟的设置、存储区的映射等,设置堆栈指针等;然后把操作系统内核从flash区拷贝带ram区,并跳转到内核的入口,将系统的控制权交给操作系统,从此系统的运行和Boot loader再无任何关系。
Boot loader的特点
- 高度依赖于硬件,包括处理机的体系结构、具体型号、硬件电路板的设计。
- 不存在通用的Boot Loader,但存在Boot Loader的通用概念和规则
- 宿主主机和目标机之间一般通过串口连接
Boot loader的启动过程
单阶段和多阶段(更复杂、具有更好的移植性)
Boot loader的两个操作模式
- 启动加载(正常使用):即Boot Loader从目标机上的某个固态存储器上将操作系统加载到ram中运行,整个过程没有用户的介入。
- 下载模式(开发人员用):目标机上的Boot Loader将通过串口或网络连接从主机上下载文件,例如内核映像和根文件系统等。下载的文件首先放在ram中,然后被Boot Loader写到固态存储器中。这种模式通常在第一次安装内核与根文件系统时使用。
重点Boot Loader介绍
- LILO:Linux草创时期提出的Boot loader,有详细的文档。
- GRUB:GNU计划的主要Boot loader。
- Blob:使用广泛
- U-Boot:功能最多、最具弹性以及开发最积极的开放源码Boot loader。
- vivi:由mizi公司为ARM处理器系列设计的一个Boot loader,目前只支持使用串口和主机通信,所以必须使用一条串口来连接目标板和主机。
下面是一段Boot loader的简单实现汇编代码,我简述一下各部分的功能。(看蓝色代码部分)
-
对不同控制寄存器的地址重新命名,使用起来方便一点。
-
程序开始,b是一条无条件跳转指令,程序一旦启动,直接跳转到reset处执行命令。
-
中断向量表
-
十三行的长整型数据是存放在标号为MEMORY_CONFIG之下的用于配置内存的13个配置字。对于arm处理器来说,我们要配置它的13个内存控制寄存器,且地址需连续,需要提前设计好每个寄存器的配置字。连续存放,以便后面统一地写到那13个寄存器中,避免一个一个进行赋值。
-
最前面的reset部分。因为程序刚刚启动,需要做一些初始化等比较重要的操作,在做这些操作时,处理器不希望被打断,所以将看门狗定时器关闭掉。
-
因为需要E口进行对串口的访问,所以这一段是对E口的配置
-
设置系统时钟,需要查数据手册,看每一个寄存器,给它进行如何的配置。
-
设置存储器,将MEMORY_CONFIG包含13个内存控制寄存器配置字的首地址给r0,然后给r1-r13,内存控制寄存器的首地址给r0,然后把13个配置字送到r0指向的空间,完成把用于控制内存的13个配置字整体写入配置寄存器当中。
-
完成Boot Loader的主要功能:
把flash源地址中的头送给r0
把flash目的地址中的头送给r1
加法指令,加的数是操作系统内核的大小,r2表示在flash中操作系统内核的终止地址
内核的拷贝
源地址拷了八个出来送给r3-r10,然后拷贝到目的地址,感叹号表示数据拷贝完后指针同步移动
检查是否拷贝完毕,直到所有内核拷贝到ram中
-
控制权交给ram中的操作系统的内核