LK(little kernel)-3:LK的启动流程-作为Android的bootloarder

说明:该篇基于高通平台(MSM8916等)+ LK2ND 二级引导场景,梳理从硬件上电到

LK(Little Kernel)是一个轻量级嵌入式内核,常用于 Bootloader(如 Android 设备的 Bootloader)。

LK 启动分为 5 个核心阶段,从汇编级最小初始化逐步过渡到 C 语言内核与应用:

硬件复位
→ 汇编阶段(_start)
→ 架构初始化(arch_init)
→ 平台初始化(platform_init)
→内核初始化(kernel_init)
→ 应用启动(app)

一、链接脚本入口-system-onesegment.ld

LK 的启动入口由链接脚本指定,链接脚本(如 arch/arm/system-onesegment.ld)
在这里插入图片描述

该脚本常用于引导加载程序(bootloader)或操作系统内核的构建。

主要功能包括:

指定输出格式与架构:设置为ARM小端32位ELF格式。
入口点:程序从_start符号开始执行。
段划分:
	.text:存放只读代码和数据。
	.rodata:存放只读数据,并对齐到4字节边界,包含多个自定义段(如.commands、.apps等)。
	.data:存放已初始化的可写数据。
	.bss:存放未初始化的数据。
地址分配:通过%MEMBASE%%MEMRWOFF%宏控制各段在内存中的起始位置。
清理无用段:丢弃调试信息等不必要的内容。

该链接脚本执行完毕后最,会进入程序入口_start
在这里插入图片描述

_start该函数的文件路径为:arch\arm\crt0.S

这段代码定义了程序的入口点 _start,并初始化了异常向量表,具体内容如图所示:
在这里插入图片描述

在该初始化函数中,最终通过汇编语言bl 跳转到主函数入口kmain
在这里插入图片描述

函数入口-kmain

经过汇编语言的跳转最终跳转到C语言中的函数入口kmain
文件路径如下:kernel\main.c
在这里插入图片描述

这段代码是系统启动的主函数kmain,负责初始化操作系统的核心组件。主要功能包括:

  1. 早期初始化:依次调用线程、架构、平台和目标平台的早期初始化函数。
  2. 调试与堆初始化:初始化调试系统和内核堆管理器。
  3. 线程与定时器系统:初始化线程管理、DPC(延迟过程调用)和定时器系统。
  4. 创建引导线程:在非NAND写入模式下创建bootstrap2线程并启用中断;否则执行NAND写入逻辑。
  5. 进入空闲状态:将当前线程转为空闲线程,等待任务调度。

整体流程为系统启动的核心准备阶段。
在这里插入图片描述

bootstrap2函数

这段代码是系统启动过程中的一个关键函数 bootstrap2,主要功能包括:

  1. 架构初始化:调用 arch_init() 初始化系统架构相关组件。
  2. 可选模块初始化:根据编译选项初始化块 I/O 库([bio_init]和文件系统库([fs_init])。
  3. 平台与目标设备初始化:依次调用 [platform_init()] 和 [target_init()]完成硬件平台及目标设备的初始化。
  4. 应用层初始化:最后调用 [apps_init()] 启动上层应用程序。

整体流程为系统从底层到上层逐步完成初始化。

该函数调用 apps_init(),扫描并启动所有注册的 LK 应用。

apps_init函数

这段代码的功能是初始化并启动应用程序,文件路径如下:app\app.c
在这里插入图片描述

这段代码的功能是初始化并启动应用程序,具体分为两步:

  1. 初始化应用:遍历所有应用描述符,调用每个应用的[init](file://d:\Github_Sh\Android_lk\lk2nd\include\app.h#L39-L39)函数(若存在)。
  2. 启动应用:再次遍历应用描述符,对未被标记为禁止启动的应用调用start_app函数。

通过__apps_start__apps_end界定应用范围,[APP_FLAG_DONT_START_ON_BOOT]标志控制是否启动。

在这里插入图片描述
最终会将所有的应用程序通过start_app函数创建线程启动,
可通过查看链接脚本查到哪些应用程序进行了注册,如图所示为.apps
在这里插入图片描述
再经过查找,发现.apps段在include\app.h中定义APP_START(appname)
在这里插入图片描述
经过查找发现,在app\aboot\aboot.c文件中进行了aboot程序的注册,最后调用了aboot_init函数进行初始化
在这里插入图片描述
由于aboot_init函数过长,在此仅对该函数进行解释

这段代码是Android设备启动加载程序(aboot)的初始化函数,主要功能包括:
在这里插入图片描述

  1. 硬件初始化:初始化看门狗、NV存储页面大小等。
  2. 设备信息读取:读取设备解锁状态和OEM解锁信息。
  3. 多槽位支持检测:查找并标记活动启动槽位。
  4. 显示初始化:根据配置初始化显示屏或HDMI输出。
  5. 按键检测:检查音量键组合以决定进入恢复模式或fastboot模式。
  6. 启动模式判断:根据重启原因(如用户强制重启、alarm启动等)决定启动路径。
  7. 启动流程
    • 尝试从EMMC或Flash启动Linux内核。
    • 若失败则进入fastboot模式,并注册相关命令。
  8. 错误处理:在启动失败时提供重试机制或进入fastboot模式。

整体逻辑围绕设备启动的核心流程展开,兼顾异常处理与调试支持。

若正常启动流程,则调用下面函数来正式启动Linux系统

boot_linux_from_mmc(); // 从MMC存储启动Linux系统 
或者
boot_linux_from_flash(); // 从闪存启动Linux

最终通过boot_linux加载系统镜像并启动Linux
在这里插入图片描述

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