Xv6内核分析(三.2)

gewenbin
gewenbin
gewenbin
188
文章
15
评论
2020年12月20日15:33:41 评论 437

main函数之kvmalloc

1. kvmalloc函数

这个函数主要就是分配一个页表给内核进程用于调度:

Xv6内核分析(三.2)

kpgdir是一个全局变量,用于记录内核进程的页目录基址,kvmalloc获得页目录后,调用switchkvm将页目录基址更新到cr3寄存器中:

Xv6内核分析(三.2)

由于寄存器用的是物理地址,所以需要将kpgdir转换为物理地址才能使用。

2. setupkvm函数

Xv6内核分析(三.2)

  • 先申请一页物理页空间用作页目录。
  • 将刚才的页目录空间全部清零。
  • 检查xv6所支持的总内存大小。
  • 调用mappages函数将kmap中描述的物理地址和虚拟地址一一建立映射。

2.1 kmap数组

Xv6内核分析(三.2)

  • 第一个成员表示要映射的虚拟地址。
  • 第二个成员表示要映射物理地址起始地址。
  • 第三个成员表示要映射物理地址结尾地址。
  • 第四个表示映射的属性。

上面的描述和sylixos下的map.h描述好类似。。。。。

其中要说明的是data这个符号,这个符号是在链接脚本中定义的:

Xv6内核分析(三.2)

PROVIDE(symbol) 在链接脚本中定义某个符号。该符号再程序中可以被引用。可以看出data符号地址是页对齐的。同时data表示的就是内核数据区起始的虚拟地址。

kmap表示的映射关系如下:

Xv6内核分析(三.2)

映射关系很简单:

  • KERBASE~KERBASE+PHYSTOP这段虚拟空间映射到0~PHYSTOP这段物理地址空间。
  • 0xFE000000~4GB这段虚拟地址空间映射到0xFE000000~4GB物理地址空间,也就是一一映射。

2.2 mappages函数

Xv6内核分析(三.2)

  • 首先将要映射的虚拟地址页对齐。
  • 将要映射的大小也页对齐,然后计算映射的结尾地址。
  • 通过walkpgdir获得一个pte入口。
  • 检查次pte是否已经被使用。
  • 设置pte条目。
  • 检查是否映射结束。
  • 更新虚拟地址和物理地址,然后继续上述步骤。

2.3 walkpgdir函数

Xv6内核分析(三.2)

  • 通过虚拟地址获得在页目录中对应的页目录条目。
  • 检查页目录项是否有效,如果有效,说明此页目录项有对应的二级页表。然后从页目录项中取得页表的基址然后转换成虚拟地址以用来访问。
  • 如果页目录项无效,则说明对应的二级页表不存在。则先申请一页物理页用作二级页表,然后将二级页表清零,接着将二级页表的基址和页属性设置到页目录中。
  • 最后将虚拟地址对应的二级页表项地址返回。

由此可知,walkpgdir函数的功能就是找到一个虚拟地址所对应的二级页表项。

kvmalloc函数的作用就是根据内核的kmap定义的映射关系,建立实现定义好的虚拟地址和物理地址之间的映射,也就是初始化新的内核页目录和页表。

gewenbin
  • 本文由 发表于 2020年12月20日15:33:41
  • 转载请务必保留本文链接:http://www.databusworld.cn/9286.html
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: