内核初始化映射时为什么要多映射”MAPPING_BEYOND_END“ ?
为什么要映射到_end + MAPPING_BEYOND_END 呢?映射到 _end不就就足矣了吗?
linux-3.6.x/arch/x86/kernel/head_32.S:
...
/*
* End condition: we must map up to the end + MAPPING_BEYOND_END.
*/
movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp
cmpl %ebp,%eax
jb 10b
...
根据 linux-3.6.x/arch/x86/kernel/vmlinux.lds.S:
SECTIONS
{
...
. = ALIGN(PAGE_SIZE);
.brk : AT(ADDR(.brk) - LOAD_OFFSET) {
__brk_base = .;
. += 64 * 1024; /* 64k alignment slop space */
*(.brk_reservation) /* areas brk users have reserved */
__brk_limit = .;
}
_end = .;
...
}
其实,在 __brk_base之后,_end之前,也就是 brk 段中,已经有足够的空间保存 page tables 了,因为根据 linux-3.6.x/arch/x86/kernel/head_32.S 中的定义:
MAPPING_BEYOND_END = PAGE_TABLE_SIZE(LOWMEM_PAGES) << PAGE_SHIFT
KERNEL_PAGES = LOWMEM_PAGES
INIT_MAP_SIZE = PAGE_TABLE_SIZE(KERNEL_PAGES) * PAGE_SIZE
RESERVE_BRK(pagetables, INIT_MAP_SIZE)
显然:
1 INIT_MAP_SIZE == MAPPING_BEYOND_END;
2 RESERVE_BRK(pagetables, INIT_MAP_SIZE) 在brk段中,告诉链接器分配了1M的空间,所以足够容纳映射内核的page tables。
所以,为什么还要映射到_end + MAPPING_BEYOND_END 呢?映射到 _end不就就足矣了吗?
UP! 希望有高手来回答啊。 up:mrgreen: 同问~~~ _end这部份不在MAPPING_BEYOND_END范围内么?:dizzy: . = ALIGN(PAGE_SIZE);
.brk : AT(ADDR(.brk) - LOAD_OFFSET) {
__brk_base = .;
. += 64 * 1024; /* 64k alignment slop space */
*(.brk_reservation) /* areas brk users have reserved */
__brk_limit = .;
brk中存放页表,但是一共64k大小,最大只支持64m空间。
但是LOW_MEM 通常为1G, 则需要1m的页表空间。所以增加了到MAPPING_BEYOND_END
页:
[1]