初始化

本节目录

页表和 MMU

  • Linux 内核运行需要 MMU 启用
  • 内核刚开始运行,MMU 未启用
  • 需要写好一个页表将内核映射到高地址,然后启用 MMU

Risc-V 页表初始化

setup_vm 初始化启动用到的两个页表:

  • trampoline_pg_dir:启用 MMU 前后所用,映射启用 MMU 的代码到高地址
  • early_pg_dir:内核最初启动的时候所用,映射整个内核到高地址

具体的实现逻辑,请自学或参照老师的课程进行学习。

启用 MMU 前后

relocate_enable_mmu 用于启用 MMU,并跳转到高地址继续执行:

  • 使用 trampoline_pg_dir 衔接
  • 启用 MMU
  • 返回后 pc 在高地址

这一部分涉及到一个问题:内核启动时从 0x4020_0000 开始,而内核代码需要在 0xFFFFFFFF80000000 运行。如何配置 MMU 来完成这个切换?

通过配置 MMU 来完成这个切换的方法是:

直接设置返回地址加上偏移量的结果,将其变成高地址,这样在返回后就能正确运行了。

Risc-V 异常向量初始化

通过 setup_trap_vector 初始化异常向量:

  • RISC-V Linux 使用一个统一的入口点 handle_exception 来处理异常和中断
  • scratch=0 表示异常从内核态发生
  • sscratch ≠ 0 时,它指向一个 task_struct 结构体,表示异常从用户态发生
  • RISC-V 的系统调用也被视为一种异常处理

小结

在 Risc-V 初始化过程中,主要完成以下任务:

  • 设置初始化时的简单页表 early_pg_dir,并开启虚拟内存机制(MMU)
  • 设置异常向量 stvec 指向 handle_exception 函数
    • 在处理异常之前保存进程上下文
    • 在返回进程之前恢复其上下文