本文共 2919 字,大约阅读时间需要 9 分钟。
新旧内核有所不同
在旧的内核是通过宏KERNEL_RAM_PADDR来确定
在新的内核中创建临时页表的时候,得到实际的物理内存地址是通过计算得到的,见下面加粗字体
44 .macro pgtbl, rd, phys
45 add \rd, \phys, #TEXT_OFFSET - 0x4000
46 .endm
48 #ifdef CONFIG_XIP_KERNEL
49 #define KERNEL_START XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
50 #define KERNEL_END _edata_loc
51 #else
52 #define KERNEL_START KERNEL_RAM_VADDR
53 #define KERNEL_END _end
54 #endif
139 __create_page_tables: @R8是实际的物理地址 R4是16K页表大小。
140 pgtbl r4, r8 @ page table address通过宏 pgtbl 将r4设置成页表的基地址(物理地址),宏pgtbl 在 arch/arm/kernel/head.S第44定义,可以看到,页表是位于 TEXT_OFFSET下面 16k 的位置,r4 = 0x30004000 这是转换表的物理基地址,最终将写入CP15 的寄存器 2 , C2 。这个值必须是 16K 对齐的。
141
74 __HEAD
75 ENTRY(stext)
76 setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ 确保进入管理(svc)模式
77 @ 并且禁止中断
78 mrc p15, 0, r9, c0, c0 @ 读取CPU ID,存入r9寄存器
79 bl __lookup_processor_type @ 调用函数,输入参数r9=cpuid,
@ 返回值r5=procinfo
80 movs r10, r5 @ 如果不支持当前CPU,则返回 (r5=0)
81 THUMB( it eq ) @ force fixup-able long branch encoding
82 beq __error_p @ 如果r5=0,则打印错误
83
84 #ifndef CONFIG_XIP_KERNEL
@ 在调用__enable_mmu前使用的都是物理地址,而内核却是以虚拟地 址连接的,这里进行一次转换
85 adr r3, 2f @ r3= 第124行代码的物理地址
86 ldmia r3, {r4, r8} @ r4= 第124行代码的虚似地址,r8=PAGE_OFFSET
87 sub r4, r3, r4 @ (PHYS_OFFSET - PAGE_OFFSET)即物理地址与虚似地址差值
88 add r8, r8, r4 @ PHYS_OFFSET r8=PAGE_OFFSET对应的物理地址
89 #else
90 ldr r8, =PLAT_PHYS_OFFSET @ RAM的起始物理地址,值为0x30000000
91 #endif
92
93 /*
94 * r1 = machine no, r2 = atags or dtb,
95 * r8 = phys_offset, r9 = cpuid, r10 = procinfo
96 */
97 bl __vet_atags @ 检查bootloader传入的参数列表atags的合法性
98 #ifdef CONFIG_SMP_ON_UP @ 2410没有定义
99 bl __fixup_smp
100 #endif
101 #ifdef CONFIG_ARM_PATCH_PHYS_VIRT @ 2410没有定义
102 bl __fixup_pv_table
103 #endif
在2.6.39版本前,还增加了__lookup_machine_type板级类型支持的检查,这里已经被取消,却增加了84-91行的代码,并且除第97行外,其它有些是没有的,
104 bl __create_page_tables @创建初始页表
105
106 /*
107 * The following calls CPU specific code in a position independent
108 * manner. See arch/arm/mm/proc-*.S for details. r10 = base of
109 * xxx_proc_info structure selected by __lookup_processor_type
110 * above. On return, the CPU will be ready for the MMU to be
111 * turned on, and r0 will hold the CPU control register value.
112 */
113 ldr r13, =__mmap_switched @ 将列表__switch_data存到r13中后面会跳到该列表出
114 @ mmu has been enabled
115 adr lr, BSYM(1f) @ return (PIC) address将程序段 __enable_mmu的地址存到 lr中。
116 mov r8, r4 @ set TTBR1 to swapper_pg_dir
@ r10中存放的基地址是从__lookup_processor_type中得到的,如上面movs r10, r5
117 ARM( add pc, r10, #PROCINFO_INITFUNC )
118 THUMB( add r12, r10, #PROCINFO_INITFUNC )
119 THUMB( mov pc, r12 )
120 1: b __enable_mmu
121 ENDPROC(stext)
122 .ltorg
123 #ifndef CONFIG_XIP_KERNEL
124 2: .long . @ "."号表示当前这行代码编译连接后的虚似地址
125 .long PAGE_OFFSET
126 #endif