好的,去掉流程图后,我们将 RISC-V 架构下 RT-Thread 从启动到运行的过程重新整理为以下四个核心阶段。这个过程基于 “FSBL -> OpenSBI -> RT-Thread (S-Mode)” 的标准启动路径。


阶段一:固件引导

这是硬件上电后的最初阶段,此时 RT-Thread 尚未获得 CPU 控制权。

  1. 硬件复位与 FSBL

    • CPU 上电复位,PC 指针指向 BootROM。
    • BootROM 加载并运行 FSBL(First Stage Boot Loader)。
    • FSBL 初始化 DDR 内存、时钟等基础硬件,将 OpenSBI 镜像加载到内存。
  2. OpenSBI 运行 (M-Mode)

    • CPU 跳转到 OpenSBI 运行,处于机器模式。
    • OpenSBI 初始化所有 CPU 核心,配置中断控制器和 PMP(物理内存保护)。
    • OpenSBI 完成初始化后,通过 sret 指令跳转到 RT-Thread 的入口地址,CPU 特权级从 M-Mode 切换到 S-Mode(监管者模式)。

阶段二:汇编早期初始化

这是 RT-Thread 执行的第一行代码,通常位于 libcpu/risc-v/common/start.S

  1. 入口 _start 与核心分流

    • 所有 CPU 核心同时进入 _start 入口。
    • 代码读取 mhartid 寄存器判断当前是哪个核心。
    • 主核 (Hart ID = 0):继续执行初始化代码。
    • 从核 (Hart ID > 0):跳转到等待循环或直接进入睡眠(WFI),等待主核发送的唤醒信号。
  2. 主核环境配置

    • 关闭中断:操作 mie 寄存器,确保初始化期间不受中断干扰。
    • 设置栈:初始化栈指针 sp,指向预先定义的栈区域。
    • 清空 BSS:将 BSS 段(未初始化全局变量存储区)清零。
    • 跳转 C 代码:汇编初始化完成后,通过 call entry 跳转到 C 语言入口函数。

阶段三:内核 C 初始化

代码进入 C 语言世界,开始构建操作系统内核的核心数据结构,入口函数通常为 entry

  1. 硬件早期初始化 (rt_hw_board_init)

    • 初始化串口(UART),使系统能够打印日志。
    • 初始化堆内存 (rt_system_heap_init)。
    • 初始化中断控制器(如 PLIC),设置中断阈值。
    • 初始化系统时钟。
  2. 内核对象初始化

    • 调度器初始化 (rt_system_scheduler_init):初始化优先级队列和调度链表。
    • 定时器初始化 (rt_system_timer_init):初始化系统定时器。
    • 空闲线程初始化 (rt_system_idle_init):创建优先级最低的空闲线程。
  3. 创建主线程

    • 调用 rt_application_init 创建 main 线程。此时 main 线程处于就绪态,但尚未运行。

阶段四:多核并行启动

这是 SMP(多核)架构特有的步骤,发生在主核初始化的最后阶段。

  1. 主核唤醒从核

    • 主核在启动调度器前,调用 rt_hw_cpu_boot_secondary 函数。
    • 主核通过 SBI 调用(sbi_hart_start)向从核发送启动信号,告知从核的启动入口地址。
  2. 从核响应与初始化

    • 从核从睡眠中醒来,跳转到指定的入口地址(如 secondary_cpu_entry)。
    • 从核设置自己的私有栈空间。
    • 从核初始化本地的中断控制器上下文。
    • 从核调用 rt_system_scheduler_start 加入调度器。

阶段五:调度器启动

这是启动过程的最后一步,标志着操作系统正式接管 CPU。

  1. 启动调度器 (rt_system_scheduler_start)

    • 内核从就绪队列中查找优先级最高的线程(通常是 main 线程)。
    • 执行 rt_hw_context_switch_to,触发第一次上下文切换。
  2. 系统运行

    • CPU 执行 sretmret 指令,从内核初始化代码跳转到 main 线程的入口函数。
    • 系统时钟中断开始周期性触发,调度器开始工作,系统正式进入多任务并行运行状态。
Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