Linux内核代码笔记2----内存寻址

硬件中的分段
     逻辑地址由一个16位的段选择符(segment selector)和32位的偏移量(offset)组成。偏移量就是段内相对地址。 段寄存器就是存放段选择符的,包括cs、ss、ds、es、fs、gs。其中:
    cs(代码段寄存器):指向程序指令段;
    ss(栈段寄存器):指向当前程序栈的段;
    ds(数据段寄存器):指向包含静态数据or全局数据段。
    cs寄存器还有一个字段包含CPU当前特权等级(Current Privilege Level,CPL)。值0为最高优先级,值3为最低优先级。Linux只有0级和3级,分别称为 内核态和用户态

段描述符
    每个段由一个8字节的段描述符(segment descriptor)表示。 段描述符放在 全局描述符表(Global Descriptor Table,GDT)或 局部描述符表(Local Descriptor Table,LDT)中。
    GDT在主存中的地址和大小存放在gdtr控制寄存器中,当前正在使用的LDT地址和大小放在ldtr控制寄存器中。

Linux中的分段
    Linux对分段支持很有限,2.6kernel中只有8086结构下才使用分段,其余使用分页方式。
    运行在用户态的Linux进程用两个相同的段对指令和数据进行寻址,这两个段就是 用户代码段用户数据段。在内核中同样有内核代码段和内核数据段。

硬件中的分页
     分页单元(paging unit)把线性地址转为物理地址。把所请求的访问类型与线性地址的访问权限相比,如果访问无效,则产生一个 缺页异常。线性地址被分为固定长度为单位的组,称为 (page)。分页单元把所有的RAM分成固定长度的 页框(page frame),也称为 物理页。每一个页框包含一个页。
    把线性地址映射为物理地址的数据结构成为 页表(page table)。页表存放在主存中,在启用分页单元前由内核进行初始化。
常规分页
    从80386起,Intel CPU支持4KB的页。
    为了减少每个进程页表所需RAM数量,线性地址转换分为两步:页目录表(page directory)->页表(page table)。(与上面的页表不一个概念)。正在使用的页目录的物理地址存放在控制寄存器cr3中。线性地址内的Directory字段决定页目录中的目录项,目录项指向适当的页表。线性地址的Table字段决定页表中的表项,表项含有页所在页框的物理地址。Offset字段决定页框内的相对位置。Offset是12位,因此每一页容量为4096字节。Directory和table分别是10位,因此寻址范围为:1024×1024×4096=2^32。
    
扩展分页
    从Pentium开始,引入了 扩展分页,允许页框的大小由4KB变为4MB,用于把大段连续的线性地址转为物理地址。内核因此可以不用中间页表进行地址转换,节省内存,保留TLB项。
转换后援缓冲器(Translation Lookaside Buffer,TLB,俗称“ 快表”),是一个高速缓存,用于加快线性地址的转换。
物理地址扩展(Physical Address Extension,PAE),允许内核使用高达64GB的RAM。但是,它针对的是物理地址,并没有扩大用户态程序的线性地址范围。
    

Reference
1、深入理解Linux内核-第3版

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值