原文:http://www.arm.linux.org.uk/developer/booting.php
为了启动在ARM板上启动linux系统,需要在启动kernel之前运行一小段叫bootloader的程序,bootloader初始化各种设备后调用kernel,并向其传递一些参数;
言之,bootloader必须完成以下作用:
(1) 设置并初始化内存;
(2) 初始化一个串口;
(3) 判断平台设备类型;
(4) 设置启动参数列表;//标记列表(tagged list)
(5) 启动内核;
1 . 设置并初始话内存
bootloader用于寻找并初始化kernel启动后在RAM内存中存储的易丢失性数据,按某个机器特定方式执行(或者用基本的算法自动加载数据和计算RAM大小,或者用机器当中的RAM的信息,或者bootloader程序设计者认为合适的方式);
2 . 初始化一个串口
bootloader需要初始化并且使能一个串口,同时串口驱动能够自动探测到哪个串口端能够用于kernel的控制端,串口的目的是用于调试或者进行简单的通信;
作为一种替代,bootloader可以同“consloe = ”标记列表向kernel传递参数,指定端口的类型和串口格式选项,详细见linux/Documentation/kernel-parameters.txt.
3 . 判断平台设备类型
bootloader需要获取机器的启动方式,是否是硬件中的一些代码(IROM)或者是算法决定超出本文档的范围,bootloader最终要向kernel提供参数“MACH_TYPE_xxx”,详细见linux/arch/arm/tools/mach-types;
4 . 设置启动参数列表
bootloader必须创建并初始话一个标记列表,一个有效的标记列表是以ATAG_CORE开始,ATAG_NONE结束,ATAG_CORE标记可以为空或者不为空,一个空的ATAG_CORE域的大小设置为2,ATAG_NONE设置为0;
任何数量的标签都可以放在这个列表中,一个重复的tag追加到前一个tag的信息里,或者全部替代,有些tags重复的时候去前者,有时取后者;
bootloader必须规定所允许的系统和文件系统的大小,因此这个界限的tag因该这样:
+-----------+ base -> | ATAG_CORE | | +-----------+ | | ATAG_MEM | | increasing address +-----------+ | | ATAG_NONE | | +-----------+ vtagged list需要存储在RAM中;及不是放在压缩的kernel镜像中也不是 ”bootp“程序中,它会覆盖tagged list;推荐放在RAM第一个16KiB位置处;
5 . 启动内核
这有两种放方式调用内核,如果镜像存储在flash中,从flash启动能被正确的链接,然后就直接用bootloader调用镜像就可以了;
这镜像也有可能放在RAM某个位置然后调用,kernel会用16k大小(image前)来存放页表,所以推荐把镜像放RAM32KiB处;
不论哪种方式,下面几条必须满足:
(1) cpu寄存器设置:r0 = 0;r1 = MACH_TYPE,步骤3获取的;r2 = 物理地址或者 tagged list在RAM中位置;
(2) cpu模式:IRQs and FIQs必须禁止,cpu为SVC(超级用户)模式;
(3) 缓存和MMU:MMU和指令缓存数据缓存都需要关闭;
(4) DMA设备需要关闭;
(5) bootloader直接跳转到内核镜像的第一条指令执行kernel;