【Android 系统开发】 Android 系统启动流程简介(一)

Android 系统启动总结 : Android 系统启动分底层 Linux 内核启动 和 应用系统启动;


-- 底层系统启动 : 系统上电, bootloader 启动, linux kernel 启动, init 进程启动;


-- 应用系统启动 : init 进程启动关键的进程如 Zygote 进程 和 System Server 等系统服务, 之后进入 Home 界面;






一. Android 底层系统启动流程(Bootloader Kernel init)





1. 系统上电 执行 ROM 引导代码





(1) Android 系统执行的操作



Android 底层上电流程 : CPU 上电 --> PC 指向 ROM 启动代码零地址 --> 直接执行启动代码 / 将启动代码载入 RAM 后执行


-- CPU 上电 : 首先 Android 系统的 CPU 上电复位;


-- 程序指针指向 : 复位时 PC 指针指向 ROM 的零地址, 即 Android 系统的启动代码的地址;


-- 直接执行代码 : 从 零地址 读取可执行代码直接运行;


-- 转载代码到RAM再执行 : 将执行代码载入到 CPU 的 RAM 中执行;




启动代码介绍 : 启动代码 固化在 ROM 中, CPU 复位上电后, PC 指向 ROM 中代码的初始地址 即 零地址, 并执行该代码;






(2) PC 启动与 Android 启动比较



PC 启动系统机制 : ROM 分类 和 BIOS 作用 (初始化硬件设备, 载入硬盘运行);


-- 启动 ROM 分类 : 包括 PROM, EPROM, EEPROM三种;


-- ROM 中的启动程序 BIOS : BIOS 是 PC 的启动代码, 其作用是初始化硬件设备, BIOS 被载入到硬盘的扇区 MBR 之后运行并开始引导操作系统;




Android 系统机制 : ROM 分类 和 Bootloader 启动程序;


-- 启动 ROM 分类 : Android 中的 启动 ROM 分为 NOR Flash 和 NAND Flash 两种;


-- ROM 中的启动程序 Bootloader : Bootloader 地址是 CPU 复位后指向的地址, 即零地址;




(3) Bootloader 启动方式简介



Bootloader 启动位置 : Bootloader 在 ROM 中直接启动 还是 装载到 RAM 中启动取决与 ROM 是否可以按字节寻址;


-- 按字节寻址的 ROM : NOR Flash 可以按字节寻址, Bootloader 可以直接在 ROM 中执行;


-- 不可字节寻址 ROM : NAND Flash 不支持按字节寻址, Bootloader 需要先载入到 CPU 的 RAM 中, 然后在执行;






(4) NOR Flash 启动过程



启动方式总结 : 直接执行 Bootloader -> 写寄存器 -> 配置模块 -> 复制代码到内存中 -> PC 指向零地址 -> 地址映射 -> 执行映射的启动代码;




注意 : 这种情况是将 Bootloader 烧写入 NOR Flash 中的情况, 与现在最新的 CPU 内置 ROM 方式不同;




NOR Flash 启动过程 : 这种 ROM 支持字节寻址, 固化在其中的启动代码(Bootloader)可以按照顺序执行;


-- 开始启动 : Bootloader 存放在 NOR Flash 零地址, CPU 复位后 PC 指向零地址, 开始执行 Bootloader;


-- 写寄存器 : 配置 EMI 寄存器, 该寄存器存储设置好的各存储器地址 和 存取规则;


-- 模块配置 : 配置电源管理模块, 使各个模块上电;


-- 复制代码 : 为了提高执行效率, 将 NOR Flash 中的代码复制到内存中;


-- PC指针 : PC 指针指向 NOR Flash 零地址, 开始执行启动代码;


-- 地址映射 : 启动代码执行后, 会将启动代码所在的 零地址 映射到 内存 RAM 空间;


-- RAM执行 : PC 指针指向 RAM 中映射的地址, 开始执行启动代码;






(5) NAND Flash 启动过程



注意 : 这种情况是将 Bootloader 烧写入 NAND Flash 中启动代码执行流程;




NAND Flash 启动过程 :


-- 搬运代码到内部 RAM : CPU 上电复位之后, DMA 将 NAND Flash 中的 Bootloader 启动代码搬运到 CPU 内部的 RAM 中, 设置 PC 到 RAM 代码地址, 开始执行 Bootloader;


-- 设置配置 向量 : Bootloader 会执行 设置中断向量, 设置硬件配置 操作;


-- 搬运代码到外部 RAM : 计算出 Bootloader 所占大小, 预留出 Bootloader 空间大小, 将执行代码搬运到 SDRAM 或 DD-RAM 外部 RAM 中;


