第1课-bootloader设计蓝图

bootloader,称为启动引导程序,是在操作系统内核之前运行的一小段程序,用于完成系统的相关初始化工作,比如初始化硬件,建立内存映射,初始化堆栈等,将系统的软硬件环境带到一个合适的状态,为操作系统的运行做好准备。
Alt text

bootloader是一个与具体硬件高度相关的裸机程序,设计一款自己的bootloader,可以参考现有的比较成熟的bootloader来设计,这就是uboot。uboot是一款支持多种嵌入式CPU、多种嵌入式系统的启动引导程序。uboot可以工作在两种工作模式,一种是自主模式,一般在嵌入式产品发布之后uboot工作在此模式,用于正常引导装载系统。另一种是开发模式或称为命令模式,此时uboot可以执行相关命令,或是手动下载程序。

第2课-ARM处理器启动流程

bootloader的工作流程需要按照芯片的启动流程与启动机制来设计,故需要先了解一下ARM处理器的启动过程。不同的ARM芯片支持不同的启动方式,比如从SD卡启动,从NandFlash启动等方式,以及不同的地址布局和启动流程。不同的芯片的启动流程既有相同点也有不同点,需要同时对比多款芯片,然后总结规律。

S3C2440

支持从NorFlash(2MB)和NandFlash(256MB) 启动,一般将uboot、内核、文件系统放在Nandflash中,然后设置开发板从Nandflash启动,以下是2440的内存布局。
Alt text

左侧是从Norfalsh启动时的内存布局,右侧是从Nandflash启动时的内存布局。CPU上电之后从0地址处开始取第一条指令,对于从Nandflash的启动方式而言,0地址安排的是4KB的BootSRAM,这是一块片内RAM,也称为“垫脚石”。ARM启动时会自动把Nandflash上的前4KB启动代码复制到BootSRAM,然后从BootSRAM启动,这小段启动代码会把剩余的启动代码从Nandflash拷贝到片外SDRAM,也就是设备内存,然后跳转到内存,从内存开始启动。这部分在芯片文档的第6章有描述,如下图所示:
Alt text

S3C6410

支持从SROM,Norflash,OneNAND,MODEM和IROM启动。从SD卡及Nandflash的启动方式被划规到IROM启动下面。
Alt text

以下是设备的内存布局。

Alt text

可以看到IROM的地址是0x08000000到0x0BFFFFFF,大小64MB,但实际只有32KB的存储空间,还可以看到从0x0C000000到0x0FFFFFFF是Internal SRAM,也就是垫脚石的内存空间,大小64MB,但实际只有4KB。从0x50000000开始的区域是DRAM,也就是内存的起始地址。

从0x00000000到0x07FFFFFF的128MB空间是设备上电之后最先执行指令的区间,这部分地址空间是动态映射的,内容并不固定,而是根据设备的启动配置的不同进行映射到不同的区域,比如,如果设备设置的是从IROM启动,则IROM的存储空间就会被映射到这段区域。

下面来分析6410从IROM启动时的启动流程,参考文档《S3C6410_Internal_ROM_Booting.pdf》,从IROM启动包含了从SD卡及从Nandflash启动,如下图所示:
Alt text

从IROM启动的启动流程为:

  1. 根据启动配置将IROM映射到0地址处,首先执行位于IROM上芯片厂商固化的一段启动代码,称为BL0。
  2. BL0这段代码会把SD卡或Nandflash的前4KB内容复制到IRAM,也就是垫脚石中,然后跳转到该处执行,这段代码称为BL1。
  3. BL1的代码在进行了相关的初始化后,会把剩余的启动代码BL2装载到SDRAM,也就是内存中,然后跳到内存去执行。
  4. BL2的代码会继续启动,完成内核和操作系统的装载,并最终将CPU交给操作系统执行。

通过以上过程,就完成了正常系统的启动。

S5PV210

210除了可以从各种存储设备启动外,还可以从USB和串口启动,它的启动配置如下:
Alt text
Alt text

从各种存储设备启动的方式统一划分到IROM启动下面,根据不同的引脚设置,再决定从某个具体的存储设备启动。下面是210的内存映射:
Alt text
Alt text

S5PV210有64KB的IROM和96KB的IRAM,0地址也是镜像映射区,和6410相类似。内存区域从0x20000000开始。

下面参考文档《S5PV210_iROM_ApplicationNote_Preliminary_20091126.pdf》来分析210从IROM启动时的启动流程,其启动顺序图如下图所示:
Alt text

S5PV210的IROM启动顺序如下:

  1. 先启动位于IROM上的BL0代码,BL0完成启动后的时钟,设备控制器初始化并启动设备
  2. BL0将位于外部存储设备上的BL1代码装载到IRAM,BL1最大不超过16KB
  3. BL1将继续装载外部设备上的BL2代码到IRAM,BL2最大不超过80KB
  4. BL2完成对DRAM内存的初始化后,开始装载操作系统到内存,最终跳转到操作系统的地址处开始执行。

第3课-uboot启动流程分析

  1. 寻找整个uboot的程序入口,方法是分析uboot的链接脚本,通过.text代码段确定第一个代码所在的文件,通过ENTRY宏来确定程序入口,uboot的程序入口是start.S的_start语句标号处。
  2. 从_start语句标号处开始,通过注释分析uboot每一步做了哪些事,不用关心具体怎么做的。

注意一点,uboot的链接起始地址不是由u-boot.lds决定的,而是由TEXT_BASE变量决定的,这个可以从uboot根目录下的config.mk文件查看得知:
Alt text

TEXT_BASE变量在对应开发板目录的config.mk文件中定义,它的内容由配置uboot时生成,生成的方法如下:
make forlinx_nand_ram256_config将调用以下步骤生成对应配置文件

Alt text

在mkconfig脚本中有如下内容:
Alt text
Alt text

其最终值是0XCFE00000,这个值在芯片手册上的内存布局中找不到,因为这个值是打开MMU之后得到的结果。
对u-boot进行反汇编之后可以看到如下内容:
Alt text

第一条指令的地址是cfe00000,由此推导出其原因。

注意一点,程序真实运行时代码的地址不一定要按照链接地址来规定,以uboot代码为例,_start语句标号是uboot的起始语句,这部分语句在运行时一定是位于0地址附近,更准确一点来说是开头4KB以内的垫脚石里面的,但是其链接地址却超过了4KB,这并不妨碍将这段代码装载到4KB以内的地址处,以及将PC指针指向这段代码。如果这4KB以内的代码里面含有跳转语句,即B和BL指令,那么PC指针跳转的地址也不会按照跳转语句的链接地址进行绝对跳转,而是进行相对跳转,即用跳转处的链接地址减去当前指令的链接地址,用这个差值作为跳转的长度。要相进行决对地址跳转,就必须借助LDR伪指令来完成,这在uboot第二阶段时是非常有用的,因为第二阶段要从垫脚石跳转到内存中去运行。

第4课-Bootloader架构设计

  • 无标签