__switch_data: .long __mmap_switched .long SYMBOL_NAME(__bss_start) .long SYMBOL_NAME(_end) .long SYMBOL_NAME(processor_id) .long SYMBOL_NAME(__machine_arch_type) .long SYMBOL_NAME(cr_alignment) .long SYMBOL_NAME(init_task_union)+8192 .type __ret, %function __ret: ldr lr, __switch_data mcr p15, 0, r0, c1, c0//更新控制寄存器cp15寄存器1=0x0000217d mov r0, r0 mov r0, r0 mov r0, r0 mov pc, lr//__switch_data /* * This code follows on after the page * table switch and jump above. * * r0 = processor control register * r1 = machine ID * r9 = processor ID */ .align 5 __mmap_switched://把sp指针指向init_task_union+8192(include/linux/sched.h)处,即第 //一个进程的task_struct和系统堆栈的地址;清空BSS段;保存processor ID //和machine type,到全局变量processor_id和__machine_arch_type,这些值 //以后要用到;r0为"A"置位的control register 值,r2为"A"清空的 //control register 值,即对齐检查(Alignment fault checking)位,并保 //存到cr_alignment,和cr_no_alignment(在文件entry-armv.S中)。最 //后跳转到start_kernel(init/main.c) adr r3, __switch_data + 4//__bss_start ldmia r3, {r4, r5, r6, r7, r8, sp}@ r2 = compat//r2=0xc0000000 @ sp = stack pointer //r4=0xc00c04e0;__bss_start //r5=0xc00e02a8;_end //r6=0xc00c0934;processor_id //r7=0xc00c0930;__machine_arch_type //r8=0xc00bcb88;cr_alignment //sp=0xc00bc000;(init_task_union)+8192 mov fp, #0 @ Clear BSS (and zero fp) 1: cmp r4, r5 strcc fp, [r4],#4 bcc 1b str r9, [r6] @ Save processor ID str r1, [r7] @ Save machine type #ifdef CONFIG_ALIGNMENT_TRAP orr r0, r0, #2 @ ...........A. #endif bic r2, r0, #2 @ Clear 'A' bit//r0=0x217d stmia r8, {r0, r2} @ Save control register values b SYMBOL_NAME(start_kernel)//跳转到start_kernel /* * Setup the initial page tables. We only setup the barest * amount which are required to get the kernel running, which * generally means mapping in the kernel code. * * We only map in 4MB of RAM, which should be sufficient in * all cases. * * r5 = physical address of start of RAM * r6 = physical IO address * r7 = byte offset into page tables for IO * r8 = page table flags */ __create_page_tables: |