main函数之kvmalloc
1. kvmalloc函数
这个函数主要就是分配一个页表给内核进程用于调度:
kpgdir是一个全局变量,用于记录内核进程的页目录基址,kvmalloc获得页目录后,调用switchkvm将页目录基址更新到cr3寄存器中:
由于寄存器用的是物理地址,所以需要将kpgdir转换为物理地址才能使用。
2. setupkvm函数
- 第一个成员表示要映射的虚拟地址。
- 第二个成员表示要映射物理地址起始地址。
- 第三个成员表示要映射物理地址结尾地址。
- 第四个表示映射的属性。
上面的描述和sylixos下的map.h描述好类似。。。。。
其中要说明的是data这个符号,这个符号是在链接脚本中定义的:
PROVIDE(symbol) 在链接脚本中定义某个符号。该符号再程序中可以被引用。可以看出data符号地址是页对齐的。同时data表示的就是内核数据区起始的虚拟地址。
kmap表示的映射关系如下:
映射关系很简单:
- KERBASE~KERBASE+PHYSTOP这段虚拟空间映射到0~PHYSTOP这段物理地址空间。
- 0xFE000000~4GB这段虚拟地址空间映射到0xFE000000~4GB物理地址空间,也就是一一映射。
2.2 mappages函数
- 首先将要映射的虚拟地址页对齐。
- 将要映射的大小也页对齐,然后计算映射的结尾地址。
- 通过walkpgdir获得一个pte入口。
- 检查次pte是否已经被使用。
- 设置pte条目。
- 检查是否映射结束。
- 更新虚拟地址和物理地址,然后继续上述步骤。
2.3 walkpgdir函数
- 通过虚拟地址获得在页目录中对应的页目录条目。
- 检查页目录项是否有效,如果有效,说明此页目录项有对应的二级页表。然后从页目录项中取得页表的基址然后转换成虚拟地址以用来访问。
- 如果页目录项无效,则说明对应的二级页表不存在。则先申请一页物理页用作二级页表,然后将二级页表清零,接着将二级页表的基址和页属性设置到页目录中。
- 最后将虚拟地址对应的二级页表项地址返回。
由此可知,walkpgdir函数的功能就是找到一个虚拟地址所对应的二级页表项。
kvmalloc函数的作用就是根据内核的kmap定义的映射关系,建立实现定义好的虚拟地址和物理地址之间的映射,也就是初始化新的内核页目录和页表。
评论