/*
* The following calls CPU specific code in a position independent
* manner. See arch/arm/mm/proc-*.S for details. r10 = base of
* xxx_proc_info structure selected by __lookup_processor_type
* above. On return, the CPU will be ready for the MMU to be
* turned on, and r0 will hold the CPU control register value.
*/
ldr r13, =__mmap_switched @ address to jump to after
@ mmu has been enabled
adr lr, BSYM(1f) @ return (PIC) address
mov r8, r4 @ set TTBR1 to swapper_pg_dir
ARM( add pc, r10, #PROCINFO_INITFUNC ) //先执行proinfo initfunc,然后跳到lr=__enable_mmu执行。
THUMB( add r12, r10, #PROCINFO_INITFUNC )
THUMB( mov pc, r12 )
1: b __enable_mmu //然后打开mmu,代码最后会跳转到r13=__mmap_switched执行。
ENDPROC(stext)
获取cpu id相关的体系的proc_info_list结构。比如armV7。里面主要保存了体系相关的mmu,tlb,cache等方法。
/*
* Read processor ID register (CP#15, CR0), and look up in the linker-built
* supported processor list. Note that we can't use the absolute addresses
* for the __proc_info lists since we aren't running with the MMU on
* (and therefore, we are not in the correct address space). We have to
* calculate the offset.
*
* r9 = cpuid
* Returns:
* r3, r4, r6 corrupted
* r5 = proc_info pointer in physical address space
* r9 = cpuid (preserved)
*/
__CPUINIT
__lookup_processor_type:
//adr指令将__lookup_processor_type_data的物理地址存到r3中。(实际上一条操作pc的add,sub指令)
adr r3, __lookup_processor_type_data
//r4存放__lookup_processor_type_data的虚拟地址。r5是__proc_info_begin变量虚拟地址。同理r6
//然后根据__lookup_processor_type_data的虚实地址的偏移计算出__proc_info_begin,__pproc_info_end的物理地址。
//这是内核启动前处理地址相关代码的常用方法
//然后就会在所有的proc_info中根据当前cpuid查找匹配的proc_info。
ldmia r3, {r4 - r6}
sub r3, r3, r4 @ get offset between virt&phys
add r5, r5, r3 @ convert virt addresses to
add r6, r6, r3 @ physical address space
1: ldmia r5, {r3, r4} @ value, mask
and r4, r4, r9 @ mask wanted bits
teq r3, r4
beq 2f
add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list)
cmp r5, r6
blo 1b
mov r5, #0 @ unknown processor
2: mov pc, lr
ENDPROC(__lookup_processor_type)
__data_loc -> _data ?
清除bbs。
保存processor_id, machine nr, atags到相应的全局变量给kernel使用。
设置sp=init_thread_union + THREAD_START_SP为0号进程的堆栈。
执行start_kernel(), ohyeah~~~:)大功告成
/*
* The following fragment of code is executed with the MMU on in MMU mode,
* and uses absolute addresses; this is not position independent.
*
* r0 = cp#15 control register
* r1 = machine ID
* r2 = atags/dtb pointer
* r9 = processor ID
*/
__INIT
__mmap_switched:
adr r3, __mmap_switched_data