diff --git a/lab2/lab2_3_3_5_4_maping_relations.md b/lab2/lab2_3_3_5_4_maping_relations.md index bd743e8..bc4fa2a 100644 --- a/lab2/lab2_3_3_5_4_maping_relations.md +++ b/lab2/lab2_3_3_5_4_maping_relations.md @@ -1,5 +1,5 @@ ### 系统执行中地址映射的三个阶段 -原理课上讲到了页映射,段映射,以及段页式映射关系,但对如何建立段页式映射关系没有详说。其实,在lab1和lab2中都会涉及如何建立映射关系的操作。在lab1中,我们已经碰到到了简单的段映射,即对等映射关系,保证了物理地址和虚拟地址相等,也就是通过建立全局段描述符表,让每个段的基址为0,从而确定了对等映射关系。在lab2中,由于在段地址映射的基础上进一步引入了页地址映射,形成了组合式的段页式地址映射。这种方式虽然更加灵活了,但实现稍微复杂了一些。在lab2中,为了建立正确的地址映射关系,ld在链接阶段生成了ucore OS执行代码的虚拟地址,而bootloader与ucore OS协同工作,通过在运行时对地址映射的一系列“腾挪转移”,从计算机加电,启动段式管理机制,启动段页式管理机制,在段页式管理机制下运行这整个过程中,虚拟地址到物理地址的映射产生了多次变化,实现了最终的段页式映射关系: +原理课上讲到了页映射、段映射以及段页式映射关系,但对如何建立段页式映射关系没有详说。其实,在lab1和lab2中都会涉及如何建立映射关系的操作。在lab1中,我们已经碰到到了简单的段映射,即对等映射关系,保证了物理地址和虚拟地址相等,也就是通过建立全局段描述符表,让每个段的基址为0,从而确定了对等映射关系。在lab2中,由于在段地址映射的基础上进一步引入了页地址映射,形成了组合式的段页式地址映射。这种方式虽然更加灵活了,但实现稍微复杂了一些。在lab2中,为了建立正确的地址映射关系,ld在链接阶段生成了ucore OS执行代码的虚拟地址,而bootloader与ucore OS协同工作,通过在运行时对地址映射的一系列“腾挪转移”,从计算机加电,启动段式管理机制,启动段页式管理机制,在段页式管理机制下运行这整个过程中,虚拟地址到物理地址的映射产生了多次变化,实现了最终的段页式映射关系: ``` virt addr = linear addr = phy addr + 0xC0000000 ``` @@ -82,9 +82,9 @@ next: 总结来看,这一阶段的目的就是更新映射关系的同时将运行中的内核(EIP)从低虚拟地址“迁移”到高虚拟地址,而不造成伤害。 -不过,这还不是我们期望的映射关系,因为它仅仅映射了0~4MB。对于段表而言,也缺少了很多运行ucore所需的表项。 +不过,这还不是我们期望的映射关系,因为它仅仅映射了0~4MB。对于段表而言,也缺少了运行ucore所需的用户态段描述符和TSS(段)描述符相应表项。 -**第三个阶段**(完善段表和页表)从pmm_init函数被调用开始。pmm_init函数将页目录表项补充完成(从0~4M扩充到0~KMEMSIZE),然后更新了段映射。 +**第三个阶段**(完善段表和页表)从pmm_init函数被调用开始。pmm_init函数将页目录表项补充完成(从0~4M扩充到0~KMEMSIZE)。然后,更新了段映射机制,使用了一个新的段表。这个新段表除了包括内核态的代码段和数据段描述符,还包括用户态的代码段和数据段描述符以及TSS(段)的描述符。理论上可以在第一个阶段,即bootloader阶段就将段表设置完全,然后在此阶段继续使用,但这会导致内核的代码和bootloader的代码产生过多的耦合,于是就有了目前的设计。 这时形成了我们期望的虚拟地址、线性地址以及物理地址之间的映射关系: