ARM Linux启动代码分析
这可以看到,映射的虚拟地址存在重叠,但并没有关系,一个虚拟地址肯定只对应一个物理地址,但一个物理地址可以对应多个虚拟地址。
291行,看名字就知道是与调试有关的,因此不分析,直接到332行,子程序返回,至此__create_page_tables分析完毕。
98行,r13 = __switch_data的地址,等会再分析__switch_data的内容。
100行,lr = __enable_mmu的物理地址。
101行,pc = r10 + PROCINFO_INITFUNC,跳到struct proc_info_list变量的__cpu_flush成员处,从arch/arm/mm/proc-v6.S文件中可以知道,那里放的是一条跳转指令:b __v6_setup。__v6_setup也是在proc-v6.S中文件中定义:
00157 __v6_setup:00158 #ifdef CONFIG_SMP00159 mrc p15, 0, r0, c1, c0, 1 @ Enable SMP/nAMP mode00160 orr r0, r0, #0x2000161 mcr p15, 0, r0, c1, c0, 100162 #endif00163 00164 mov r0, #000165 mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache00166 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache00167 mcr p15, 0, r0, c7, c15, 0 @ clean+invalidate cache00168 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer00169 #ifdef CONFIG_MMU00170 mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs00171 mcr p15, 0, r0, c2, c0, 2 @ TTB control register00172 orr r4, r4, #TTB_FLAGS00173 mcr p15, 0, r4, c2, c0, 1 @ load TTB100174 #endif /* CONFIG_MMU */00175 adr r5, v6_crval00176 ldmia r5, {r5, r6}00177 #ifdef CONFIG_CPU_ENDIAN_BE800178 orr r6, r6, #1 < 25 @ big-endian page tables00179 #endif00180 mrc p15, 0, r0, c1, c0, 0 @ read control register00181 bic r0, r0, r5 @ clear bits them00182 orr r0, r0, r6 @ set them00183 mov pc, lr @ return to head.S:__ret
158到162行,如果CPU是双核以上的,那么就使能多核模式。
164到168行,失能数据Cache、指令cache和write buffer。
169到174行,如果支持MMU,那么失能数据和指令TLB,将r4或上TTB_FLAGS之后写入到TTB1寄存器。
175行,取得v6_crval标号的物理地址,v6_crval的定义:
00191 .type v6_crval, #object00192 v6_crval:00193 crval clear=0x01e0fb7f, mmuset=0x00c0387d, ucset=0x00c0187c
其中crval是一个宏,定义如下:
.macro crval, clear, mmuset, ucset#ifdef CONFIG_MMU.word \clear.word \mmuset#else.word \clear.word \ucset#endif.endm
这里假设是支持MMU的,因此v6_crval标号的定义替换为:
v6_crval:.word 0x01e0fb7f.word 0x00c0387d
176行,r5 = 0x01e0fb7f,r6 = 0x00c0387d
177到179行,大端模式相关,现在大部分CPU都工作在小端模式。
180行,读控制寄存器的值。
181行,r0 = r0 & (~r5)。
182行,r0 = r0 r6。
183行,返回,注意,这里lr的值为__enable_mmu标号的物理地址,因为返回到__enable_mmu标号处执行,至此__v6_setup分析完毕,下面看__enable_mmu。
00160 __enable_mmu:00161 #ifdef CONFIG_ALIGNMENT_TRAP00162 orr r0, r0, #CR_A00163 #else00164 bic r0, r0, #CR_A00165 #endif00166 #ifdef CONFIG_CPU_DCACHE_DISABLE00167 bic r0, r0, #CR_C00168 #endif00169 #ifdef CONFIG_CPU_BPREDICT_DISABLE00170 bic r0, r0, #CR_Z00171 #endif00172 #ifdef CONFIG_CPU_ICACHE_DISABLE00173 bic r0, r0, #CR_I00174 #endif00175 mov r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) \00176 domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) \00177 domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) \00178 domain_val(DOMAIN_IO, DOMAIN_CLIENT))00179 mcr p15, 0, r5, c3, c0, 0 @ load domain access register00180 mcr p15, 0, r4, c2, c0, 0 @ load page table pointer00181 b __turn_mmu_on00182 ENDPROC(__enable_mmu)
161到174行,根据配置设置相应的位,不说了。
175到179行,设置域存取寄存器。
180行,设置TTB寄存器。
181行,跳到__turn_mmu_o
ARMLinux启动代 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)