深入理解Linux内核之内存寻址

内存寻址

内存地址

逻辑地址

机器语言指令中用来指定一个操作数或者一条指令的地址

每一个逻辑地址由一个段和偏移量组成

偏移量指明了从段开始的地方到实际地址之间的距离.

线性地址(虚拟地址)

32位无符号整数,可以表达4GB的地址

物理地址

内存芯片级单元寻址

关系:

分段机制:逻辑地址->线性地址
分页机制:线性地址->物理地址

段选择符和段寄存器

逻辑地址组成:段标识符+偏移量
段标识符16位长,称为段选择符.偏移量32位长.

为了快速找到段选择符,提供段寄存器

段寄存器目的:存放段选择符

段寄存器只有6个,但有3个有专门用途:

cs 代码段寄存器 指向包含程序指令的段
ss 栈段寄存器 包含当前程序栈的段
ds 数据段寄存器 包含静态数据或者全局数据段

cs段有一个两位字段(CPL),0表示最高优先级(内核态),3表示最低优先级(用户态)

段描述符

每个段由一个8byte的段描述符表示,用于描述段的特征
它描述了段的特征,段描述符放在全局描述符表(GDT)或者局部描述符表(LDT)中
通常只定义一个GDT,每个进程除了存放在GDT中的段之外如果还需要创建附加的段,就可以有自己的LDT.

快速访问段描述符

逻辑地址48bit:16bit的段选择符+32bit的偏移量

段寄存器存放段选择符

分段单元

1.先检查段选择符的TI字段,以决定段描述符保存在哪一个描述符表中.TI字段指明描述符是在GDT中还是在LDT中,
2.段选择符的index字段*8与gdtr或者ldtr寄存器中内容相加
3.把逻辑地址的偏移量与段描述符Base字段的值相加就得到了线性地址

Linux的分段

分段和分页实际上都是划分进程的物理地址空间:

分段可以给每个进程分配不同的线性地址空间

分页可以给同一线性地址空间映射到不同的物理空间

所有段从0x00000000开始,linux下逻辑地址和线性地址是一致的,即逻辑地址的偏移量字段的值与相应的线性地址的值总是一致的.

段寄存器会随着内核特权级别而更新.当为用户态的时候,ds寄存器必须含有用户数据段的段选择符,ss也是.以此类推,内核态也是这样.

当对指向指令或者数据结构的指针进行保存的时候,内核不需要为其设置逻辑地址的段选择符.因为已经保存在了cs寄存器中

Linux GDT

单处理器系统中只有一个GDT,多处理器系统中每个CPU对应一个GDT

分页机制

分页单元把线性地址转换为物理地址

线性地址分为固定长度的页,页内部的连续线性地址被映射到连续的物理地址当中.

页既指一组线性地址,又指包含在这组中的数据.

然后分页把所有RAM分为固定长度的页框,每一个页框包含一个页,也就是说一个页框的长度与一个页的长度一致.

页只是一个数据块,可以存放在页框或者磁盘中

而页框是主存中的物理地址

TLB

一个高速缓存,用于加快线性地址的转换.
当一个线性地址第一次使用的时候,可以通过访问RAM中的页表计算出相应的物理地址.
同时物理地址被存放在一个TLB表项中.

物理内存布局

初始化阶段,内核必须建立一个物理地址映射来指定哪些物理地址范围内对内核可用那些不可用.

进程页表

进程的线性地址空间分为两部分.

从0x00000000到oxbfffffff的线性地址.无论进程运行在用户态还是内核态都可以寻址
从0xc0000000 到0xffffffff的线性地址,只有内核态的进程才能够寻址

进程运行在用户态的时候,产生的线性地址小鱼0xc0000000,进程运行在内核态的时候,执行内核代码,产生地址大于等于0xc0000000.

内核页表

内核维持着一组自己使用的页表,驻留在所谓的主内核页全局目录中,系统初始化后,这组页表还从来没有被任何进程或者线程使用,第一个阶段内核创建一个有限的地址空间,这个空间仅能够装入RAM和对其初始化的核心数据结构.

第二个阶段,内核充分利用剩余的RAM并且适当地建立分页表.

固定映射的线性地址

至少128MB的线性地址总是留作他用,因为内核使用这些线性地址实现非连续内存分配和固定映射的线性地址.

内核使用固定映射的线性地址来代替指针变量,因为这些指针变量的值从来不改变.

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
内存工作原理 1.内存寻址 首先,内存从CPU获得查找某个数据的指令,然后再找出存取资料的位置时(这个动作称为“寻址”),它先定出横坐标(也就是“列地址”)再定出纵坐标(也就是“行地址”),这就好像在地图上画个十字标记一样,非常准确地定出这个地方。对于电脑系统而言,找出这个地方时还必须确定是否位置正确,因此电脑还必须判读该地址的信号,横坐标有横坐标的信号(也就是RAS信号,Row Address Strobe)纵坐标有纵坐标的信号(也就是CAS信号,Column Address Strobe),最后再进行读或写的动作。因此,内存在读写时至少必须有五个步骤:分别是画个十字(内有定地址两个操作以及判读地址两个信号,共四个操作)以及或读或写的操作,才能完成内存的存取操作。 2.内存传输 为了储存资料,或者是从内存内部读取资料,CPU都会为这些读取或写入的资料编上地址(也就是我们所说的十字寻址方式),这个时候,CPU会通过地址总线(Address Bus)将地址送到内存,然后数据总线(Data Bus)就会把对应的正确数据送往微处理器,传回去给CPU使用。 3.存取时间 所谓存取时间,指的是CPU读或写内存内资料的过程时间,也称为总线循环(bus cycle)。以读取为例,从CPU发出指令给内存时,便会要求内存取用特定地址的特定资料,内存响应CPU后便会将CPU所需要的资料送给CPU,一直到CPU收到数据为止,便成为一个读取的流程。因此,这整个过程简单地说便是CPU给出读取指令,内存回复指令,并丢出资料给CPU的过程。我们常说的6ns(纳秒,秒-9)就是指上述的过程所花费的时间,而ns便是计算运算过程的时间单位。我们平时习惯用存取时间的倒数来表示速度,比如6ns的内存实际频率为1/6ns=166MHz(如果是DDR就标DDR333,DDR2就标DDR2 667)。 4.内存延迟 内存的延迟时间(也就是所谓的潜伏期,从FSB到DRAM)等于下列时间的综合:FSB同主板芯片组之间的延迟时间(±1个时钟周期),芯片组同DRAM之间的延迟时间(±1个时钟周期),RAS到CAS延迟时间:RAS(2-3个时钟周期,用于决定正确的行地址),CAS延迟时间 (2-3时钟周期,用于决定正确的列地址),另外还需要1个时钟周期来传送数据,数据从DRAM输出缓存通过芯片组到CPU的延迟时间(±2个时钟周期)。一般的说明内存延迟涉及四个参数CAS(Column Address Strobe 行地址控制器)延迟,RAS(Row Address Strobe列地址控制器)-to-CAS延迟,RAS Precharge(RAS预冲电压)延迟,Act-to-Precharge(相对于时钟下沿的数据读取时间)延迟。其中CAS延迟比较重要,它反映了内存从接受指令到完成传输结果的过程中的延迟。大家平时见到的数据3—3—3—6中,第一参数就是CAS延迟(CL=3)。当然,延迟越小速度越快。
深入理解Linux内核是一个非常广泛的话题,需要对计算机体系结构、操作系统理论、计算机网络等多个领域有深入的了解。下面是一些学习Linux内核的建议。 1. 操作系统原理:学习操作系统的基本原理,包括进程管理、内存管理、文件系统、设备管理等方面的知识。可以参考经典教材《操作系统概念》、《现代操作系统》等。 2. C语言编程:Linux内核主要使用C语言编写,因此需要熟练掌握C语言的语法和常用库函数。可以参考经典教材《C程序设计语言》、《C和指针》等。 3. 计算机体系结构:学习计算机的硬件体系结构,包括处理器、内存、I/O设备等。可以参考经典教材《计算机组成原理》、《现代操作系统》等。 4. Linux内核源码:深入理解Linux内核需要阅读和理解Linux内核源码。可以从最基础的启动代码、内存管理、进程管理等模块开始,逐步深入到文件系统、网络等模块。可以参考《Linux内核源代码情景分析》、《深入Linux内核架构》等书籍。 5. 内核调试工具:学习使用内核调试工具,如gdb、strace、ltrace等工具,可以帮助理解内核的执行过程和调用关系。 6. 社区参与:Linux内核是一个开放的社区项目,可以通过参与社区讨论、提交代码等方式深入了解内核的运作机制。可以参考Linux内核源码仓库、LWN.net等网站。 需要注意的是,深入理解Linux内核是一个非常庞大的工程,需要付出长期的努力和耐心。建议从基础知识开始逐步深入,不断扩大知识面和阅读范围,多动手实践,不断提升自己的编程和调试能力。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值