-- 搬运 Bootloader : 将 Bootloader 代码搬运到 SDRAM 或 DDR-RAM 中的首地址;


-- 地址映射 : 设置 Remap, 映射 0 地址到 SDRAM 或者 DDR-RAM 首地址;


-- 执行Bootloader : 设置 PC 指针到 零地址, 执行 Bootloader;






(6) Bootloader 烧录工艺



MASK 烧录 : 早期的 ROM PROM 通过 MASK 植入启动代码;




烧录器 : EPROM EEPROM 通过烧录器烧入启动代码, 之后贴片焊接;




JTAG 调试器 : NOR Flash 和 NAND Flash 通过 JTAG 调试器连接 CPU 的 JTAG 调试接口 和 PC 机, 将编译好的 Bootloader 烧入 NOR Flash 和 NAND Flash 指定地址;




CPU 内置 ROM :


-- 固化代码 : CPU 再内置的 ROM 中固化一段代码, 这段代码不是 Bootloader;


-- 代码作用 : 这段代码启动后可以与 PC 连接, 直接使用网络接口 或 USB 接口便可以连接 PC, 不再依赖 JTAG 调试器烧录, 速度和效率也提高了;






2. Bootloader 引导程序简介





(1) Bootloader 作用



Bootloader 作用 : 初始化硬件设备, 建立内存空间映射图, 为内核启动准备好软件, 硬件环境;


-- 类似 BIOS : Bootloader 本质与 PC 上的 BIOS 相同, 都是为 操作系统 初始化 软件, 硬件环境;






(2) Bootloader 加密



加密简介 :


-- 加锁原因 : 手机厂商为了实现 系统价值, 稳定运行, 用户信息安全 等功能, 会对 Bootloader 进行加锁;


-- 加锁局限 : Bootloader 加锁后只能引导指定手机厂商的 硬件, 内核, 和操作系统, 不能识别其他厂商硬件;


-- 解锁隐患 : Bootloader 一旦解锁, 对用户来说 : 存在潜在的稳定性 与 系统安全问题; 对厂商来说 : 手机可以随意刷写 沦为硬件平台;






3. Linux 内核





(1) Linux 内核镜像



Linux 内核镜像 : Linux 内核有两种镜像 Image 和 zImage;


-- Image (非压缩内核) : 没有经过压缩的内核镜像, 占用空间大, 执行速度快;


-- zImage (压缩内核) : Image 经过压缩后的内核镜像, 占用空间小, 但是执行的时候需要解压缩, 执行效率慢;


-- 嵌入式选择 : 嵌入式系统中空间比较小, 通常采用 zImage 压缩镜像, 牺牲一点执行效率换取较少的存储空间;






(2) 内核启动流程



Kernel 启动流程 : 内核初始化 -> 设备驱动初始化 -> 内核启动 -> 挂载文件系统 -> 启动用户空间进程;






(3) 内核初始化



内核初始化 : 主要对硬件进行配置;


-- 向量表 : 创建异常向量表 和 初始化中断处理函数;


-- 进程调度器 : 初始化系统核心进程调度器 和 时钟中断处理机制;


-- 串口 : 初始化串口控制台;


-- 缓存 : 创建和初始化系统, 为内存调用提供缓存;


-- 内存管理 : 初始化内存管理, 检测内存大小及碑内核占用的内存情况;


-- 进程通信 : 初始化系统进程通信机制;






(4) 设备初始化



设备初始化 : 加载设备驱动, 主要有 静态加载 和 动态加载两种方式;


-- 静态加载 : 将驱动模块加载到内核中, 设备驱动会在内核启动的时候自动加载, 这种驱动是无法卸载的;


-- 动态加载 : 在系统中使用 modprobe 或者 insmod 进行设备驱动模块的加载, 使用 rmmod 进行设备驱动模块卸载;






(5) 挂载文件系统



挂载文件系统 :


-- 创建并挂载根设备 : kernel 初始化 和 设备初始化之后会创建 根设备, 根设备文件系统以只读方式挂载;


-- 释放内存到根设备 : 根设备创建成功之后, 根设备是只读的, 这时释放未使用的内存到 根设备上;






(6) 启动 init 程序



启动应用程序 : 根文件挂载成功后, 启动 /sbin/init 程序, 这是 linux 系统第一个应用程序, 启动成功后 init 进程会获得 linux 系统的控制权;


-- 硬件初始化 : 初始化 Android 设备硬件;


-- 挂载根文件 : 根据命令行参数挂载根文件系统;


-- 跑启动脚本 : 执行用户自定义的 init 启动脚本;





上一篇:【Android 系统开发】 Android 系统启动流程简介(二)


下一篇:【嵌入式开发】 Linux Kernel 下载 配置 编译 安装 及 驱动简介(二)