下边我就再把我更进一步了解到的bootloader执行过程再重新叙述一下:
我使用的是s5pv210芯片、K9K8G08U0A型号的nand flash
第一步:cpu启动起来后,先来到0x00000000这个地址处(也就是irom的地址),此时会看到有一段代码(这是irom中固定的代码)在这里,这段代码会找到bootloader的第一段代码(以下就称为BL1)存放的地址,由于BL1存放在nand flash中,不支持片上执行,所以irom会把这段代码拷贝到iram中,
但是在拷贝之前,irom会先把iram的起始4个地址分别写上一定的内容(不过通常只写0x00地址为BL1所占空间的大小(一般是8k),而其他三个地址全写为0),把BL1这段代码拷贝到iram后,irom的使命就快要完成了,irom的最后一个任务就是把pc指针指向放BL1的那块地址的起始位置,然后就按照这个地址的指令开始执行。
第二步:这个时候开始执行BL1的代码。这段代码的功能是初始化硬件,比如串口,内存,显示器,按键等等。
在初始化所有需要初始化的硬件后,BL1还会有一个拷贝指令,就是要把bootloader拷贝到sdram中一般会把bootloader的代码放到BLADD(表示为bootloader在sdram中存放的地址。
这时候BL1的使命也将要完成,于是,BL1会把pc指针跳转到BL2的地址,此时所有要运行的代码都在sdram中,这次的跳转不会直接从这次拷贝的开始地址执行,而是跳过BL1代码所占的地址,从BL2开始执行。
第三步:执行BL2中的代码。此时BL2代码的功能主要是实现MTD设备驱动初始化,电源、时钟初始化,堆栈空间,以及各种必要的初始化,并且会提供一个命令行,可以进行交互。在这之后会有一个设置内核参数的过程,这些参数在内存中的存在方式也是以结构体存储,以链表进行关联的,而这个 链表有一个固定的起始地址-0x3000_0100;每一个结构体代表一个信息,并首尾相连,内核在需要这些参数时,就可以再对应的地址上取数据。这一步执行完毕后,就要把kernel的代码拷贝到sdram中的一个指定地址,并且会把这个地址强制转换成一个函数指针,并且向这个函数中传递一些参数,最终会到内核中执行内核代码。这个时候,内核就会被引导到执行状态。