linux分页机制

   在linux分页机制中有几个概念需要了解,线性地址,物理地址,页目录表,页表,页目录项,页表项。

   首先为了防止一个进程非法跨越到另一个进程或者一个进程非法跨越到内核中,linux中使用了线性地址。线性地址是一个进程执行过程中产生的地址,在32位的系统中其地址空间为0x00000000 - 0xffffffff,其中0xc00000000 - 0xbfffffff无论是用户进程还是内核进程都可以访问。0xcfffffff - 0xffffffff只有内核态进程可以访问。当进程运行在用户态的时候产生的地址小于0xc00000000,运行在内核态的时候产生的线性地址大于0xc00000000,但是某些需要访问用户态的时候也会产生用户态线性地址。

    32位的线性地址按照10/10/12的分为三个部分,第一个10位用于在页目录表中索引页表地址,第二个10用于在索引的到的页表中索引特定的页,最后的12位为在页中的偏移。在linux内核0.11版本中,总共有一个页目录表,一个页目录表的大小是4k。页目录中保存着页目录项,每个页目录项为32位。也就是说每个页目录表总共有1024个页表。每个页目录项的32位有20位用于索引页表,其他的位用于表示页目录项的属性。同理,每个页表也是4k,掌控1024个页。


P--位0是存在(Present)标志,用于指明表项对地址转换是否有效。P=1表示有效;P=0表示无效。在页转换过程中,如果说涉及的页目录或页表的表项无效,则会导致一个异常。如果P=0,那么除表示表项无效外,其余位可供程序自由使用,如图4-18b所示。例如,操作系统可以使用这些位来保存已存储在磁盘上的页面的序号。

R/W--位1是读/写(Read/Write)标志。如果等于1,表示页面可以被读、写或执行。如果为0,表示页面只读或可执行。当处理器运行在超级用户特权级(级别0、1或2)时,则R/W位不起作用。页目录项中的R/W位对其所映射的所有页面起作用。

U/S--位2是用户/超级用户(User/Supervisor)标志。如果为1,那么运行在任何特权级上的程序都可以访问该页面。如果为0,那么页面只能被运行在超级用户特权级(0、1或2)上的程序访问。页目录项中的U/S位对其所映射的所有页面起作用。


     X86结构中,Linux内核代码加上初始化必要的一些数据,被装载在物理内存从1M开始的地址上(1M以内的地址留给BIOS或者其他特殊的用途)。虽然内核的大小是不确定的,但通常0-8M的地址范围足够保存这些内容。这些内容依次为:内核代码、已初始化的内核数据、未初始化的内核数据。

内核刚刚被装入内存时,分页功能还未启用,为了允许CPU在实模式和保护模式之间切换的过程中,都能对这8M的地址进行访问,内核需要建立两张临时的页表,其结果是将0x00000000-0x007FFFFF和0xC0000000-0xC07FFFFF的线性地址同时映射到0x00000000-0x007FFFFF的物理地址上。这两张页表我们称为临时内核页表pg0和pg1。

当然,为了寻址这两张页表,首先要建立一个页全局目录,我们称为临时页全局目录,它被存放在swapper_pg_dir变量中。因为暂时只需要映射两张页表,算上0x00000000-0x007FFFFF和0xC0000000-0xC07FFFFF两个地址段,我们此时只需要初始化该目录中的4项就可以了,而将其余1020项全部设为0。

将我们需要映射的线性地址按照10/10/12个bit位展开,就可以知道我们需要的是哪4项了。

0x00000000 -> 0x000 / 0x000 / 0x000

0x007FFFFF -> 0x001 / 0x3FF / 0xFFF

0xC0000000 -> 0x300 / 0x000 / 0x000

0xC07FFFFF -> 0x301 / 0x3FF / 0xFFF

取出对应页目录项的前10bit,可以知道我们需要初始化的4个页目录项为0x0、0x1、0x300、0x301。其中0x0和0x300对应pg0,0x1和0x301对应pg1。

至此建立起临时页表,下一步建立内核最终页表。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值