Android Kernel - Boot Loader

本文详细解析了Android Bootloader的核心组件LK(Little Kernel)的主要代码流程,包括kmain函数、线程初始化、架构早期初始化、平台初始化、定时器初始化等关键步骤。通过阅读源代码,介绍了内存管理、中断处理、调试机制、设备初始化等方面的知识,为理解Android启动流程提供了深入的洞察。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

Android Boot loader 的 code 在 bootable/bootloader/lk 底下, LK 是 Little Kernel 的缩写, 是 andriod bootloader 的核心精神.

 

入口函数在 kernel/main.c 中的 kmain(), 以下就来读读这一段 code.

 

 

 

In include/debug.h: 我们可以看到 dprintf 的第一个参数是代表 debug level.

 

 

 

In include/debug.h: 

 

 

 

所以 dprintf 会依 DEBUGLEVEL 来判断是否输出信息.

 

来看第一个 call 的函数: thread_init_early, define in thread.c

 

 

 

#define NUM_PRIORITIES 32 in include/kernel/thread.h

 

list_initialize() defined in include/list.h: initialized a list

 

 

 

run_queue 是 static struct list_node run_queue[NUM_PRIORITIES]

 

thread_list 是 static struct list_node thread_list

 

再来要 call  的函数是: arch_early_init() defined in arch/arm/arch.c

 

 

 

现代操作系统普遍采用虚拟内存管理(Virtual Memory Management)机制,这需要处理器中的MMU(Memory Management Unit,

 

内存管理单元)提供支持。

 

CPU执行单元发出的内存地址将被MMU截获,从CPU到MMU的地址称为虚拟地址(Virtual Address,以下简称VA),而MMU将这个地

 

址翻译成另一个地址发到CPU芯片的外部地址引脚上,也就是将VA映射成PA

 

MMU将VA映射到PA是以页(Page)为单位的,32位处理器的页尺寸通常是4KB。例如,MMU可以通过一个映射项将VA的一页

 

0xb7001000~0xb7001fff映射到PA的一页0x2000~

