Linux启动流程导读(arm为例)

以arm为例,分析一下kernel的启动过程;

内核版本:linux-3.2.tar.gz

一、arch/arm/kernel/head.s

/* * Kernel startup entry point. * ————————— * * This is normally called from the decompressor code. The requirements * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0, * r1 = machine nr, r2 = atags or dtb pointer. * * This code is mostly position independent, so if you link the kernel at * 0xc0008000, you call this at __pa(0xc0008000). * * See linux/arch/arm/tools/mach-types for the complete list of machine * numbers for r1. * * We’re trying to keep crap to a minimum; DO NOT add any machine specific * crap here – that’s what the boot loader (or in extreme, well justified * circumstances, zImage) is for. */ .arm __HEAD @#define __HEAD .section “.head.text”,”ax”ENTRY(stext) THUMB( adr r9, BSYM(1f) ) @ Kernel is always entered in ARM. THUMB( bx r9 ) @ If this is a Thumb-2 kernel, THUMB( .thumb ) @ switch to Thumb now. THUMB(1: ) setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode 关闭普通中断,快速中断,使能svc模式 @ and irqs disabled mrc p15, 0, r9, c0, c0 @ get processor id 获得芯片ID bl __lookup_processor_type @ r5=procinfo r9=cpuid 获得处理器型号,r5 == id,#1 movs r10, r5 @ invalid processor (r5=0)? 校验正确性,0错误 THUMB( it eq ) @ force fixup-able long branch encoding beq __error_p @ yes, error ‘p’#ifndef CONFIG_XIP_KERNEL adr r3, 2f ldmia r3, {r4, r8} sub r4, r3, r4 @ (PHYS_OFFSET – PAGE_OFFSET)

add r8, r8, r4 @ PHYS_OFFSET

==========

#1 :arch/arm/kernel/head-common.h

==========

/* * 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 r3, __lookup_processor_type_data @adr 相对偏移读取,读取下面type_data地址 ldmia r3, {r4 – r6} @将该地址存放的值 放入r4(.),r5(begin),r6(end) sub r3, r3, r4 @ get offset between virt&phys 链接地址-实际地址=偏移量

==========

继续arch/arm/kernel/head.s

==========

/* * r1 = machine no, r2 = atags or dtb, * r8 = phys_offset, r9 = cpuid, r10 = procinfo */ bl __vet_atags @#1,head-common.s#ifdef CONFIG_SMP_ON_UP bl __fixup_smp @略#endif#ifdef CONFIG_ARM_PATCH_PHYS_VIRT bl __fixup_pv_table @略#endif bl __create_page_tables @#2

==========

#1 :arch/arm/kernel/head-common.h

==========

/* Determine validity of the r2 atags pointer. The heuristic requires * that the pointer be aligned, in the first 16k of physical RAM and * that the ATAG_CORE marker is first and present. If CONFIG_OF_FLATTREE * is selected, then it will also accept a dtb pointer. Future revisions * of this function may be more lenient with the physical address and * may also be able to move the ATAGS block if necessary. * * Returns: * r2 either valid atags pointer, valid dtb pointer, or zero * r5, r6 corrupted */__vet_atags: tst r2, #0x3 @ aligned? 不对其就返回 bne 1f ldr r5, [r2, #0] @读到r5#ifdef CONFIG_OF_FLATTREE ldr r6, =OF_DT_MAGIC @ is it a DTB? 过滤DTB cmp r5, r6 beq 2f#endif cmp r5, #ATAG_CORE_SIZE @ is first tag ATAG_CORE? must be first cmpne r5, #ATAG_CORE_SIZE_EMPTY bne 1f ldr r5, [r2, #4] ldr r6, =ATAG_CORE cmp r5, r6 bne 1f2: mov pc, lr @ atag/dtb pointer is ok 1: mov r2, #0 mov pc, lrENDPROC(__vet_atags)

============

@#2:__create_page_tables

============

/* * 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. * * r8 = phys_offset, r9 = cpuid, r10 = procinfo * * Returns: * r0, r3, r5-r7 corrupted * r4 = physical page table address */__create_page_tables: pgtbl r4, r8 @ page table address

============

每个人在他的人生发轫之初,总有一段时光,

Linux启动流程导读(arm为例)

相关文章:

你感兴趣的文章:

标签云: