初始化
本节目录
页表和 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 函数
- 在处理异常之前保存进程上下文
- 在返回进程之前恢复其上下文