解析Linux系统下的高端内存

作者&投稿:贾甘 (若有异议请与网页底部的电邮联系)
~ Linux内核地址空间划分
通常32位Linux内核虚拟地址空间划分0~3G为用户空间,3~4G为内核空间(注意,内核可以使用的线性地址只有1G)。注意这里是32位内核地址空间划分,64位内核地址空间划分是不同的。
通常32位Linux内核虚拟地址空间划分0~3G为用户空间,3~4G为内核空间(注意,内核可以使用的线性地址只有1G)。注意这里是32位内核地址空间划分,64位内核地址空间划分是不同的。
 Linux内核高端内存的由来
当内核模块代码或线程访问内存时,代码中的内存地址都为逻辑地址,而对应到真正的物理内存地址,需要地址一对一的映射,如逻辑地址0xc0000003对应的物理地址为0×3,0xc0000004对应的物理地址为0×4,… …,逻辑地址与物理地址对应的关系为
物理地址 = 逻辑地址 – 0xC0000000:这是内核地址空间的地址转换关系,注意内核的虚拟地址在“高端”,但是ta映射的物理内存地址在低端。
实际上,“内核直接映射空间”也达不到 1G, 还得留点线性空间给“内核动态映射空间” 呢。
因此,Linux 规定“内核直接映射空间” 最多映射 896M 物理内存。
对于高端内存,可以通过 alloc_page() 或者其它函数获得对应的 page,但是要想访问实际物理内存,还得把 page 转为线性地址才行(为什么?想想 MMU 是如何访问物理内存的),也就是说,我们需要为高端内存对应的 page 找一个线性空间,这个过程称为高端内存映射。
 假 设按照上述简单的地址映射关系,那么内核逻辑地址空间访问为0xc0000000 ~ 0xffffffff,那么对应的物理内存范围就为0×0 ~ 0×40000000,即只能访问1G物理内存。若机器中安装8G物理内存,那么内核就只能访问前1G物理内存,后面7G物理内存将会无法访问,因为内核 的地址空间已经全部映射到物理内存地址范围0×0 ~ 0×40000000。即使安装了8G物理内存,那么物理地址为0×40000001的内存,内核该怎么去访问呢?代码中必须要有内存逻辑地址 的,0xc0000000 ~ 0xffffffff的地址空间已经被用完了,所以无法访问物理地址0×40000000以后的内存。
显 然不能将内核地址空间0xc0000000 ~ 0xfffffff全部用来简单的地址映射。因此x86架构中将内核地址空间划分三部分:ZONE_DMA、ZONE_NORMAL和 ZONE_HIGHMEM。ZONE_HIGHMEM即为高端内存,这就是内存高端内存概念的由来。
在x86结构中,三种类型的区域(从3G开始计算)如下:
ZONE_DMA 内存开始的16MB
ZONE_NORMAL 16MB~896MB
ZONE_HIGHMEM 896MB ~ 结束(1G)

 高端内存是指物理地址大于 896M 的内存。对于这样的内存,无法在“内核直接映射空间”进行映射。
为什么?
因为“内核直接映射空间”最多只能从 3G 到 4G,只能直接映射 1G 物理内存,对于大于 1G 的物理内存,无能为力。
高端内存映射有三种方式:
1、映射到“内核动态映射空间”
这种方式很简单,因为通过 vmalloc() ,在“内核动态映射空间”申请内存的时候,就可能从高端内存获得页面(参看 vmalloc 的实现),因此说高端内存有可能映射到“内核动态映射空间” 中。
2、永久内核映射
如果是通过 alloc_page() 获得了高端内存对应的 page,如何给它找个线性空间?
内核专门为此留出一块线性空间,从 PKMAP_BASE 到 FIXADDR_START ,用于映射高端内存。在 2.4 内核上,这个地址范围是 4G-8M 到 4G-4M 之间。这个空间起叫“内核永久映射空间”或者“永久内核映射空间”
这个空间和其它空间使用同样的页目录表,对于内核来说,就是 swapper_pg_dir,对普通进程来说,通过 CR3 寄存器指向。
通常情况下,这个空间是 4M 大小,因此仅仅需要一个页表即可,内核通过来 pkmap_page_table 寻找这个页表。
通过 kmap(), 可以把一个 page 映射到这个空间来
由于这个空间是 4M 大小,最多能同时映射 1024 个 page。因此,对于不使用的的 page,应该及时从这个空间释放掉(也除映射关就是解系),通过 kunmap() ,可以把一个 page 对应的线性地址从这个空间释放出来。
3、临时映射
内核在 FIXADDR_START 到 FIXADDR_TOP 之间保留了一些线性空间用于特殊需求。这个空间称为“固定映射空间”
在这个空间中,有一部分用于高端内存的临时映射。
这块空间具有如下特点:
1、 每个 CPU 占用一块空间
2、 在每个 CPU 占用的那块空间中,又分为多个小空间,每个小空间大小是 1 个 page,每个小空间用于一个目的,这些目的定义在 kmap_types.h 中的 km_type 中。
当要进行一次临时映射的时候,需要指定映射的目的,根据映射目的,可以找到对应的小空间,然后把这个空间的地址作为映射地址。这意味着一次临时映射会导致以前的映射被覆盖。
通过 kmap_atomic() 可实现临时映射。
下图简单简单表达如何对高端内存进行映射

 Linux内存线性地址空间大小为4GB,分为2个部分:用户空间部分(通常是3G)和内核空间部分(通常是1G)。在此我们主要关注内核地址空间部分。
