分享
 
 
 

Linux内存观点(1)

王朝system·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

目录

每个子系统都给其它子系统提供了接口,你甚至不需要深入每个子系统的细节,仅仅搞清楚子系统的接口就可以进行内核级的程序开发了。

内核地址空间的布局

初始化和固定映射

Boot mem

高端内存

VM 和 vmalloc

物理内存管理

slab 管理

page cache

swap cache 和 swap file

虚存管理(vma)

swap out

swap in

mm fault handle

mmap

我的理解是这样:

1.可以分成两个部分讨论:

内核空间的内存管理

用户空间的内存管理

2

对于用户空间管理,正如你说的,核心是映射,映射操作由cpu自动完成的,但是如何映射是linux定的。

正如数学中定义的,关于一个映射有3个要素;

定义域

|

| 映射规则

V

值域

因此要完成一个映射的定义,需要

在用户空间分配一个定义域(vm_area_struct的分配等操作);

在“物理地址”上分配一个值域(内核空间的分配----页面级分配器);

定义映射(页表操作);

3

对于其它操作,也可以从这个3要素来考虑

比如交换:

就是把一部分值域“搬迁”到“外设”中,映射原象一端固定住,“象”一端也跟着移到“外设”中

交换中的缺页中断

不过是把部分“值域”再搬回到内存中来

内核地址空间的布局

我们计算一下, 如果4G的空间都有映射那么页表占去了多少空间:一个页表4K(一个pte代表4K), pgd 中有1024 项(每一项代表4K空间 ),那么就需要 4K*(1024+1) = 4M+4k 的空间.

内核的pgd 是 swapper_pg_dir,静态分配, 系统初始化时把前768项空出来. 也就是只初始化了3G以上的空间, 编译时内核的虚拟地址从3G开始.这样内核通过这个页目录寻址.初始化时映射的这一部分空间称为预映射.预映射把所有物理内存映射到内核, 同时p--v 转换非常简单,使得内核无须维护自己的虚拟空间,并且能够方便的存取用户空间.

众所周知的,__pa 宏基于这样的预映射.内核拥有独立的pgd, 也就是说内核的虚拟空间是独立于其他程序的.这样以来和其他进程完全没有联系.那么我们所说的用户在低3G,内核在最高1G,为所有用户共享, 又是怎么回事呢? 其实很简单, 进程页表前768项指向进程的用户空间,如果进程要访问内核空间,如系统调用,则进程的页目录中768项后的项指向swapper_pg_dir的768项后的项。然后通过swapper_pg_dir来访问内核空间。一旦用户陷入内核,就使用内核的swapper_pg_dir(不是直接使用而是保持用户pgd 768后面的和 swapper_pg_dir 一致,共享内核页表{因为到内核不切换pgd?}看看do_page_fault ^_^ 的相关处理)进行寻址!

linux 把他的1G线性空间分成了几个部分:

1) Linux将整个4G线性地址空间分为用户空间和内核空间两部分,而内核地址空间又被划分为"物理内存区", "虚拟内存分配区", "高端页面映射区","专用页面映射区", "系统保留映射区"几个区域.

2) 在标准配置下, 物理区最大长度为896M,系统的物理内存被顺序映射在物理区中,在支持扩展页长(PSE)和全局页面(PGE)的机器上,物理区使用4M页面并作为全局页面来处理(呵呵,没有白白计算). 当系统物理内存大于896M时,超过物理区的那部分内存

称为高端内存,低端内存和高端内存用highmem_start_page变量来定界,内核在存取高端内存时必须将它们映射到"高端页面映射区".

3) Linux保留内核空间最顶部128K区域作为保留区,紧接保留区以下的一段区域为专用页面映射区,它的总尺寸和每一页的用途由fixed_address枚举结构在编绎时预定义,用__fix_to_virt(index)可获取专用区内预定义页面的逻辑地址.在专用页面区内为每个CPU预定义了一张高端内存映射页,用于在中断处理中高端页面的映射操作.

4) 距离内核空间顶部32M, 长度为4M的一段区域为高端内存映射区,它正好占用1个页帧表所表示的物理内存总量, 它可以缓冲1024个高端页面的映射.在物理区和高端映射区之间为虚存内存分配区, 用于vmalloc()函数,它的前部与物理区有8M隔离带, 后部与高端映射区有8K(2.4为4k?)的隔离带.

