ucore lab 2
物理内存管理
基本流程
为了完成物理内存管理,首先要探测可用的物理内存资源,了解物理内存位于什么地方,有多大,再以固定页面大小划分整个物理内存空间,准备以此为最小内存分配单位来管理整个物理内存,设置其可用状态为free,used,reserved。再建立页表,启动分页机制,让MMU将预先建好的页表项读到TLB中,根据页表项描述的虚拟页和物理页的对应关系完成CPU对内存的读写执行操作。
在实验中主要关注pmm_init
函数,完成的工作包括:
- 初始化物理内存页管理器框架
pmm_manager
- 建立空闲的page链表,分配以4KB为单位的空闲内存
- 检查物理内存页分配算法
- 为确保切换到分页机制后可执行,建立临时二级页表
- 建立一一映射关系的二级页表
- 开启分页机制
- 重新设置全局段描述符表
- 取消临时二级页表
- 检查页表建立是否正确
- 通过自映射机制完成页表打印输出(扩展内容)
探测系统物理内存布局
获取内存大小方法由BIOS中断调用和直接探测两种。BIOS中断调用一般只能在实模式下完成,直接探测方法必须在保护模式下完成。终端获取内存布局有三种方法,基于INT 15h中断,分别为88h,e801h和e820h,并非所有情况三种都生效,在linux中是依次尝试三种方法。在本实验中采用e820h来实现。因为在实模式下,因此写在了bootloader中,调用该中断,将映射结构保存在0x8000处。
INT 15h能完成一系列功能,这里调用参数为e820h的INT 15h BIOS中断,获取内存映射地址描述符。
INT 15h中断这里的调用参数如下
1 | eax: e820h |
返回值如下:
1 | eflags CF位:中断执行成功则不置位,否则置位 |
我们便可以通过此中断调用,递增di的值(20的倍数),从而找到内存布局的entry,放到保存地址范围描述副结构的缓冲区中,便于后续ucore管理。该缓冲区结构体定义如下:
1 | struct e820map { |
接下来我们来观察在bootloader中的汇编码实现探测内存,汇编代码如下:
1 | probe_memory: |
以页为单位管理物理内存
获得可用内存范围后,需要建立想对应数据结构来完成管理操作,4KB对齐。这里每个物理页采用Page的数据结构来实现,Page设计需要尽量小