linux-2.6.14.1/arch/arm/kernel/head.S
.type __create_page_tables, %function
__create_page_tables:
ldr r5, [r8, #MACHINFO_PHYSRAM] @ physram
/*
#define S3C2410_CS6 (0x30000000) //arch-s3c2410/map.h
#define S3C2410_SDRAM_PA (S3C2410_CS6)
r5 为系统物理内存基地址
r8 = machine info (struct machine_desc的基地址)
#define MACHINFO_PHYSRAM 4
*/
pgtbl r4, r5 @ page table address
/*
.macro pgtbl, rd, phys
adr /rd, stext
sub /rd, /rd, #0x4000
.endm
*/
//stext表示内核解压缩后在ram中的起始位置(即0x30008000)
//r4寄存器中保存着页表基址在物理内存中的起始地址(0x30004000)
//ram接在片选6上,其起始地址为0x30000000,即页表基址在片选6的第16K 位置处
/*
* Clear the 16K level 1 swapper page table
*/
mov r0, r4
mov r3, #0
add r6, r0, #0x4000 //页表在物理内存中的未端地址,即0x30004000 + 16K
1: str r3, [r0], #4
str r3, [r0], #4
str r3, [r0], #4
str r3, [r0], #4
teq r0, r6 //循环将0x30004000--0x30008000间的16K页表内容清零
bne 1b
ldr r7, [r10, #PROCINFO_MMUFLAGS] @ mmuflags
/*
#define PROCINFO_MMUFLAGS 8
r10 = procinfo (struct proc_info_list的基地址)
*/
/*
* 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
/*
r6 = 0x300 = 768
*/
orr r3, r7, r6, lsl #20 @ flags + kernel base
str r3, [r4, r6, lsl #2] @ identity mapping
/*
r4 + r6 * 4 = 0x30004000 + 0x300 * 4
即表示页表的第r6(768)表项【r4是页表在物理内存中的基地址】
r6 << 20为0x30008000即解压后的内核在物理内存中的首地址
所以页表的第768项所映射的物理内存地址为0x30008000
*/
/*
* Now setup the pagetables for our kernel direct
* mapped region. We round TEXTADDR down to the
* nearest megabyte boundary. It is assumed that
* the kernel fits within 4 contigous 1MB sections.
*/
add r0, r4, #(TEXTADDR &