从linux-2.4内核开始,在建立临时页表的时候,一般的教科书都说是映射了8M的物理内存,但是为什么是映射8M呢?当时网上有资料说,8M足够了,但为什么就足够了,一直没有彻底搞清楚,今天又重新分析这部分的代码(linux-2.6.24)。 先看下面内存布局图:
在建立临时页表时到底映射多大的内存取决于以下几个方面:
(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指针引用的错误。
上面是我进来看代码的一些心得,可能考虑不对,希望大家指教,相互交流。
分享到:
相关推荐
A9的MMU页表是由linux管理和创建的,ARM11运行的是rtthreaed,MMU页表是在系统启动前预先创建好的。ARM11属于ARMv6架构,其MMU需要两级页表来映射物理地址,第一级页表为段映射,一个页表条目表示1M空间;第二级页表...
对linux内存页表创建的详细讲解,和本博客前面文章紧密联系,讲解了物理内存、硬件IO、中断是如何映射的,什么是内存,内存映射是怎么一回事,另有例子演示,适合正确理解概念的文章
Linux下使用c语言实现的内存管理模拟器 假设有台计算机物理内存大小为4MB,每个内存页大小为4k。采用分页机制,使用二级页表,第一级为页目录,共有1024项,每个页目录项指向一个页表,每个页表项指向一个实际的物理...
Linux虚拟内存的实现需要6种机制的支持:地址映射机制、内存分配回收机制、缓存和刷新机制、请求页机制、交换机制和内存共享机制。 在Linux中,虚拟内存管理是通过地址映射机制把用户程序的逻辑地址映射到物理地址...
虚拟内存与物理内存区别,内核对页表的设置,实例分析映射机制,有源码分析
Linux 内存管理导读-三级页表-伙伴系统
虚拟内存技术是现代操作系统中的一个关键技术,它克服了旧有的内存管理的限制,允许系统运行比物理内存大的应用程序,同时也允许把暂时不用的页交换到磁盘,从而得到更多的可用内存。本文将深入剖析 Linux 内核的...
MMU是通过页表来查询虚拟地址与物理地址的映射关系。有时候,应用层需要直接访问物理地址,这时应用层就需要调用应用层mmap接口继而调用驱动层的mmap接口将希望的物理地址映射成用户态能访问的虚拟地址。由于操作...
目录:页表管理 内核页表 物理内存 高端内存 地址映射 虚拟内存 地址空间 高速缓存 页框回收 交换机制 缺页异常 共享内存 文件映射 程序执行
在嵌入式Linux系统中,虚拟地址空间映射是指将物理地址空间映射到虚拟地址空间的过程,这个过程需要硬件和软件的支持。本文将从硬件和软件的角度分析虚拟地址空间映射的基本原理,并讨论在805plus微处理器平台上虚拟...
Linux下的内存映射函数mmap详解及示例代码.pdf 本文档将详细介绍Linux下的内存映射函数mmap,包括其概念、实现机制、示例代码等方面的内容。 mmap概念 mmap是Linux操作系统中的一种内存映射机制,可以将文件映射...
1.4 Linux内存布局 21 1.5 内核空间和用户空间 23 1.5.1 初始化临时内核页表 24 1.5.2 永久内核页表的初始化 32 1.5.3 第一次进入用户空间 41 1.5.4 内核映射机制实例 44 1.6 固定映射的线性地址 48 1.7 高端内存...
代码页表代码代码页表代码代码页表代码代码页表代码
"Linux对x86系统4G以上大内存的寻址和管理" Linux操作系统在x86系统上对4G以上大内存的寻址和管理是非常重要的。由于x86系统的地址空间是32位的,因此它只能寻址最大4GB的内存空间。但是,随着应用的不断发展,对...
ARM内存页表的硬件原理---原理和硬件实现
"浅析 Linux 内存架构模型" 本文将从 Linux 内存架构模型的角度,讨论 Linux 操作系统中内存管理的机制和实现方式。操作系统的内存管理是指操作系统根据程序的请求,把内存段分配给它们,当程序不再需要内存时释放...
与直接映射的物理内存末端、高端内存的始端所对应...分别叫做内核映射、临时内核映射以及非连续内存分配。在这里,只总结前两种技术,第三种技术将在后面总结。 建立内核映射可能阻塞当前进程;这发生在空闲页表项不
虚拟内存是指通过硬件和软件的结合,模拟出一个大的内存空间,从而使得程序可以使用更多的内存空间。虚拟内存的实现是通过MMU(Memory Management Unit)来实现的。MMU可以根据某种规则“折射”地址,使得程序可以...
页表代码页表代码页表代码页表代码代码页表代码