<think>我们正在分析MTK平台从BootROM到Android的完整启动流程,并特别关注efuse在签名校验中的作用。 根据引用内容,启动流程主要分为以下几个阶段: 1. BootROM阶段 2. Pre-loader阶段 3. Little Kernel (LK) 阶段 4. Kernel阶段 5. Android用户空间初始化 同时,我们需要明确efuse校验签名的具体阶段。efuse通常用于存储安全相关的密钥和配置,在安全启动过程中用于验证固件的签名。 步骤分解: 1. BootROM (boot rom): - 设备上电后,CPU从BootROM的固定地址开始执行。 - BootROM初始化内部RAM(ISRAM),初始化必要的外设(如存储控制器),然后从外部存储设备(如eMMC或NAND Flash)的预定义位置加载Pre-loader到ISRAM。 - 在加载Pre-loader之前或之后,BootROM会进行安全校验。根据引用[1],BootROM会“只加载MTK授权的二进制文件”,这里就涉及到了签名校验。而efuse的作用就是存储用于验证签名的公钥哈希或安全配置。因此,BootROM阶段会使用efuse中的信息来验证Pre-loader的签名。 2. Pre-loader- Pre-loader是MTK平台特有的一个引导阶段,由BootROM加载到ISRAM中执行。 - 根据引用[1]和[3],Pre-loader的主要任务包括: a. 初始化硬件(如UART、Timer、RTC、WDT、PMIC等)[^3]。 b. 获取启动原因(如正常启动、充电模式等)并保存到全局变量bootargs中[^3]。 c. 安全相关检查(security check)[^3]。 d. 初始化外部RAM(DRAM)[^1]。 e. 从存储设备中加载Little Kernel (LK) 到DRAM的固定地址(如0x81e00000)[^1]。 f. 电池检查(battery check)[^3]。 - 然后Pre-loader跳转到LK执行。 3. Little Kernel (LK): - LK是一个轻量级的引导加载程序,通常用于加载操作系统内核。 - 根据引用[1]和[2],LK的主要任务包括: a. 初始化更多的硬件设备。 b. 加载bootimage(包含Linux内核和ramdisk)到DRAM[^1]。 c. 跳转到内核执行。 - 注意:在LK阶段,可能还会进行进一步的签名验证(例如对内核的验证),但根据问题要求,我们关注efuse校验,而efuse的校验主要发生在BootROM阶段。不过,后续阶段也可能使用efuse中的其他信息。 4. Kernel阶段: - 内核启动后,完成系统的核心初始化,包括驱动、进程管理等。 - 根据引用[2],内核初始化完成后会fork出init进程。 5. Android用户空间初始化: - init进程拉起,然后执行ramdisk中的init程序,进入用户空间初始化。 - init进程fork出zygote进程,然后启动整个Android系统[^2]。 关于efuse校验签名的具体阶段: - 根据引用[1]中所述,BootROM在加载Pre-loader时会进行安全校验,只加载MTK授权的二进制文件。这个校验过程就是安全启动(Secure Boot)的一部分。 - 在安全启动中,BootROM会使用存储在efuse中的根公钥哈希(或类似的信息)来验证Pre-loader的签名。如果验证失败,则启动过程终止。 - 因此,efuse的校验发生在BootROM加载Pre-loader的阶段。 总结完整启动流程: 1. BootROM: - 上电复位,执行ROM代码。 - 初始化内部RAM和基本外设。 - 从外部存储设备加载Pre-loader到ISRAM。 - 使用efuse中存储的密钥信息验证Pre-loader的签名(安全启动)。如果验证失败,停止启动。 - 验证通过后,跳转到Pre-loader。 2. Pre-loader- 初始化UART、Timer、RTC、WDT、PMIC等基本硬件[^3]。 - 获取启动原因并保存到bootargs。 - 安全相关检查(可能包括进一步的硬件安全机制)。 - 初始化外部DRAM。 - 加载LK到DRAM(地址0x81e00000)[^1]。 - 跳转到LK。 3. LK: - 初始化更多硬件。 - 加载bootimage(包含Linux内核和ramdisk)到DRAM。 - 跳转到内核。 4. Kernel- 内核初始化,包括驱动加载等。 - 创建init进程。 5. Android用户空间: - init进程启动,执行init.rc等脚本。 - 启动zygote,进而启动SystemServer等,最终完成Android启动。 注意:efuse的校验仅在BootROM阶段明确提到,但后续阶段(如LK加载内核时)也可能有签名校验,不过这些校验可能使用不同的机制(例如使用Pre-loader或LK阶段加载的密钥),而efuse通常用于最底层的信任根。 因此,efuse校验签名的具体阶段是BootROM加载Pre-loader时。</think>### MTK平台从BootROM到Android的完整启动流程及efuse签名校验分析 #### **启动流程详解**(基于MTK平台) 1. **BootROM阶段**(芯片上电初始化) - 上电复位后,CPU从固定地址执行BootROM代码 - 初始化内部ISRAM、时钟、基础外设控制器 - **关键操作**: - 从外部存储(如eMMC/NAND Flash)的**预定义位置**加载Pre-loader二进制文件 - 使用内置DMA将Pre-loader复制到ISRAM(地址示例:`0x0000_8000`) - **执行efuse签名校验**(见后文详解) - 跳转到ISRAM中的Pre-loader入口地址[^1] 2. **Pre-loader阶段**(ISRAM中执行) - 初始化关键硬件: ```c init_uart(); // 串口调试 init_timer(); // 定时器 init_pmic(); // 电源管理 init_rtc(); // 实时时钟 ``` - 读取RTC记录的启动模式(正常启动/恢复模式等) - 初始化外部DRAM控制器(为加载LK做准备) - 从存储设备加载**Little Kernel (LK)** 到DRAM固定地址(如`0x81E0_0000`) - 执行电池检测(低电量时阻塞启动) - 跳转到LK入口[^1][^3] 3. **Little Kernel (LK) 阶段**(DRAM中执行) - 初始化更复杂的外设:显示、USB、文件系统等 - 加载**bootimage**(包含Linux内核和initramfs)到DRAM - 解析内核启动参数(如`bootargs`中的启动模式) - 跳转到Linux内核入口[^1][^2] 4. **Linux Kernel阶段** - 初始化CPU调度、内存管理、驱动框架 - 解压并挂载initramfs(初始根文件系统) - 创建第一个用户进程`init`(PID=1) - 启动Android专属服务:Binder IPC、ASHMem等[^2] 5. **Android用户空间初始化** - `init`进程执行`init.rc`脚本: - 启动`servicemanager`(Binder服务管理) - 启动`zygote`(Java虚拟机母体) - `zygote`孵化`system_server`(系统服务核心) - 启动Launcher、AMS、WMS等,完成Android UI加载[^2] ```mermaid graph TD A[BootROM] -->|加载并校验Pre-loader| B(Pre-loader) B -->|初始化DRAM<br>加载LK| C(Little Kernel) C -->|加载bootimage| D(Linux Kernel) D -->|启动init进程| E[Android Userspace] E --> F[Zygote] F --> G[SystemServer] G --> H[Launcher] ``` #### **efuse签名校验机制及阶段** **作用位置**:**BootROM加载Pre-loader阶段** **校验流程**: 1. BootROM读取芯片熔断的**efuse密钥**(物理不可修改) 2. 计算Pre-loader二进制文件的**数字签名**(通常为RSA/PSS) 3. 对比签名与efuse存储的**认证公钥哈希** 4. 若校验失败: - 终止启动流程 - 可能触发安全警报(如点亮故障LED) 5. 校验成功才允许执行Pre-loader[^1] **efuse关键特性**: - 一次性可编程存储器(物理防篡改) - 存储**安全启动根密钥**(Root of Trust) - 启用/禁用安全启动的熔断位(permanent enable flag) - 支持密钥吊销(通过存储密钥版本号) > ⚠️ **注意**:后续阶段(如LK加载内核时)可能进行二次校验,但**efuse校验仅在BootROM→Pre-loader阶段发生**,构成信任链的基础。 #### **安全启动信任链** ``` BootROM (efuse Root Key) ↓ 验证签名 Pre-loader ↓ 验证签名(可选) Little Kernel ↓ 验证签名 Linux Kernel ↓ 验证签名 Android系统分区 ``` 此机制确保从硬件层到应用层的完整信任链,防止未授权固件运行[^1]。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值