linux 启动过程临时页表到底映射了多大内存
2012-08-13 16:14
555 查看
从 linux-2.4内核开始,在建立临时页表的时候,一般的教科书都说是映射了8M的物理内存,但是为什么是映射8M呢?当时网上有资料说,8M足够了,但为什么就足够了,一直没有彻底搞清楚,今天又重新分析这部分的代码(linux-2.6.24)。 先看下面内存布局图:
文章出处:飞诺网(www.diybl.com):http://www.diybl.com/course/6_system/linux/linuxjq/20120314/567015.html
在建立临时页表时到底映射多大的内存取决于以下几个方面:
(1)保护模式下内核的尺寸: 毫无疑问内核代码必须被映射
(2)临时页表所占的空间尺寸: 假设临时页表映射整个4G的线性地址空间,那么:
页面个数 = 4G/4k = 1M个页面
每个页面对应一个页表项,占4个字节,那么总共占有4M的空间
(3)bootmem allocator是用来在真正的页表建立好之前用于内存管理的,他用一个位图表来管理整个内存,
每一bit代表一个页框,假设有4G的物理内存,那么1M个页面共占有空间 = 1M/8 = 128K。
(4)由于对齐占有的空间(可以忽略,感觉k的数量级吧)
综合上述几个方面,需要映射的物理内存大约等于:
保护模式内核尺寸 + 临时页表占用空间尺寸 + bootmem allocator位图表尺寸 =
现在内核大约4M 最大4M 128K = 8M + 128K
在linux内核的head_32.S中下面代码:
movl $(pg0 - __PAGE_OFFSET), %edi
movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
movl $0x007, %eax /* 0x007 = PRESENT+RW+USER */
10:
leal 0x007(%edi),%ecx /* Create PDE entry */
movl %ecx,(%edx) /* Store identity PDE entry */
movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */
addl $4,%edx
movl $1024, %ecx
11:
stosl
addl $0x1000,%eax
loop 11b
/* End condition: we must map up to and including INIT_MAP_BEYOND_END */
/* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp
cmpl %ebp,%eax
jb 10b
movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
红字部分与映射内存有关:
INIT_MAP_BEYOND_END =
BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
= 128K + (4K + 4 )*4K
= 128K + 4M + 4K
所以是映射了8M物理内存, 即10:之后的代码执行了两次,这完全满足前面分析的需要映射的物理内存的大小。
可以从内核代码中的注释中得到验证:
/*
* paging_init() sets up the page tables - note that the first 8MB are
* already mapped by head.S.
*
* This routines also unmaps the page at virtual kernel address 0, so
* that we can trap those pesky NULL-reference errors in the kernel.
*/
这里还提到了:把虚拟地址=0开始的第一个页的映射解除,主要是为了跟踪对NULL指针引用的错误。
From:http://fosbin.blog.163.com/blog/static/18274600720113302469881/
文章出处:飞诺网(www.diybl.com):http://www.diybl.com/course/6_system/linux/linuxjq/20120314/567015.html
文章出处:飞诺网(www.diybl.com):http://www.diybl.com/course/6_system/linux/linuxjq/20120314/567015.html
在建立临时页表时到底映射多大的内存取决于以下几个方面:
(1)保护模式下内核的尺寸: 毫无疑问内核代码必须被映射
(2)临时页表所占的空间尺寸: 假设临时页表映射整个4G的线性地址空间,那么:
页面个数 = 4G/4k = 1M个页面
每个页面对应一个页表项,占4个字节,那么总共占有4M的空间
(3)bootmem allocator是用来在真正的页表建立好之前用于内存管理的,他用一个位图表来管理整个内存,
每一bit代表一个页框,假设有4G的物理内存,那么1M个页面共占有空间 = 1M/8 = 128K。
(4)由于对齐占有的空间(可以忽略,感觉k的数量级吧)
综合上述几个方面,需要映射的物理内存大约等于:
保护模式内核尺寸 + 临时页表占用空间尺寸 + bootmem allocator位图表尺寸 =
现在内核大约4M 最大4M 128K = 8M + 128K
在linux内核的head_32.S中下面代码:
movl $(pg0 - __PAGE_OFFSET), %edi
movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
movl $0x007, %eax /* 0x007 = PRESENT+RW+USER */
10:
leal 0x007(%edi),%ecx /* Create PDE entry */
movl %ecx,(%edx) /* Store identity PDE entry */
movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */
addl $4,%edx
movl $1024, %ecx
11:
stosl
addl $0x1000,%eax
loop 11b
/* End condition: we must map up to and including INIT_MAP_BEYOND_END */
/* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp
cmpl %ebp,%eax
jb 10b
movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
红字部分与映射内存有关:
INIT_MAP_BEYOND_END =
BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
= 128K + (4K + 4 )*4K
= 128K + 4M + 4K
所以是映射了8M物理内存, 即10:之后的代码执行了两次,这完全满足前面分析的需要映射的物理内存的大小。
可以从内核代码中的注释中得到验证:
/*
* paging_init() sets up the page tables - note that the first 8MB are
* already mapped by head.S.
*
* This routines also unmaps the page at virtual kernel address 0, so
* that we can trap those pesky NULL-reference errors in the kernel.
*/
这里还提到了:把虚拟地址=0开始的第一个页的映射解除,主要是为了跟踪对NULL指针引用的错误。
From:http://fosbin.blog.163.com/blog/static/18274600720113302469881/
文章出处:飞诺网(www.diybl.com):http://www.diybl.com/course/6_system/linux/linuxjq/20120314/567015.html
相关文章推荐
- linux 启动过程临时页表到底映射了多大内存?
- linux 启动过程临时页表到底映射了多大内存?
- 进程所用内存(包括页表、vma、映射内存)的释放过程 (基于linux2.6.11.12)
- linux非解压代码的启动过程分析 unicore head.S vmlinux解压后的代码运行 临时MMU的建立
- linux的临时页表映射问题
- ARM-Linux启动过程的空间映射之一
- linux的临时页表映射问题
- ARM Linux 内核启动总结 之 创建临时页表
- Linux内存管理 (2)页表的映射过程
- 从PC机、嵌入式linux、以及android系统的启动过程来总结uboot到底是干嘛的
- 从PC机、嵌入式linux、以及android系统的启动过程来总结uboot到底是干嘛的
- arm-linux启动过程中的内存布局
- [linux内存]系统启动过程中的内存管理
- linux-3.2.36内核启动3-setup_arch中的内存初始化2(arm平台 分析建立页表)
- linux-3.2.36内核启动3-setup_arch中的内存初始化2(arm平台 分析建立页表)
- linux 高端内存页框管理:永久内核映射、临时内核映射以及非连续内存分配
- ARM架构内核启动分析-head.S(1.3、stext分析之内存临时页表建立)
- [linux内存]系统启动过程中的内存管理
- linux arm的高端内存映射(2) 永久映射和临时映射
- Linux启动过程之内核挂载内存文件系统和真正根文件系统原因及过程分析