3.5.2 PRE_KERNEL_1 阶段初始化详解
2026/4/28大约 3 分钟启动流程初始化PRE_KERNEL_1内核
3.5.2 PRE_KERNEL_1 阶段初始化详解
📚 本节导读
学习时长: 约 45 分钟
难度级别: ⭐⭐☆☆☆(中级)
前置知识: 3.5.1 _k_run_init_call 函数详解
🎯 学习目标
- 理解 PRE_KERNEL_1 阶段的具体执行流程
- 掌握每个核心初始化函数的功能
- 理解子级别(HIGH/MIDDLE/LOW)的设计意义
- 了解为什么这些函数要在调度器启动前执行
一、概述
1.1 PRE_KERNEL_1 的定位
PRE_KERNEL_1 是 OneOS 多级初始化机制的第一阶段,在调度器启动之前执行。这个阶段主要完成最基础的硬件和系统框架初始化。
1.2 执行顺序(从project.map提取)
PRE_KERNEL_1 阶段的函数按子级别(Sublevel)顺序执行,实际执行顺序如下:
| 序号 | 子级别 | 函数名 | 源文件 | 地址(来自 project.map) |
|---|---|---|---|---|
| 1 | - | pre_kernel_1_start | os_startup.c | 0x08022798 |
| 2 | HIGH | cortex_m_set_vector | vector_table.c | 0x080227a0 |
| 3 | MIDDLE | os_hw_board_init | drv_common.c | 0x080227a8 |
| 4 | LOW | device_core_init | device.c | 0x080227b0 |
| 5 | LOW | __driver_stm32_usart_early_driver_init | drv_usart.c | 0x080227b8 |
说明:地址从0x08022798递增,地址顺序就是执行顺序
1.3 关键约束
⚠️ 重要限制
在 PRE_KERNEL_1 阶段:
- ❌ 调度器未启动,不能使用任务相关 API
- ❌ 不能使用依赖调度器的功能(如延时、信号量等待等)
- ✅ 只能使用最基础的硬件操作和内存操作
二、核心初始化函数详解
详细文档
每个函数的详细解析请查看对应的单独文档:
2.1 pre_kernel_1_start(起始标记)
这是 PRE_KERNEL_1 阶段的第一个函数,作为阶段开始标记。
👉 详细文档:3.5.2.1 pre_kernel_1_start 函数详解
2.2 cortex_m_set_vector(HIGH 子级别)
负责设置 Cortex-M 处理器的向量表,这是中断系统的核心。
👉 详细文档:3.5.2.2 cortex_m_set_vector 函数详解
2.3 os_hw_board_init(MIDDLE 子级别)
这是板级硬件初始化的核心函数,每个芯片平台都有自己的实现。
👉 详细文档:3.5.2.3 os_hw_board_init 函数详解
2.4 device_core_init(LOW 子级别)
初始化设备管理框架的核心组件。
👉 详细文档:3.5.2.4 device_core_init 函数详解
2.5 __driver_stm32_usart_early_driver_init(LOW 子级别)
STM32 串口早期初始化,用于在系统启动早期配置控制台串口。
👉 详细文档:3.5.2.5 __driver_stm32_usart_early_driver_init 函数详解
三、关键点说明
3.1 子级别设计的意义
| 子级别 | 设计考虑 |
|---|---|
| HIGH | 不依赖任何其他初始化,是其他功能的基础 |
| MIDDLE | 依赖 HIGH 级别的初始化结果,为 LOW 级别提供基础 |
| LOW | 依赖前两个级别的初始化,通常是框架层初始化 |
3.2 PRE_KERNEL_1 vs 其他阶段
| 特性 | PRE_KERNEL_1 | PRE_KERNEL_2 | POST_KERNEL |
|---|---|---|---|
| 调度器状态 | 未启动 | 未启动 | 已启动 |
| 可用功能 | 基础硬件操作 | 更多硬件操作 | 完整内核 API |
| 典型内容 | 向量表、板级初始化、设备框架 | 更多硬件、时钟 | 内核组件、驱动 |
3.3 为什么这些函数不能延后?
| 函数 | 不能延后的原因 |
|---|---|
pre_kernel_1_start | 作为起始标记,必须在最前面 |
cortex_m_set_vector | 中断响应需要向量表 |
os_hw_board_init | 后续初始化可能依赖硬件(如串口打印) |
device_core_init | 后续设备驱动注册需要设备框架 |
__driver_stm32_usart_early_driver_init | 后续代码可能需要使用 os_kprintf |
💡 本节总结
重点回顾
- PRE_KERNEL_1 的执行顺序:按子级别 HIGH → MIDDLE → LOW 执行,地址递增顺序就是执行顺序
- 五个核心函数(从 project.map 提取):
pre_kernel_1_start- 阶段起始标记cortex_m_set_vector- 向量表设置os_hw_board_init- 板级硬件初始化device_core_init- 设备框架初始化__driver_stm32_usart_early_driver_init- 串口早期初始化
- 关键约束:调度器未启动,不能使用任务 API
- 真实项目数据来源:从 project.map 搜索
.init_call.1.可以找到所有 PRE_KERNEL_1 函数
下一步
接下来请学习:
- PRE_KERNEL_2 阶段初始化详解 - 继续了解下一阶段的初始化(文档待创建)