实用平台:i386
Linux内存线性地址空间大小为4GB,分为2个局部:用户空间局部(等闲是3G)和内核空间局部(等闲是1G)。在此我们重要关怀内核地址空间局部。
内核穿越内核页大局目录来管教所有的物理内存,由于线形地址前3G空间为用户利用,内核页大局目录前768项(刚好3G)除0、1两项外全副为0,后256项(1G)用来管教所有的物理内存。内核页大局目录在编译时静态地定义为swapper_pg_dir数组,该数组从物理内存地址0x101000处开始储藏。
由图可见,内核线形地址空间局部从PAGE_OFFSET(等闲定义为3G)开始,为了将内核装入内存,从PAGE_OFFSET开始8M线形地址用来照射内核所在的物理内存地址;接下来是mem_map数组,mem_map的起始线形地址与系统构造相干,例如对于UMA构造,由于从PAGE_SIZE开始16M线形地址空间对应的16M物理地址空间是DMA区,mem_map数组等闲开始于PAGE_SIZE+16M的线形地址;从PAGE_SIZE开始到VMALLOC_START
–
VMALLOC_OFFSET的线形地址空间直接照射到物理内存空间(一一对应影射,物理地址=线形地址-PAGE_OFFSET),这段区域的大小和机器切实具有的物理内存大小有关,这儿VMALLOC_OFFSET在x86上为8M,重要用来遏止越界讹谬;在内存比拟小的系统上,余下的线形地址空间(还要再扣除空白区即VMALLOC_OFFSET)被vmalloc()函数用来把不继续的物理地址空间照射到继续的线形地址空间上,在内存比拟大的系统上,vmalloc()利用从VMALLOC_START到VMALLOC_END(也即PKMAP_BASE扣除2页的空白页大小PAGE_SIZE)的线形地址空间,此刻余下的线形地址空间(还要再扣除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变量中。真空断路器o:p>
正是由于vmalloc()利用区、kmap()利用区及安宁大小区的存在才使ZONE_NORMAL区大小受到局限,由于内核在运行时必需这些函数,因而在线形地址空间中起码要VMALLOC_RESERVE大小的空间。VMALLOC_RESERVE的大小与系统构造相干,在x86上,VMALLOC_RESERVE定义为128M,这即便为什么我们看到ZONE_NORMAL大小等闲是16M到896M的起因。
linux内核地址映射模型x86
CPU采用了段页式地址映射模型。进程代码中的地址为逻辑地址,经过段页式地址映射后,才真正访问物理内存。
段页式机制如下图。
linux内核地址空间划分
通常32位linux内核地址空间划分0~3G为用户空间,3~4G为内核空间。注意这里是32位内核地址空间划分,64位内核地址空间划分是不同的。
linux内核高端内存的由来
当内核模块代码或线程访问内存时,代码中的内存地址都为逻辑地址,而对应到真正的物理内存地址,需要地址一对一的映射,如逻辑地址0xc0000003对应的物理地址为0×3,0xc0000004对应的物理地址为0×4,…
…,逻辑地址与物理地址对应的关系为
物理地址
=
逻辑地址
0xC0000000
逻辑地址物理内存地址0xc00000000×00xc00000010×10xc00000020×20xc00000030×3…
…
0xe00000000×20000000……0xffffffff0×40000000
??
显然不能将内核地址空间0xc0000000
~
0xfffffff全部用来简单的地址映射。因此x86架构中将内核地址空间划分三部分:ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM。ZONE_HIGHMEM即为高端内存,这就是内存高端内存概念的由来。
在x86结构中,三种类型的区域如下:
ZONE_DMA
内存开始的16MB
ZONE_NORMAL
16MB~896MB
ZONE_HIGHMEM
896MB
~
结束
linux内核高端内存的理解
前面我们解释了高端内存的由来。
linux将内核地址空间划分为三部分ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM,高端内存HIGH_MEM地址空间范围为0xF8000000
~
0xFFFFFFFF(896MB~1024MB)。那么如内核是如何借助128MB高端内存地址空间是如何实现访问可以所有物理内存?
当内核想访问高于896MB物理地址内存时,从0xF8000000
~
0xFFFFFFFF地址空间范围内找一段相应大小空闲的逻辑地址空间,借用一会。借用这段逻辑地址空间,建立映射到想访问的那段物理内存(即填充内核PTE页面表),临时用一会,用完后归还。这样别人也可以借用这段地址空间访问其他物理内存,实现了使用有限的地址空间,访问所有所有物理内存。如下图。
例如内核想访问2G开始的一段大小为1MB的物理内存,即物理地址范围为0×80000000
~
0x800FFFFF。访问之前先找到一段1MB大小的空闲地址空间,假设找到的空闲地址空间为0xF8700000
~
0xF87FFFFF,用这1MB的逻辑地址空间映射到物理地址空间0×80000000
~
0x800FFFFF的内存。映射关系如下:
逻辑地址物理内存地址0xF87000000×800000000xF87000010×800000010xF87000020×80000002…
…0xF87FFFFF0x800FFFFF
当内核访问完0×80000000
~
0x800FFFFF物理内存后,就将0xF8700000
~
0xF87FFFFF内核线性空间释放。这样其他进程或代码也可以使用0xF8700000
~
0xF87FFFFF这段地址访问其他物理内存。
从上面的描述,我们可以知道高端内存的最基本思想:借一段地址空间,建立临时地址映射,用完后释放,达到这段地址空间可以循环使用,访问所有物理内存。
看到这里,不禁有人会问:万一有内核进程或模块一直占用某段逻辑地址空间不释放,怎么办?若真的出现的这种情况,则内核的高端内存地址空间越来越紧张,若都被占用不释放,则没有建立映射到物理内存都无法访问了。
计算机的存储空间问题相信大部分的管理员都有不同的处理方式。今天我们就一起来了解一下,在linux系统中,交换空间的具体使用情况是什么。希望通过对本文的阅读,大家对于linux系统有更多的了解,下面就开始今天的主要内容吧。
交换空间
交换空间是现代Linux系统中的二种内存类型。交换空间的主要功能是当全部的RAM被占用并且需要更多内存时,用磁盘空间代替RAM内存。
例如,假设你有一个8GBRAM的计算机。如果你启动的程序没有填满RAM,一切都好,不需要交换。假设你在处理电子表格,当添加更多的行时,你电子表格会增长,加上所有正在运行的程序,将会占用全部的RAM。如果这时没有可用的交换空间,你将不得不停止处理电子表格,直到关闭一些其他程序来释放一些RAM。
内核使用一个内存管理程序来检测近没有使用的内存块(内存页)。内存管理程序将这些相对不经常使用的内存页交换到硬盘上专门指定用于“分页”或交换的特殊分区。这会释放RAM,为输入电子表格更多数据腾出了空间。那些换出到硬盘的内存页面被内核的内存管理代码跟踪,如果需要,可以被分页回RAM。
Linux计算机中的内存总量是RAM+交换分区,交换分区被称为虚拟内存.
Linux交换分区类型
Linux提供了两种类型的交换空间。默认情况下,大多数Linux在安装时都会创建一个交换分区,但是也可以使用一个特殊配置的文件作为交换文件。电脑培训http://www.kmbdqn.cn/发现交换分区顾名思义就是一个标准磁盘分区,由mkswap命令指定交换空间。
如果没有可用磁盘空间来创建新的交换分区,或者卷组中没有空间为交换空间创建逻辑卷,则可以使用交换文件。这只是一个创建好并预分配指定大小的常规文件。然后运行mkswap命令将其配置为交换空间。除非绝对必要,否则我不建议使用文件来做交换空间。(LCTT译注:Ubuntu近来的版本采用了交换文件而非交换空间,所以我对于这种说法保留看法)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)