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

 

posted on 2013-08-20 23:37  choi87  阅读(1207)  评论(0)    收藏  举报