linux 直接映射 页表大小,linux 启动过程临时页表到底映射了多大内存?
從linux-2.4內(nèi)核開始,在建立臨時頁表的時候,一般的教科書都說是映射了8M的物理內(nèi)存,但是為什么是映射8M呢?當(dāng)時網(wǎng)上有資料說,8M足夠了,但為什么就足夠了,一直沒有徹底搞清楚,今天又重新分析這部分的代碼(linux-2.6.24)。 先看下面內(nèi)存布局圖:
在建立臨時頁表時到底映射多大的內(nèi)存取決于以下幾個方面:
(1)保護模式下內(nèi)核的尺寸: 毫無疑問內(nèi)核代碼必須被映射
(2)臨時頁表所占的空間尺寸: 假設(shè)臨時頁表映射整個4G的線性地址空間,那么:
頁面?zhèn)€數(shù) = 4G/4k = 1M個頁面
每個頁面對應(yīng)一個頁表項,占4個字節(jié),那么總共占有4M的空間
(3)bootmem allocator是用來在真正的頁表建立好之前用于內(nèi)存管理的,他用一個位圖表來管理整個內(nèi)存,
每一bit代表一個頁框,假設(shè)有4G的物理內(nèi)存,那么1M個頁面共占有空間 = 1M/8 = 128K。
(4)由于對齊占有的空間(可以忽略,感覺k的數(shù)量級吧)
綜合上述幾個方面,需要映射的物理內(nèi)存大約等于:
保護模式內(nèi)核尺寸 + 臨時頁表占用空間尺寸 + bootmem allocator位圖表尺寸 =
現(xiàn)在內(nèi)核大約4M??????????最大4M???????????????? 128K?????????????? = 8M + 128K
在linux內(nèi)核的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)
紅字部分與映射內(nèi)存有關(guān):
INIT_MAP_BEYOND_END =
BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
= 128K??????????? +?(4K????????????? +???? 4?????????)*4K
= 128K????????????+ 16M + 4K
所以是映射了8M物理內(nèi)存,?即10:之后的代碼執(zhí)行了兩次,這完全滿足前面分析的需要映射的物理內(nèi)存的大小。
總結(jié)
以上是生活随笔為你收集整理的linux 直接映射 页表大小,linux 启动过程临时页表到底映射了多大内存?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ug10许可证错误一8_面对排污许可证后
- 下一篇: 为什么6lowpan 要有四个地址_大型