Linux 0.11中的页目录表及页表内容分析

Linux0.11针对的内存是16M。采用了两级分页机制进行内存的管理。

根据head.s中第114行的.org 0x1000可知,物理地址0x1000之前的所有数据都将被页目录表覆盖(这个覆盖,是指更改了内存中的内核镜像文件,而不是磁盘上的内核镜像文件)。

1、首先,Linux从0x00000地址开始对五页内存进行清零。(1页页目录表+4页页表)

1 setup_paging:
2 movl $10245,%ecx / 5 pages - pg_dir+4 page tables /
3 xorl %eax,%eax
4 xorl %edi,%edi /
pg_dir is at 0x000 */
5 cld;rep;stosl
2、接着,填写页目录表(页目录表的位置为0x00000-0x00fff,大小为4K,每一项占4字节)。因为只有4个页表,所以只填写了前四项。

1 movl $pg0+7,pg_dir /* set present bit/user r/w /
2 movl $pg1+7,pg_dir+4 /
--------- " " --------- /
3 movl $pg2+7,pg_dir+8 /
--------- " " --------- */
4 movl p g 3 + 7 , p g d i r + 12 / ∗ − − − − − − − − − " " − − − − − − − − − ∗ / 这里, 4 个页目录项的内容分别是 pg3+7,pg_dir+12 /* --------- " " --------- */ 这里,4个页目录项的内容分别是 pg3+7,pgdir+12/""/这里,4个页目录项的内容分别是pg0(1,2,3)+7,分别是4个页表的物理地址+111B。前面的$pg0(1,2,3)是页表的物理地址,而111B则代表这4个页表权限为可读写。

3、填写页表项的内容

1 movl $pg3+4092,%edi
2 movl $0xfff007,%eax /* 16Mb - 4096 + 7 (r/w user,p) /
3 std
4 1: stosl /
fill pages backwards - more efficient 😃 /
5 subl 0 x 1000 , 6 j g e 1 b 这里的填写是逆序填写的,也就是首先将 16 M 物理内存最后一页的启始地址 + 权限 ( 16 M − 4 K + 111 B ) 填写到第 4 张页表的最后一项。地址为 0x1000,%eax 6 jge 1b 这里的填写是逆序填写的,也就是首先将16M物理内存最后一页的启始地址+权限(16M-4K+111B)填写到第4张页表的最后一项。地址为 0x1000,6jge1b这里的填写是逆序填写的,也就是首先将16M物理内存最后一页的启始地址+权限(16M4K+111B)填写到第4张页表的最后一项。地址为pg3+4092,其中$pg3为(第4张页表的起始地址),4092是因为1024
4(1024项,每项占用4字节)-4(最后一项页占用4字节)。所以第4张页表的最后一项是(16M-4K)0xfff000+111B=0xfff007。

最终,std以4递减edi寄存器(一个页表项占4字节,edi指向正在操作的页表项),subl $0x1000,%eax将减去0x1000(一页内存的大小,eax指向正在操作的内存边界),l:stosl是填写页表项,知道eax的内容为0,这样就填写完了4个页表。

这样,内存中的页目录表和页表分布就是:
在这里插入图片描述
最后,把页目录表的地址(0x000000)写到控制寄存器CR3,然后置控制寄存器CR0的PG位,这样就开启了内存的分页管理功能。
Linux0.11在分页机制下的寻址(两级表寻址)

第一级表称为页目录。

存放在1页4k页面中。具有1k个4字节长度的表项。这些表项指向第二级表。线性地址的最高10位(位31-22)用作一级表(页目录)中的索引值来选择某个页目录项,用以选择某个二级表。

第二级表称为页表。

长度也是1个页面,每个表含有1k个4字节的表项。每个4字节表项含有相关页面的20位物理地址。二级页表使用线性地址中间的10位(位21-12)作为表项索引值,在表内索引含有页面20位物理地址的表项。该20位页面物理地址和线性地址中的低12位(页内偏移)组合在一起就得到了分页转换中的输出值,也就是最终的物理地址。

也就是说:

线性地址高10位---------索引页目录表----------->找到相应页表

线性地址中间10位---------索引页表----------->得到页表中相应的项,其中的高20位就是物理地址的高20位

线性地址低12位-------------------->物理地址的低12位
在这里插入图片描述
下面举两个例子说明Linux0.11的分页寻址。

1、寻址0x38

首先写成32位地址为0x0000 0038。取最高10位,0000 0000 00B,索引页目录项。这里找到页目录表的第0项,内容为$pg0+7=0x0000 1007。取线性地址的中间10位,00 0000 0000B,索引页表1(pg0)中的第0项,内容为

0x0000 0000+7,取他的高20位0x0000 0加上线性地址的低12位0x038就得到最终的物理地址0x0000 0038

2、寻址0x00f5 9f50

首先取最高10位,0000 0000 11,索引页目录表。这里为3就找到页目录表的第3项,指向页表4,内容为$pg3+7=0x0000 4000+7。取线性地址的中间10位,11 0101 1001B,索引页表4(pg3)中的0x359项,内容为0x00f5 9000+7。取其高20位0x00f5 9000加上线性地址的低12位0xf50就得到最终的物理地址0x00f5 9f50

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值