内核通过内核页全局目录来管理所有的物理内存,由于线性地址前3G空间为用户使用,内核页全局目录前768项(刚好3G)除0、1两项外全部为0,后256项(1G)用来管理所有的物理内存。内核页全局目录在编译时静态地定义为swapper_pg_dir数组,该数组从物理内存地址0x101000处开始存放。

 由图可见,内核线性地址空间部分从PAGE_OFFSET(通常定义为3G)开始,为了将内核装入内存,从PAGE_OFFSET开始8M线性地址用来映射内核所在的物理内存地址(也可以说是内核所在虚拟地址是从PAGE_OFFSET开始的);接下来是mem_map数组,mem_map的起始线性地址与体系结构相关,比如对于UMA结构,由于从PAGE_OFFSET开始16M线性地址空间对应的16M物理地址空间是DMA区,mem_map数组通常开始于PAGE_OFFSET+16M的线性地址;从PAGE_OFFSET开始到VMALLOC_START – VMALLOC_OFFSET的线性地址空间直接映射到物理内存空间(一一对应影射,物理地址==线性地址-PAGE_OFFSET),这段区域的大小和机器实际拥有的物理内存大小有关,这儿VMALLOC_OFFSET在X86上为8M,主要用来防止越界错误;在内存比较小的系统上,余下的线性地址空间(还要再减去空白区即VMALLOC_OFFSET)被vmalloc()函数用来把不连续的物理地址空间映射到连续的线性地址空间上,在内存比较大的系统上,vmalloc()使用从VMALLOC_START到VMALLOC_END(也即PKMAP_BASE减去2页的空白页大小PAGE_SIZE(解释VMALLOC_END))的线性地址空间,此时余下的线性地址空间(还要再减去2页的空白区即VMALLOC_OFFSET)又可以分成2部分:第一部分从PKMAP_BASE到FIXADDR_START用来由kmap()函数来建立永久映射高端内存;第二部分,从FIXADDR_START到FIXADDR_TOP,这是一个固定大小的临时映射线性地址空间,(引用:Fixed virtual addresses are needed for subsystems that need to know the virtual address at compile time such as the APIC),在X86体系结构上,FIXADDR_TOP被静态定义为0xFFFFE000,此时这个固定大小空间结束于整个线性地址空间最后4K前面,该固定大小空间大小是在编译时计算出来并存储在__FIXADDR_SIZE变量中。
正是由于vmalloc()使用区、kmap()使用区及固定大小区(kmap_atomic()使用区)的存在才使ZONE_NORMAL区大小受到限制,由于内核在运行时需要这些函数,因此在线性地址空间中至少要VMALLOC_RESERVE大小的空间。VMALLOC_RESERVE的大小与体系结构相关,在X86上,VMALLOC_RESERVE定义为128M,这就是为什么ZONE_NORMAL大小通常是16M到896M的原因。


Linux下系统 I\/O 性能分析的套路
硬件层面,考虑升级至SSD替换老旧的HDD,利用RAID技术提高数据可靠性和性能。此外,合理设置磁盘隔离、预读策略,以及调整内核块设备参数,都是优化磁盘I\/O的重要手段。同时,定期检查并修复磁盘错误,确保数据的完整性。总的来说,Linux系统I\/O性能优化涉及多方面的策略,从文件系统选择、配置到硬件优化,每...

