引言:一般而言Android系统内核引导(主要是arm架构下linux内核)和x86下内核引导还是有不少差别,不过大同小异。这里更多的要关注嵌入式的外设问题,如各种不同的存储器。
关于x86架构: linux系统内核引导流程梳理
既然提到了嵌入式的存储器,有必要先介绍下。常见的存储器可以分为3类:ram、rom和flash。
ram为随机访问存储器,即主要的内存芯片,掉电数据丢失,读写速度快,有sram(静态)和dram(动态)。其中sram是目前cpu读写最快的存储设备,当然价格也昂贵,主要用于cpu的一级、二级缓存。dram常见的为主流计算机中的ddr内存,还有如sdram、fpram之类。
rom只读存储器,掉电可以保存数据,读写速度慢。从开始只能写一次的prom,到可以用紫外线擦除的eprom,再到后边电子擦除的eeprom,使用越来越方便。
flash结合ram读写速度快和rom掉电不丢数据、可以电子擦除的优势而推出,中文名闪存。flash目前主要有nor flash和nand flash,nor flash有sdram的特性,读取速度快,可以直接运行程序,但价格稍贵。nand flash可以看成eeprom,价格便宜,不能直接运行程序,通常用来存储image文件,复制到ram后运行。
有了这些概念,再结合x86系统引导流程,便可以很好的理解arm架构下引导流程。和x86一样,计算机系统的粗略启动流程:
上电 –> xloader -> bootloader –> kernel -> 文件系统
两者主要区别在于多一个xloader,xloader主要功能为初始化系统时钟和片外ram(ddr)。也即是说xloader运行于片内ram,很可能是sram,根据前边对sram的了解,xloader代码少且运行速度快,运行结束后跳转到片外ram的bootloader处,这样引导流程又归一了。
对于arm架构的cpu,复位或上电后通常从内存0x0000处取第一条指令,相比x86就没有BIOS,所以整个引导都 由bootloader完成。同x86一样,对于nor flash,在其硬件设计时地址被映射到0x0000处,bootloader代码固化在内存最前边,这样保证上电后直接执行bootloader代码。
然而对于nand flash,不能直接执行里面的bootloader程序,所以需要将其持拷贝到ram中。那么,这个拷贝过程是由谁完成的?答案是nand controler,只知道它是硬件操作就行,具体原理不深究。
现在的bootloader如u-boot,为了更易于移植,一般包括两个阶段:stage1和stage2。
stage1为汇编程序,主要完成:
- 设置异常向量
- 设置cpu速度、时钟频率
- 初始化内存控制器
- 将stage2的代码复制到ram中(获得理更快的执行速度)
- 初始化堆栈(c程序执行所需)
- 跳转到ram中stage2的代码处
- 初始化flash设备
- 检测系统内存映射()
- 初始化显示相关设备
- 初始化网络相关设备
- 将kernel映像和根文件系统从flash中拷贝到ram中
- 设定内核启动参数并跳转到内核入口处
虚拟盘一般为ramdisk,可以自行配置,主要用于提高系统性能,例如将一些经常被访问、并且不会被更改的文件通过ramdisk放在内存中,以加快访问。ramdisk工作于虚拟文件系统(VFS) 层,不能格式化,访问ramdisk要基于其它文件系统。
而根文件系统也分为虚拟根文件系统和真实的根文件系统。通常会在虚拟的根文件系统中做一部分工作,然后再切换到真实的根文件系统下面。
内核启动参数主要为rdinit相关参数,启动用户空间的init进程,从而启动android系统。
最后在这里留下几个疑问,程序如何从内核空间过渡到用户空间?fastboot、recovery与bootloader间的关系?根文件系统什么时候挂载上的?