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

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)或操作系统内核的构建。

c 复制代码
主要功能包括:

指定输出格式与架构:设置为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系统

c 复制代码
boot_linux_from_mmc(); // 从MMC存储启动Linux系统 
或者
boot_linux_from_flash(); // 从闪存启动Linux

最终通过boot_linux加载系统镜像并启动Linux

相关推荐
代码AC不AC16 小时前
【Linux】System V 通信方式
linux·消息队列·共享内存·信号量·system v
vortex516 小时前
vmware虚拟机设置启动时进入live cd
linux·网络安全
Lugas Luo17 小时前
Ascend 310B 定制 SDHCI 主机控制器源码深层次劫持与优化解析
linux·嵌入式硬件
钟智强17 小时前
Linux SSH密码爆破脚本,从原理到实践
linux·运维·ssh
wangjialelele17 小时前
一文读懂 Redis 持久化与事务
linux·数据库·redis·bootstrap
Linux蓝魔17 小时前
麒麟官方yum源配置V10SP2-V10SP3-V10SP3-2403
大数据·linux·运维
helloliyh17 小时前
linux 删除指定日期目录(包括目录下文件)
linux·运维·服务器
野犬寒鸦17 小时前
Redis复习记录Day03
服务器·redis·后端·面试·bootstrap·mybatis
半个俗人17 小时前
06.Linux用户权限相关命令
linux·运维·服务器
小宇的天下17 小时前
Calibre LVS Circuit Comparison(1)
linux·数据库·lvs