简要剖析Linux系统的进程管理机制
Linux是一个多用户多任务的操作系统。 多用户是指多个用户可以在同一时间使用同一个linux系统; 多任务是指在Linux下可以同时执行多个任务,更详细的说,linux采用了分时管理的方法,所有的任务都放在一个队列中,操作系统根据每个任务的优先级为每个任务分配合适的时间片,每个时间片很短,用户根本感觉不到是多个任务在运行...

解析Linux系统下的高端内存
在内存比较小的系统上,余下的线性地址空间(还要再减去空白区即VMALLOC_OFFSET)被vmalloc()函数用来把不连续的物理地址空间映射到连续的线性地址空间上,在内存比较大的系统上,vmalloc()使用从VMALLOC_START到VMALLOC_END(也即PKMAP_BASE减去2页的空白页大小PAGE_SIZE(解释VMALLOC_END))的线性地址空间,此...

如何分析linux下的几种目标文件
1.\/bin \/usr\/bin \/usr\/local\/bin 都是放置用户可执行二进制文件。2.\/boot 主要是放置liunx系统启动时用到的文件。2.\/dev 文件夹内主要是西东外设与存储有关的一些相关文件。3.\/etc 放置设置文件。例如用户帐号密码文件,各种服务文件。\/etc\/sysconfig\/目录包括了在LINUX下各种系统配置文件...

浅析Linux下进程的调度策略与优先级
在 Linux 中,nice 的值范围为-20 ~ +19,默认值为 0。nice 值越大,则优先级越低,因此相对较低 nice 值的进程可以获得更多的处理器时间。通过命令 ps -el 查看系统中的进程列表,其中 NI 列就是进程对应的 nice 值。使用 top 命令,看到的 NI 列也是进程的 nice 值。调整 ...

详解Linux系统下的hosts文件
hosts文件是Linux系统上一个负责ip地址与域名快速解析的文件,以ascii格式保存在\/etc\/目录下。hosts文件包含了ip地址与主机名之间的映射,还包括主机的别名。在没有域名解析服务器的情况下,系统上的所有网络程序都通过查询该文件来解析对应于某个主机名的ip地址,否则就需要使用dns服务程序来解决。通过可以...

Linux操作系统下用户和用户配置文件有哪些解析
对于用户账户管理我们经常用到的配置文件有:\/etc\/passwd,\/etc\/shadow,\/etc\/group。还有就是\/etc\/gshadow,不过这个我们一般情况下用不到。1、\/etc\/passwd account:passwd:UID:GID:GECOS:directory:shell account:用户名,是UID到名称的一种映射。passwd:密码,在你的配置文件中你会看到一个X,在以前...

深入解析Linux系统下的进程切换
[oracle@linuxidc ~]$ bg %1 [oracle@linuxidc ~]$ jobs -l [1]+ 4524Running ins.sh 2.4切换程序至前台 也可以用 fg %[number]指令把一个程序掉到前台运行 代码如下:[oracle@linuxidc ~]$ fg %1 .\/tcpserv01 2.5终止后台程序 也可以直接终止后台运行的程序,使用 kill 命令 代码如下...

Linux系统下常用性能分析工具top命令,怎么详解?
top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器。下面详细介绍它的使用方法。top - 01:06:48 up 1:22, 1 user, load average: 0.06, 0.60, 0.48 Tasks: 29 total, 1 running, 28 sleeping, 0 stopped, 0 zombie Cpu(s): 0....

如何查看linux系统下的各种日志文件 linux 系统日志的分析大全_百度知 ...
Linux系统所有的日志文件都在\/var\/log下,且必须有root权限才能察看。 日志文件其实是纯文本的文件,每一行就是一个消息。察看方式有很多。1. cat命令。日志文件总是很大的,因为从第一次启动Linux开始,消息都累积在日志文件中。如果这个文件不只一页,那么就会因为显示滚动得太快看不清文件的内容。2. 文本编辑器。

临桂县18944735682: linux如果高端内存很多,用户进程是优先使用高端内存还是低端内
弥峰痔疾: 我觉得这个问题有些歧义.好像32位系统才有高端内存的概念吧,64位系统还有高端内存吗?并且高端内存只是针对内核说的吧,用户进程好像也没有高端内存这个概念吧

临桂县18944735682: Linux系统下怎样内存申请应用?
弥峰痔疾: 1. 地址空间的管理 物理地址都是有内核管理的, node——>zone——>mem_map... 内核虚拟地址, 低端内存的虚拟地址与线性地址是一样的. 高端内存只有在映射了以...

