系统启动知识 (二) bootrom, bootloader, fastboot 关系


说到这个地方,有几个术语可能需要搞清楚:

BootROM, Bootloader各是什么东西:

BootROM是固化在SOC内部(在片内的一小块norflash上,容量很小,只读)的一段代码,是芯片设计时候的一个重点环节

如果这块代码有问题,那芯片流片指定是废了!一旦流片,无人能更改!

 

说了BootROM是什么之后,我们来思考一下,为什么需要BootROM?

先想一下,51单片机有bootrom吗,没有,51单片机上电立即从0x0000000的地方开始读取代码执行,本身代码就在norflash上,CPU直接跳转过去执行就行了。STM32有bootrom吗,好像也没有,理由和51一样。那么为什么手机soc就有BootRom呢?因为一个重大的区别,手机的代码量太大了,手机的固件动辄几百MB,甚至几个G, (新买的手机,光系统本身镜像甚至就会占一个GB以上的内存),固件的size远远大于内部norflash的容量(这个norflash又小又贵),这就导致:

---->1.固件根本无法放到norflash中,norflash本身也是只读的,根本无法烧写

---------> 2. 固件一般是烧写到SD卡,或者emmc,spiflash中

-------------> 3. 无法上电后直接被CPU取指令,他们是需要被搬运到DDR中才能被CPU取出来执行

----------------> 4. 需要先初始化DDR, 而不同厂家DDR的初始化代码是不同的,也是需要代码来做的

 

因此可以看到,3和4存在死锁,如果初始化DDR的代码在要搬运到DDR的镜像中, 那么因为没有地方能初始化DDR, 这就导致系统永远也启不来。这就是bootloader存在的意义。

bootloader和我们的系统镜像是分开的,它是一小段短小精炼的代码,可以由我们自由编辑,编译,然后烧写到flash中,或者sd中。更关键的是,借助bootloader, 我们就可以像发射火箭一样,实现多级启动

首先是第一级:bootrom, 上电后根据bootmode的pin选择启动方式,然后自动将spiflash/emmc/usb中的指定size的固件(bootloader的全部或者一部分)搬运到片内sram中(容量有限,所以bootloader可能无法全部加载到此处),然后跳转执行

然后是第二级:bootloader 相对来说灵活性就很高了,比如在初始化DDR之后,可以先加载M0, M7的固件,然后再加载linux kernel. bootloader中还可以做一些安全相关的工作,比如设置内存某些区域的安全非安全读写属性等

最后是第三级:kernel 加载好之后,进入linux的启动环节

 

流程大致如下:

 

上面提到了第一步,上电的时候,soc会根据bootmode 选择不同的启动方式;比如某个引脚组合,就会从USB启动,某个组合会从emmc启动;如果选择了USB启动,这里就会涉及到另一个有趣的问题,那就是USB烧录。当bootmode 选择为从USB启动后,bootrom 会尝试从usb接收固件,也就是bootloader, 在我司的产品中,bootloader是lk. 其实这里就是一个usb文件传输的过程。

我们看一下烧录脚本的细节:
.\bin\libusbex.exe .\bin\bootarea.img.eng.clr # 这是第一行,这里就是通过libusb将带有fastboot 功能的lk (bootarea.img.eng.clr) 传输到设备中, 注意这个是非加密的版本,加密版本的lk名字是bootarea.img.pro.enc, 传输成功后,就可以在PC端用fastboot (host) 和 设备端的fastboot (device)通信了.

.\bin\fastboot.exe erase blackbox

.\bin\fastboot.exe flash normal .\image\normal.img

.\bin\fastboot.exe flash system .\image\system.img

.\bin\fastboot.exe reboot

也可以看到fastboot的主要作用就是烧录,擦除分区,启动等;fastboot 运行时是一个host段的fastboot 和 传送到设备端的 lk里的fastboot交互的过程,也就是说是由host段先发起fastboot 命令,然后设备端进行响应的过程。而如果不从usb启动,不执行我们的烧录脚本,就不会走到fastboot里,也就是说正常启动的lk , 是启动了aboot来执行启动的相关操作,而烧录用的lk是启动了fastboot 来执行烧录相关的指令。

这里还涉及到加密的lk, 这个是干啥的呢,就是加密固件要用对应的加密的lk来加载,非加密要用非加密的lk来加载。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM