linux高端内存与内存映射——重要

本文详细介绍了Linux内核空间和用户空间的划分,强调了内核如何使用高端内存进行地址映射,包括段页式地址映射模型、内核如何初始化页表以及高端内存的管理方式,如临时映射、持久内核映射和内核动态映射。通过理解这些机制,可以更好地了解Linux内核如何高效地管理和访问物理内存。
摘要由CSDN通过智能技术生成
Linux 操作系统和驱动程序运行在内核空间,应用程序运行在用户空间,两者不能简单地使用指针传递数据,因为Linux使用的虚拟内存机制,用户空间的数据可能被换出,当内核空间使用用户空间指针时,对应的数据可能不在内存中。

内核空间和用户空间

用户空间:在Linux中,每个用户进程都可以访问4GB的线性虚拟内存空间。其中从0到3GB的虚存地址是用户空间,通过每个进程自己的页目录、页表,用户进程可以直接访问。

内核空间:从3GB到4GB的虚存地址为内核态空间,存放供内核访问的代码和数据用户态进程不能访问,只有内核态进程才能寻址。所有进程从3GB到4GB的虚拟空间都是一样的,linux以此方式让内核态进程共享代码段和数据段。

由于虚拟机制的引入,进程的可以使用32位地址系统支持的全部4G线性空间。进程的线性地址空间分成两部分:

  • 从0x00000000 到 0xbfffffff的线性地址,无论用户态还是内核态的进程都可以寻址。
  • 从0xc0000000 到 0xffffffff的线性地址,只有内核态的进程才能寻址。

当进程运行在用户态时,它产生的线性地址小于0xc0000000;当进程运行在内核态时,它执行内核代码,所产生的线性地址大于等于0xc0000000、且所有进程共享。如果是多核CPU,那么就会出现多个进程并发访问这些地址的现象,这里就要牵扯到临界区资源,也就是我们将来在介绍同步与互斥内容中要重点讨论的。宏PAGE_OFFSET产生的值就是0xc0000000,这就是进程在线性地址空间中的偏移量,也是内核生存空间的开始之处。

页全局目录被分成了两部分,的第一部分表项映射的线性地址小于0xc0000000(共1024项,在PAE未启用时是前768项,PAE启动时是前3项),具体大小依赖特定进程。相反,剩余的表项对所有进程来说都应该是相同的,它们等于主内核页全局目录的相应表项。

那么,什么又是主内核页全局目录呢?内核维持着一组自己使用的页表,驻留在所谓主内核页全局目录(master kernel Page Global Directory)中。系统初始化后,这组页表还从未被任何进程或任何内核线程直接使用,主要用来为系统中每个普通进程对应的页全局目录项提供参考模型。

内核如何初始化自己的页表?这个过程分为两个阶段。事实上,内核映像刚刚被装入内存后,CPU仍然运行于实模式,所以分页功能没有被启用。 第一个阶段,内核创建一个有限的地址空间,包括内核的代码段和数据段、初始页表和用于存放动态数据结构的共128KB大小的空间。这个最小限度的地址空间仅足够将内核装入RAM和对其初始化的核心数据结构。 第二个阶段,内核充分利用剩余的RAM并适当地建立分页表。


Linux内核地址映射模型

x86 CPU采用了段页式地址映射模型。进程代码中的地址为逻辑地址,经过段页式地址映射后,才真正访问物理内存。

段页式机制如下图。

 

Linux内核地址空间划分

通常32位Linux内核地址空间划分0~3G为用户空间,3~4G为内核空间。注意这里是32位内核地址空间划分,64位内核地址空间划分是不同的。

 

Linux内核高端内存的由来

当内核模块代码或线程访问内存时,代码中的内存地址都为逻辑地址,而对应到真正的物理内存地址,需要地址一对一的映射,如逻辑地址0xc0000003对应的物理地址为0×3,0xc0000004对应的物理地址为0×4,… …,逻辑地址与物理地址对应的关系为

物理地址 = 逻辑地址 – 0xC0000000

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值