3.5 内核初始化详解
2026/4/26大约 5 分钟启动流程内核初始化
3.5 内核初始化详解
📚 本节导读
学习时长: 约 1 小时
难度级别: ⭐⭐⭐☆☆(进阶级)
前置知识: 3.4 $Sub$$main钩子详解
🎯 学习目标
- 理解 os_kernel_init() 的完整执行流程
- 理解调度器初始化
- 理解定时器系统初始化
- 理解空闲任务和回收任务初始化
一、函数概述
1.1 概念定义
os_kernel_init() 是 OneOS 内核初始化的核心函数,负责在调度器启动前完成所有必要的内核组件初始化。它位于 $Sub$$main 钩子函数之后、调度器启动之前,确保内核各组件按正确顺序初始化。
1.2 函数位置
os_kernel_init() 函数位于:kernel/source/os_startup.c二、功能说明
2.1 核心功能说明
os_kernel_init() 的设计原则是"按依赖顺序初始化",确保每个组件在其依赖项就绪后初始化:
| 功能模块 | 说明 | 必要性 |
|---|---|---|
| PRE_KERNEL_1 初始化 | 执行第一级内核初始化,如板级硬件初始化 | ✅ 必须 |
| 显示版本信息 | 打印 OneOS 内核版本信息(调试模式) | ⚪ 可选 |
| 滴答队列初始化 | 初始化系统滴答队列,用于延时和定时器管理 | ✅ 必须 |
| 调度器初始化 | 初始化任务调度器和就绪队列 | ✅ 必须 |
| 定时器模块初始化 | 根据配置初始化哈希桶或单链表定时器 | ✅ 必须 |
| 回收任务初始化 | 创建回收任务,用于回收已删除任务资源 | ✅ 必须 |
| 空闲任务初始化 | 创建空闲任务,系统无任务时运行 | ✅ 必须 |
| sys_task 初始化 | 创建并启动系统任务 | ✅ 必须 |
2.2 函数实际作用
根据项目实际代码,os_kernel_init() 主要做 八件事:
- 执行 PRE_KERNEL_1 级别初始化
- 显示系统版本信息
- 初始化滴答队列
- 初始化调度器
- 初始化定时器模块
- 初始化回收任务
- 初始化空闲任务
- 创建并启动 sys_task
三、代码解析
3.1 完整代码(第 256-281 行)
void os_kernel_init(void)
{
/* 1. PRE_KERNEL_1 初始化 */
_k_run_init_call(OS_INIT_LEVEL_PRE_KERNEL_1);
/* 2. 显示版本信息 */
_k_show_sys_info();
/* 3. 初始化滴答队列 */
k_tickq_init();
/* 4. 初始化调度器 */
k_sched_init();
/* 5. 初始化定时器模块 */
#ifdef OS_USING_HASH_BUCKET_TIMER
k_timer_module_init();
#endif
#ifdef OS_USING_SINGLE_LIST_TIMER
k_single_list_timer_module_init();
#endif
/* 6. 初始化回收任务 */
k_recycle_task_init();
/* 7. 初始化空闲任务 */
k_idle_task_init();
/* 8. 创建并启动sys_task系统任务! */
_k_sys_task_init();
}3.2 分步详细解释
第一步:PRE_KERNEL_1 初始化和版本信息
/* pre kernel 1 init call */
_k_run_init_call(OS_INIT_LEVEL_PRE_KERNEL_1);- 解释: 执行 PRE_KERNEL_1 级别的初始化
- 含义: 调用所有注册到 PRE_KERNEL_1 级别的初始化函数
- 作用: 内核启动前的第一级初始化,如 os_hw_board_init() 就在这里执行
/* Show version information. */
_k_show_sys_info();- 解释: 显示系统版本信息
- 含义: 在调试模式下打印 OneOS 内核版本信息
- 作用: 帮助开发者确认系统版本,发布版本不执行此操作
第二步:基础组件初始化(滴答队列、调度器、定时器)
k_tickq_init();- 解释: 初始化滴答队列
- 含义: 初始化系统滴答队列
- 作用: 用于管理延时任务和定时器,是调度器的基础组件
k_sched_init();- 解释: 初始化调度器
- 含义: 初始化任务调度器和就绪队列
- 作用: 这是内核的核心!没有调度器,多任务就无法运行
#ifdef OS_USING_HASH_BUCKET_TIMER
k_timer_module_init();
#endif- 解释: 哈希桶定时器初始化(条件编译)
- 含义: 根据配置选择是否初始化哈希桶定时器
- 作用: OneOS 支持两种定时器实现,根据配置选择
#ifdef OS_USING_SINGLE_LIST_TIMER
k_single_list_timer_module_init();
#endif- 解释: 单链表定时器初始化(条件编译)
- 含义: 根据配置选择是否初始化单链表定时器
- 作用: OneOS 支持两种定时器实现,根据配置选择
第三步:任务初始化(回收任务、空闲任务、sys_task)
k_recycle_task_init();- 解释: 初始化回收任务
- 含义: 创建回收任务(recycle task)
- 作用: 用于回收已删除任务的资源,优先级通常很低
k_idle_task_init();- 解释: 初始化空闲任务
- 含义: 创建空闲任务(idle task)
- 作用: 当没有其他任务运行时,运行空闲任务,空闲任务是必须存在的!
_k_sys_task_init();- 解释: 创建并启动 sys_task 系统任务
- 含义: 创建名为 "sys_task" 的系统任务
- 作用: 执行剩余的初始化级别,最后调用 app_entry() 进而调用用户 main()
四、关键点说明
| 功能 | 说明 |
|---|---|
| PRE_KERNEL_1 | 第一级初始化,包含板级硬件初始化 |
| 滴答队列 | 管理延时和定时器的基础数据结构 |
| 调度器 | 多任务的核心,决定哪个任务运行 |
| 定时器模块 | 支持哈希桶或单链表两种实现 |
| 回收任务 | 优先级低,负责回收已删除任务资源 |
| 空闲任务 | 必须存在,无其他任务时运行 |
| sys_task | 第一个运行的任务,优先级最高 |
注意: os_kernel_init() 完成后,调度器还未启动,需要调用 os_kernel_start() 才会开始多任务调度。
💡 本节总结
重点回顾
- os_kernel_init() 的定位:内核级核心初始化函数,在调度器启动前执行
- os_kernel_init() 的 8 个步骤:
- PRE_KERNEL_1 初始化
- 显示版本信息
- 初始化滴答队列
- 初始化调度器
- 初始化定时器模块
- 初始化回收任务
- 初始化空闲任务
- 创建并启动 sys_task
- 设计原则:按依赖顺序初始化,确保每个组件就绪
- 初始化级别顺序 - PRE_KERNEL_1 → PRE_KERNEL_2 → POST_KERNEL → PRE_DEVICE → DEVICE → COMPONENT → APPLICATION → SMP
下一步
接下来请学习下一节内容。