基于ARM 的Linux 的启动分析报告——ARM+Linux的启动分析(5)

//调用宏pgtbl,r4=0xc0024000:页表基址
/*
* Clear the 16K level 1 swapper page table
*/
mov r0, r4 //r0=0xc0024000
mov r3, #0
add r6, r0, #0x4000 //r6=0xc0028000
1: str r3, [r0], #4
str r3, [r0], #4
str r3, [r0], #4
str r3, [r0], #4
teq r0, r6
bne 1b //将地址0xc0024000~0xc0028000清0
ldr r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mm_mmuflags
/*
* Create identity mapping for first MB of kernel to
* cater for the MMU enable. This identity mapping
* will be removed by paging_init(). We use our current program
* counter to determine corresponding section base address.
*/
mov r6, pc, lsr #20 @ start of kernel section
orr r3, r7, r6, lsl #20 @ flags + kernel base
str r3, [r4, r6, lsl #2] @ identity mapping
/*
* Now setup the pagetables for our kernel direct
* mapped region.
*/
add r0, r4, #(KERNEL_START & 0xff000000) >> 18
str r3, [r0, #(KERNEL_START & 0x00f00000) >> 18]!
ldr r6, =(KERNEL_END - 1)
add r0, r0, #4
add r6, r4, r6, lsr #18
1: cmp r0, r6
add r3, r3, #1 << 20
strls r3, [r0], #4
bls 1b
/*
* 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)
*/
.type __lookup_processor_type, %function
__lookup_processor_type: //判断cpu类型
adr r3, 3f //取标号3的地址
ldmda r3, {r5 - r7}
sub r3, r3, r7 @ 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 //读取arm linux中cpu信

and r4, r4, r9 @ mask wanted bits //屏蔽cpu id的低8位
teq r3, r4 //寄存器0的cpu id与arm linux中cpu id比较
beq 2f
add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list) //否则寻找
下一块
//proc_info
cmp r5, r6
blo 1b
mov r5, #0 @ unknown processor //没有匹配信息,r5=0
2: mov pc, lr
/*
* This provides a C-API version of the above function.
*/
ENTRY(lookup_processor_type)
stmfd sp!, {r4 - r7, r9, lr}
mov r9, r0
bl __lookup_processor_type
mov r0, r5
ldmfd sp!, {r4 - r7, r9, pc}
/*
* Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch]
for
* more information about the __proc_info and __arch_info structures.
*/
.long __proc_info_begin
.long __proc_info_end
3: .long .
.long __arch_info_begin
.long __arch_info_end
/*
* Lookup machine architecture in the linker-build list of
architectures.
* Note that we can't use the absolute addresses for the __arch_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.
*
* r1 = machine architecture number
* Returns:
* r3, r4, r6 corrupted
* r5 = mach_info pointer in physical address space
*/
.type __lookup_machine_type, %function
__lookup_machine_type: //判断体系类型
adr r3, 3b //取上面标号2的地址
ldmia r3, {r4, r5, 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: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type
teq r3, r1 @ matches loader number?
beq 2f @ found
add r5, r5, #SIZEOF_MACHINE_DESC @ 不匹配,查找next
machine_desc
cmp r5, r6
blo 1b
mov r5, #0 @ unknown machine
2: mov pc, lr
/*
* This provides a C-API version of the above function.
*/
ENTRY(lookup_machine_type)
stmfd sp!, {r4 - r6, lr}
mov r1, r0
bl __lookup_machine_type
mov r0, r5

ldmfd sp!, {r4 - r6, pc}
因水平有限,如有不妥之处或者更好的方法,敬请指出。

你可能感兴趣的:(linux,list,function,table,UP)