临桂县18944735682: Linux系统有多大内存 -
弥峰痔疾: 你是指支持的内存上限么? 际上最大支持多大的内容跟操作系统的种类无关,而是跟操作系统是几位的还有CPU是几位的有关. DOS是16位的,所以DOS支持的最大内存是64MB(2的16次方字节等于64MB). 32位的Linux和32位的Windows(XP、Vista...)支持的最大内存是4GB,2的32次方字节=4GB. 64位的Linux和Windows支持的最大内存=16EB.

临桂县18944735682: linux系统中怎么打开支持8G的内核 -
弥峰痔疾: 根据你的内核版本 你安装的应该是RHEL4.5 也就是redhat enterprise linux 4 upgrade5, 这个发行版默认的内核最大支持4G内存 ,如果想使用8G内存,需要安装安装光盘中的kernel-PAE 内核 下面是RHEL4的kernel doc Red Hat Enterprise Linux...

临桂县18944735682: Linux操作系统中内存buffer和cache的区别 -
弥峰痔疾: cache 和 buffer的区别:Cache:高速缓存,是位于CPU与主内存间的一种容量较小但速度很高的存储器.由于CPU的速度远高于主内存,CPU直接从内存中存取数据要等待一定时间周期,Cache中保存着CPU刚用过或循环使用的一部分数据,...

临桂县18944735682: 怎么查看linux 系统的内存分布 -
弥峰痔疾: top命令能显示系统内存.目前常用的Linux下查看内容的专用工具是free命令.下面是对内存查看free命令输出内容的解释:total:总计物理内存的大小.used:已使用多大.free:可用有多少.Shared:多个进程共享的内存总额.Buffers/cached:磁盘缓存的大小.

临桂县18944735682: 如何查看Linux系统下的硬件信息 -
弥峰痔疾: 1,查看CPU信息:cat /proc/cpuinfo2,查看板卡信息:cat /proc/pci3,查看USB设备:cat /proc/bus/usb/devices4,查看PCI信息:lspci (相比cat /proc/pci更直观)5,查看内存信息:cat /proc/meminfo6,查看键盘和鼠标:cat /proc/bus/input/...

临桂县18944735682: Linux中的可用内存指的是什么 -
弥峰痔疾: Linux 内存机制 Linux支持虚拟内存(Virtual Mmemory),虚拟内存是指使用磁盘当作RAM的扩展,这样可用的内存的大小就相应地增大了.内核会将暂时不用的内存块的内容写到硬盘上,这样一来,这块内存就可用于其它目的.当需要用到原始的内容时,它们被重新读入内存.这些操作对用户来说是完全透明的;Linux下运行的程序只是看到有大量的内存可供使用而并没有注意到时不时它们的一部分是驻留在硬盘上的.当然,读写硬盘要比直接使用真实内存慢得多(要慢数千倍),所以程序就不会象一直在内存中运行的那样快.用作虚拟内存的硬盘部分被称为交换空间(Swap Space).

临桂县18944735682: linux 的虚拟内存是什么?怎么用?我可以把虚拟内存当内存用吗? -
弥峰痔疾: 通俗的说就是你内存条容量不够用了,系统就划出硬盘的一部分空间当做虚拟运存!但是运行速度慢!手动设置虚拟内存大小:①用右键点击桌面上的“我的电脑”图标,在出现的右键菜单中选“属性”选项打开“系统属性”窗口.在窗口中点击“高级”选项卡,出现高级设置的对话框 ②点击“性能”区域的“设置”按钮,在出现的“性能选项”窗口中选择“高级”选项卡,打开其对话框.③在该对话框中可看到关于虚拟内存的区域,点击“更改”按钮进入“虚拟内存”的设置窗口.选择一个有较大空闲容量的分区,勾选“自定义大小”前的复选框,将具体数值填入“初始大小”、“最大值”栏中,而后依次点击“设置→确定”按钮即可,最后重新启动计算机使虚拟内存设置生效

临桂县18944735682: Linux 系统怎么看内存和CPU占用情况? -
弥峰痔疾: Linux下查看内存与cpu的命令查看内存的命令: free 查看内存详细信息可以用 cat /proc/meminfo查看cpu使用情况可以用:ps -加参数 还可以用 top 查看cpu型号信息可以用 cat /proc/cpuinfo远程桌面可以用 Xmanger 来链接..但首先你需要在linux上做相关配置才行.想了解更多linux技术,请关注《linux就该这么学》官方网站.

你可能想看的相关专题

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网