1. 启动流程
1.1. bootrom
芯片上电后,会自动执行bootrom代码,bootrom是各家厂商定制的,但完成的工作基本相同。bootrom通常支持从多种不同的介质启动,如SD卡、NADN、eMMC、USB等。以Exynos4412为例,bootrom会读取OM引脚指定的启动介质。以eMMC为例,eMMC分为boot0、boot1、RPMB和user四个物理分区,四个物理分区独立寻址。可以通过寄存器指定eMMC的bootmode,也就是eMMC启动时,读取那个物理分区的数据。这就需要根据厂家需要,提前设置eMMC的寄存器。对于Exynos4412来说,bootrom会去读boot0分区的内容。
短接emmc clk到GND会使emmc启动识别,fallback到其他启动模式,可以进行救砖刷机。
1.2. BootLoader
在bootrom运行时,使用的是芯片内部的SRAM,SRAM不需要初始化,但容量比较小。 BootLoader通常会分为多个阶段,每个阶段有自己独立的镜像文件。以U-Boot的SPL(Secondary Program Loader)为例,SPL镜像体积较小,可以在启动时被加载的SRAM执行,完成基本的外设初始化和DDR初始化后,可以读取完整U-Boot镜像到DDR中执行,由U-Boot初始化更多的外设、实现更多更复杂的功能。最后,U-Boot读取Kernel镜像、Kernel启动参数或dtb镜像、rootfs镜像,并跳转到Kernel执行。
1.3. Kernel
跳转到Kernel后
- 建立页表
- 开启MMU
- 配置bootcpu的idle线程,之后的处理在idle线程的上下文执行
- 跳转到start_kernel,完成一些重要的初始
- start_kernel的最后fork 1号进程(init)和2号进程(kthreadd),之后的初始化主要1号进程的上下文指向
- 1号进程会进一步做一下初始化,其中包括设备驱动的初始化,为每个处理创建idle线程等,其中很多初始化会通过创建新的kthread线程来完成
- 挂载rootfs
- fork 1号进程,并最终启动rootfs中的init程序,作为用户态的1号进程
1.4. Init
用户态的init程序有多种选择,比如busybox
、systemd
、SysV
等。init
启动后,会fork
出各个用户进程,直到整个系统启动。