Linux内存布局

简介: 在上一篇博文里,我们已经看到Linux如何有效地利用80x86的分段和分页硬件单元把逻辑地址转换为线性地址,在由线性地址转换到物理地址。那 么我们的应用程序如何使用这些逻辑地址,整个内存的地址布局又是怎样的?打一个比方,内存就像一座城市,而居住在这个城市里的市民就像是各个进程,一个市 民吃喝拉撒睡,当然就得用于“房子”、“车子”、“票子”等各种各样的资源。

在上一篇博文里,我们已经看到Linux如何有效地利用80x86的分段和分页硬件单元把逻辑地址转换为线性地址,在由线性地址转换到物理地址。那 么我们的应用程序如何使用这些逻辑地址,整个内存的地址布局又是怎样的?打一个比方,内存就像一座城市,而居住在这个城市里的市民就像是各个进程,一个市 民吃喝拉撒睡,当然就得用于“房子”、“车子”、“票子”等各种各样的资源。有些资源是固定的,如“房子”,我们称之为静态数据;有些资源是动态的,如 “车子”,我们称之为动态数据;有些资源是用来购买(产生)数据的,如“票子”,我们称之为代码。

现在,我们就来看看内存这座巨大的城市史如何布局的。在系统初始化阶段,内核首先在实模式下建立一个物理地址映射来指定哪些物理地址范围对内核可用而哪些不可用(主要是根据映射硬件设备I/O的共享内存,或者根据相应的页框含有的BIOS数据)。

内存的某些部分将永久地分配给BOIS或内核,用来存放BIOS信息、内核代码以及静态内核数据结构。所以内核将下列页框记为保留:
• 在不可用的物理地址范围内的页框,一般用来存放BIOS信息。
• 含有内核代码和已初始化的数据结构的页框。

标记为保留页框中的页,绝不能被动态分配或交换到磁盘上。

一般来说,Linux内核安装在RAM中从物理地址0x00100000开始的地方,也就是说,从第二个MB开始。所需页框总数依赖于内核的配置方案:典型的配置所得到的内核可以完全被安装在小于3MB的RAM中。

为什么内核没有安装在RAM第一个MB开始的地方?主要是为具体的PC体系结构所考虑。例如:
• 页框0由BIOS使用,存放加电自检(Power-On Self-Test,POST)期间检查到的硬件配置。因此,很多膝上型电脑的BIOS甚至在系统初始化后还将数据写到该页框。
• 物理地址从0x000a0000 到 0x000fffff的范围通常留给BIOS例程,并且映射ISA图形卡上的内部存储器。这个区域就是所有IBM兼容PC上从640KB到1MB之间著名的洞:物理地址存在但被保留,对应的页框不能由操作系统使用。
• 前1MB内的其他页框可能由特定计算机模型保留。例如,IBM 笔记本电脑把0x0a页框映射到0x9f页框。

在启动过程的早期阶段,内核询问BIOS并了解物理内存的大小,并调用machine_specific_memory_setup()函数建立物理地址映射。假设我们的内存是128MB,那么,第一个MB就给BIOS了。整个128MB的内存被物理映射成以下布局:
0x00000000   -   0x0009ffff     除第一个页框外的640K空间可用
0x000a0000   -   0x000effff     保留
0x000f0000   -   0x000fffff     保留给BIOS例程
0x00100000   -   0x07feffff     126.9MB可用空间
0x07ff0000   -   0x07ff2fff     ACPI data
0x07ff3000   -   0x07ffffff     ACPI NVS
0xffff0000   -   0xffffffff     保留
这 里简单介绍一下128MB内存的末尾,从0x07ff0000 到0x07ff2fff的物理地址范围中存有加电自测(POST)阶段由BIOS写入的系统硬件设备信息;在初始化阶段,内核把这些信息拷贝到一个合适的 内核数据结构中,然后认为这些页框是可用的。相反,从0x07ff3000到0x07ffffff的物理地址范围被映射到硬件设备的ROM芯片。从 0xffff0000开始的物理地址范围标记为保留,因为它由硬件映射到了BIOS的ROM芯片。注意BIOS也许并不提供一些物理地址范围的信息(在上 述图中,范围是0x000a0000到 0x000effff)。为安全可靠起见,Linux假定这样的范围是不可用的。

虽然,我们看到第一个MB里,BIOS并没有用完,但是为了避免把内核装入一组不连续的页框里,影响性能,Linux便跳过第1MB的RAM,之间从第2个MB开始加载。其实一般来说,对于两个MB,也就是512个页框,对初始化时的内核代码及一些静态数据,已经足够了。

