1 /* 2 * r1 = machine no, r2 = atags or dtb, 3 * r8 = phys_offset, r9 = cpuid, r10 = procinfo 4 */ 5 __create_page_tables: 6 pgtbl r4, r8 @ page table address 7 @\ 8 @====================================================== 9 @ .macro pgtbl, rd, phys 10 @ add \rd, \phys, #TEXT_OFFSET - PG_DIR_SIZE 11 @ @ TEXT_OFFSET:=$(textofs-y) (在arch/arm/Makefile定义,而又textofs-y:=0x00008000) 12 @ @ 所以 r4=0x40000000+0x00008000-0x4000=0x40004000 13 @ .endm 14 @====================================================== 15 /* 16 * Clear the swapper page table 17 */ 18 mov r0, r4 @ r0=页目录表头部的物理地址 (0x40004000) 19 mov r3, #0 @ r3=0 20 add r6, r0, #PG_DIR_SIZE @ r6=页目录表尾部的物理地址 (0x40008000) 21 1: str r3, [r0], #4 @ 把0x40004000~0x40008000的所有内容清零 22 str r3, [r0], #4 23 str r3, [r0], #4 24 str r3, [r0], #4 25 teq r0, r6 26 bne 1b 27 28 #ifdef CONFIG_ARM_LPAE 29 /* 30 * Build the PGD table (first level) to point to the PMD table. A PGD 31 * entry is 64-bit wide. 32 */ 33 mov r0, r4 34 add r3, r4, #0x1000 35 orr r3, r3, #3 36 mov r6, #4 37 mov r7, #1 << (55 - 32) 38 1: 39 #ifdef CONFIG_CPU_ENDIAN_BE8 40 str r7, [r0], #4 41 str r3, [r0], #4 42 #else 43 str r3, [r0], #4 44 str r7, [r0], #4 45 #endif 46 add r3, r3, #0x1000 47 subs r6, r6, #1 48 bne 1b 49 50 add r4, r4, #0x1000 51 #ifdef CONFIG_CPU_ENDIAN_BE8 52 add r4, r4, #4 53 #endif 54 #endif 55 56 ldr r7, [r10, #PROCINFO_MM_MMUFLAGS] @ r7=mm_mmuflags(参考struct proc_info_list中的__cpu_mm_mmu_flags,proc-*.S中填充的) 57 58 /* 59 * Create identity mapping to cater for __enable_mmu. 60 * This identity mapping will be removed by paging_init(). 61 */ 62 adr r0, __turn_mmu_on_loc @ r0=(phys)__turn_mmu_on_loc 63 ldmia r0, {r3, r5, r6} @ r3=(virt). r5=(virt)__turn_mmu_on r6=(virt)__turn_mmu_on_end(r5~r6是代码区) 64 sub r0, r0, r3 @ r0=r0-r3 (在下面两行中转换phys地址为virt地址的时候使用) 65 add r5, r5, r0 @ (phys)r5=(virt)r5+(offset)r0 66 add r6, r6, r0 @ (phys)r6=(virt)r6+(offset)r0 67 mov r5, r5, lsr #SECTION_SHIFT @ r5=r5>>20(ex: 0xc0008060>>20=0xc00) 68 mov r6, r6, lsr #SECTION_SHIFT @ r6=r6>>20(ex: 0xc0008080>>20=0xc00) 69 70 1: orr r3, r7, r5, lsl #SECTION_SHIFT @ mm_mmuflags|0xc0000000 71 str r3, [r4, r5, lsl #PMD_ORDER] @ *(r4+r5*4)=r3(映射r5~r6的代码区, 一般大小是1MB,原地址映射) 72 cmp r5, r6 @ 如果一个页目录项不够,继续映射 73 addlo r5, r5, #1 74 blo 1b 75 76 /* 77 * Map our RAM from the start to the end of the kernel .bss section. 78 */ 79 add r0, r4, #PAGE_OFFSET >> (SECTION_SHIFT - PMD_ORDER) @ r0=0x40004000+0x3000=0x40007000(CONFIG_PAGE_OFFSET在.config中定义) 80 ldr r6, =(_end - 1) @ r6=内核镜像结束地址(ex: 0xc10a8c37) 81 orr r3, r8, r7 @ r3=0x40000000|mm_mmuflags 82 add r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER) @ r6=0x40004000+0x3042 83 1: str r3, [r0], #1 << PMD_ORDER @ *r0=r3; r0+=4 84 add r3, r3, #1 << SECTION_SHIFT @ r3+=(1<<20) 85 cmp r0, r6 @ 判断是否把内核_end全部映射完毕 86 bls 1b @ 如没有完毕,继续映射 87 @ 这段是把线性地址0xc0000000~0xc00xxxxx映射到物理地址0x40000000~0x400xxxxx 88 @ xxxxx根据_end-1而定) 89 90 #ifdef CONFIG_XIP_KERNEL 91 /* 92 * Map the kernel image separately as it is not located in RAM. 93 */ 94 #define XIP_START XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR) 95 mov r3, pc 96 mov r3, r3, lsr #SECTION_SHIFT 97 orr r3, r7, r3, lsl #SECTION_SHIFT 98 add r0, r4, #(XIP_START & 0xff000000) >> (SECTION_SHIFT - PMD_ORDER) 99 str r3, [r0, #((XIP_START & 0x00f00000) >> SECTION_SHIFT) << PMD_ORDER]! 100 ldr r6, =(_edata_loc - 1) 101 add r0, r0, #1 << PMD_ORDER 102 add r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER) 103 1: cmp r0, r6 104 add r3, r3, #1 << SECTION_SHIFT 105 strls r3, [r0], #1 << PMD_ORDER 106 bls 1b 107 #endif 108 109 /* 110 * Then map boot params address in r2 if specified. 111 * We map 2 sections in case the ATAGs/DTB crosses a section boundary. 112 */ 113 mov r0, r2, lsr #SECTION_SHIFT 114 movs r0, r0, lsl #SECTION_SHIFT @ r0=0x40000000(atag所在页目录的基址) 115 subne r3, r0, r8 @ r3=0x00000000 116 addne r3, r3, #PAGE_OFFSET @ r3=0xc0000000 117 addne r3, r4, r3, lsr #(SECTION_SHIFT - PMD_ORDER) @ r3=0x40004000+0x3000=0x40007000 118 orrne r6, r7, r0 @ r6=mm_mmuflags|0x40000000 119 strne r6, [r3], #1 << PMD_ORDER @ 进行1MB映射0xc0000000->0x40000000 120 addne r6, r6, #1 << SECTION_SHIFT @ r6=r6+0x00100000 121 strne r6, [r3] @ 进行1MB映射0xc0010000->0x40010000 122 123 #if defined(CONFIG_ARM_LPAE) && defined(CONFIG_CPU_ENDIAN_BE8) 124 sub r4, r4, #4 @ Fixup page table pointer 125 @ for 64-bit descriptors 126 #endif 127 128 #ifdef CONFIG_DEBUG_LL 129 #if !defined(CONFIG_DEBUG_ICEDCC) && !defined(CONFIG_DEBUG_SEMIHOSTING) 130 /* 131 * Map in IO space for serial debugging. 132 * This allows debug messages to be output 133 * via a serial console before paging_init. 134 */ 135 addruart r7, r3, r0 136 137 mov r3, r3, lsr #SECTION_SHIFT 138 mov r3, r3, lsl #PMD_ORDER 139 140 add r0, r4, r3 141 mov r3, r7, lsr #SECTION_SHIFT 142 ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags 143 orr r3, r7, r3, lsl #SECTION_SHIFT 144 #ifdef CONFIG_ARM_LPAE 145 mov r7, #1 << (54 - 32) @ XN 146 #ifdef CONFIG_CPU_ENDIAN_BE8 147 str r7, [r0], #4 148 str r3, [r0], #4 149 #else 150 str r3, [r0], #4 151 str r7, [r0], #4 152 #endif 153 #else 154 orr r3, r3, #PMD_SECT_XN 155 str r3, [r0], #4 156 #endif 157 158 #else /* CONFIG_DEBUG_ICEDCC || CONFIG_DEBUG_SEMIHOSTING */ 159 /* we don't need any serial debugging mappings */ 160 ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags 161 #endif 162 163 #if defined(CONFIG_ARCH_NETWINDER) || defined(CONFIG_ARCH_CATS) 164 /* 165 * If we're using the NetWinder or CATS, we also need to map 166 * in the 16550-type serial port for the debug messages 167 */ 168 add r0, r4, #0xff000000 >> (SECTION_SHIFT - PMD_ORDER) 169 orr r3, r7, #0x7c000000 170 str r3, [r0] 171 #endif 172 #ifdef CONFIG_ARCH_RPC 173 /* 174 * Map in screen at 0x02000000 & SCREEN2_BASE 175 * Similar reasons here - for debug. This is 176 * only for Acorn RiscPC architectures. 177 */ 178 add r0, r4, #0x02000000 >> (SECTION_SHIFT - PMD_ORDER) 179 orr r3, r7, #0x02000000 180 str r3, [r0] 181 add r0, r4, #0xd8000000 >> (SECTION_SHIFT - PMD_ORDER) 182 str r3, [r0] 183 #endif 184 #endif 185 #ifdef CONFIG_ARM_LPAE 186 sub r4, r4, #0x1000 @ point to the PGD table 187 #endif 188 mov pc, lr @ 返回 189 ENDPROC(__create_page_tables) 190 .ltorg 191 .align 192 __turn_mmu_on_loc: 193 .long . 194 .long __turn_mmu_on 195 .long __turn_mmu_on_end
浙公网安备 33010602011771号