一. 前言
__create_page_tables是内核用于创建初始的页表。
二. __create_page_tables分析
__create_page_tables代码如下:
__create_page_tables:
pgtbl r4 @ page table address
/*
* Clear the 16K level 1 swapper page table
*/
mov r0, r4
mov r3, #0
add r6, r0, #0x4000
1: str r3, [r0], #4
str r3, [r0], #4
str r3, [r0], #4
str r3, [r0], #4
teq r0, r6
bne 1b
ldr r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mm_mmuflags
/*
* Create identity mapping for first MB of kernel to
* cater for the MMU enable. This identity mapping
* will be removed by paging_init(). We use our current program
* counter to determine corresponding section base address.
*/
mov r6, pc, lsr #20 @ start of kernel section
orr r3, r7, r6, lsl #20 @ flags + kernel base
str r3, [r4, r6, lsl #2] @ identity mapping
/*
* Now setup the pagetables for our kernel direct
* mapped region.
*/
add r0, r4, #(KERNEL_START & 0xff000000) >> 18
str r3, [r0, #(KERNEL_START & 0x00f00000) >> 18]!
ldr r6, =(KERNEL_END - 1)
add r0, r0, #4
add r6, r4, r6, lsr #18
1: cmp r0, r6
add r3, r3, #1 << 20
strls r3, [r0], #4
bls 1b
/*
* Then map first 1MB of ram in case it contains our boot params.
*/
add r0, r4, #PAGE_OFFSET >> 18
orr r6, r7, #(PHYS_OFFSET & 0xff000000)
.if (PHYS_OFFSET & 0x00f00000)
orr r6, r6, #(PHYS_OFFSET & 0x00f00000)
.endif
str r6, [r0]
mov pc, lr
pgtbl r4 :
pgtbl指令是一个宏,如下:
.macro pgtbl, rd
ldr \rd, =(KERNEL_RAM_PADDR - 0x4000)
.endm
KERNEL_RAM_PADDR是一个宏,如下:
#define KERNEL_RAM_PADDR (PHYS_OFFSET + TEXT_OFFSET)
PHYS_OFFSET定义在include/asm/arch/memory.h文件中,其中asm是asm-arm的软链接,arch是arch-s3c2410的软链接,所以PHYS_OFFSET是定义在include/asm-arm/arch-s3c2410/memory.h文件中。
&

__create_page_tables函数用于创建Linux内核的初始页表。它首先清除16K的交换页表,然后创建身份映射,使物理地址与虚拟地址一致,以便MMU启用。之后设置内核直接映射区域的页表,并映射一部分RAM以包含引导参数。
最低0.47元/天 解锁文章
1712

被折叠的 条评论
为什么被折叠?