内 核可能不会见到BIOS报告的所有物理内存:例如,如果未使用PAE支持来编译,即使有更大的物理内存可供使用,内核也只能寻址4GB大小的RAM。 setup_memory()函数在machine_specific_memory_setup()执行后被调用:它分析物理内存区域表并初始化一些变 量来描述内核的物理内存布局,这些变量如下表所示:

 

变量名称

说明

num_physpages

最高可用页框的页框号

totalram_pages

可用页框的总数量

min_low_pfn

RAM 中在内核映像后第一个可用页框的页框号

max_pfn

最后一个可用页框的页框号

max_low_pfn

被内核直接映射的最后一个页框的页框号(低地址内存)

totalhigh_pages

内核非直接映射的页框的总数(高地址内存)

highstart_pfn

内核非直接映射的第一个页框的页框号

highend_pfn

内核非直接映射的最后一个页框的页框号



下图显示Linux怎样填充前3MB的RAM。
内存布局
我 们看到图中可用的页框,是内存的其余部分,我们称为动态内存,这不仅是进程所需的宝贵资源,也是内核本身所需的宝贵资源。实际上,整个系统的性能取决于如 何有效地管理动态内存。因此,现在所有多任务操作系统都在尽力优化对动态内存的使用,也就是尽可能做到当需要是分配,不需要时释放。

后面的博文中,我们将重点讨论内核如何给自己分配动态内存。主要包括页框管理、高端内存映射、伙伴系统算法、slab分配器、内存池、非连续内存区管理。
相关文章
|
8月前
|
缓存 监控 Linux
Linux内存问题排查命令详解
Linux服务器卡顿?可能是内存问题。掌握free、vmstat、sar三大命令,快速排查内存使用情况。free查看实时内存,vmstat诊断系统整体性能瓶颈,sar实现长期监控,三者结合,高效定位并解决内存问题。
835 0
Linux内存问题排查命令详解
|
缓存 Linux
linux 手动释放内存
在 Linux 系统中,内存管理通常自动处理,但业务繁忙时缓存占用过多可能导致内存不足,影响性能。此时可在业务闲时手动释放内存。
877 17
|
监控 Linux
如何检查 Linux 内存使用量是否耗尽?这 5 个命令堪称绝了!
本文介绍了在Linux系统中检查内存使用情况的5个常用命令:`free`、`top`、`vmstat`、`pidstat` 和 `/proc/meminfo` 文件,帮助用户准确监控内存状态,确保系统稳定运行。
2722 6
|
缓存 Linux 数据安全/隐私保护
Linux环境下如何通过手动调用drop_caches命令释放内存
总的来说,记录住“drop_caches” 命令并理解其含义,可以让你在日常使用Linux的过程中更加娴熟和自如。
1899 23
|
监控 Linux Python
Linux系统资源管理:多角度查看内存使用情况。
要知道,透过内存管理的窗口,我们可以洞察到Linux系统运行的真实身姿,如同解剖学家透过微观镜,洞察生命的奥秘。记住,不要惧怕那些高深的命令和参数,他们只是你掌握系统"魔法棒"的钥匙,熟练掌握后,你就可以骄傲地说:Linux,我来了!
472 27
|
消息中间件 Linux
Linux中的System V通信标准--共享内存、消息队列以及信号量
希望本文能帮助您更好地理解和应用System V IPC机制,构建高效的Linux应用程序。
570 48
|
缓存 Java Linux
如何解决 Linux 系统中内存使用量耗尽的问题?
如何解决 Linux 系统中内存使用量耗尽的问题?
1444 59
如何在 Linux 系统中查看进程占用的内存?
如何在 Linux 系统中查看进程占用的内存?
3187 58
|
缓存 Linux
如何检查 Linux 内存使用量是否耗尽?
何检查 Linux 内存使用量是否耗尽?
944 58
|
缓存 NoSQL Linux
Linux系统内存使用优化技巧
交换空间(Swap)的优化 禁用 Swap sudo swapoff -a 作用:这个命令会禁用系统中所有的 Swap 空间。swapoff 命令用于关闭 Swap 空间,-a 参数表示关闭 /etc/fstab 文件中配置的所有 Swap 空间。 使用场景:在高性能应用场景下,比如数据库服务器或高性能计算服务器,禁用 Swap 可以减少磁盘 I/O,提高系统性能。
571 3