5) 当系统物理内存超过4G时,必须使用CPU的扩展分页(PAE)模式所提供的64位页目录项才能存取到4G以上的物理内.在PAE模式下, 线性地址到物理地址的转换使用3级页表,第1级页目录由线性地址的最高2位索引, 每一目录项对应1G的寻址空间,第2级页目录项以9位索引, 每一目录项对应2M的寻址空间, 第3级页目录项以9位索引,每一目录项对应4K的页帧. 除了页目录项所描述的物理地址扩展为36位外,64位和32位页目录项结构没有什么区别. 在PAE模式下,包含PSE位的中级页目录项所对应的页面从4M减少为2M.

内核的1G线性空间(灰色代表已经建立映射,只有物理区为完全映射)

物理区 8M隔离 vmalloc 区 8K隔离 4M的高端映射区 固定映射区 128K

保留区

||

V

和物理区对应的物理内存 被映射到高端映射区的物理内存 其他高端物理内存

下面从代码中寻找一下根据(上面的分析好像不是2.4.0, ^_^):

下面的代码摘自 include/asm-386/pgtable.h

/* Just any arbitrary offset to the start of the vmalloc VM area: the

* current 8MB value just means that there will be a 8MB "hole" after the

* physical memory until the kernel virtual memory starts. That means that

* any out-of-bounds memory accesses will hopefully be caught.

* The vmalloc() routines leaves a hole of 4kB between each vmalloced

* area for the same reason. ;)

*/

#define VMALLOC_OFFSET (8*1024*1024)

#define VMALLOC_START (((unsigned long) high_memory + 2*VMALLOC_OFFSET-1) & ~(VMALLOC_OFFSET-1))

#define VMALLOC_VMADDR(x) ((unsigned long)(x))

#define VMALLOC_END (FIXADDR_START)

可以看出物理区 和 VM 区中间的那个空洞.而vmalloc区结束和固定映射区开始也应该是4k的空洞啊!

fixmap.h

fixed_addresses 看看这个结构就知道,高端内存映射区属于固定内存区的一种,并且每个cup一个.

enum fixed_addresses {

#ifdef CONFIG_X86_LOCAL_APIC

FIX_APIC_BASE, /* local (CPU) APIC) -- required for SMP or not */

#endif

#ifdef CONFIG_X86_IO_APIC

FIX_IO_APIC_BASE_0,

FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1,

#endif

#ifdef CONFIG_X86_VISWS_APIC

FIX_CO_CPU, /* Cobalt timer */

FIX_CO_APIC, /* Cobalt APIC Redirection Table */

FIX_LI_PCIA, /* Lithium PCI Bridge A */

FIX_LI_PCIB, /* Lithium PCI Bridge B */

#endif

#ifdef CONFIG_HIGHMEM

FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */

FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,

#endif

__end_of_fixed_addresses

};

这个文件的以下定义也非常有意义:

/*

* used by vmalloc.c.

*

* Leave one empty page between vmalloc'ed areas and

* the start of the fixmap, and leave one page empty

* at the top of mem..

*/

#define FIXADDR_TOP (0xffffe000UL)

#define FIXADDR_SIZE (__end_of_fixed_addresses need_resched = 1;

cpu_idle();

}

arch/i386/kernel/setup.c

void __init setup_arch(char **cmdline_p)

{

unsigned long bootmap_size;

unsigned long start_pfn, max_pfn, max_low_pfn;

int i;

.......

setup_memory_region(); //有的系统 e820 不太好使,可能伪造一个 bios e820

.......

init_mm.start_code = (unsigned long) &_text; //初始化 init_mm

......

code_resource.start = virt_to_bus(&_text);

......

data_resource.start = virt_to_bus(&_etext);

......

#define PFN_UP(x) (((x) + PAGE_SIZE-1) PAGE_SHIFT)

#define PFN_DOWN(x) ((x) PAGE_SHIFT)

#define PFN_PHYS(x) ((x) MAXMEM_PFN) {

highstart_pfn = MAXMEM_PFN;

printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",

pages_to_mb(highend_pfn - highstart_pfn));

}

#endif

/*

* Initialize the boot-time allocator (with low memory only):

*/

bootmap_size = init_bootmem(start_pfn, max_low_pfn);

/*

* 把所有可用的低端内存注册于 bootmem allocator .

*/

.......

/*

* Reserve the bootmem bitmap itself as well. We do this in two

* steps (first step was init_bootmem()) because this catches

* the (very unlikely) case of us accidentally initializing the

* bootmem allocator with an invalid RAM area.

*/

reserve_bootmem(HIGH_MEMORY, (PFN_PHYS(start_pfn) +

bootmap_size + PAGE_SIZE-1) - (HIGH_MEMORY));

/*

* reserve physical page 0 - it's a special BIOS page on many boxes,

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有