freshtree 1.2 __lookup_machine_type() 機器類型的查找代碼如下: __lookup_machine_type: adr r3, 3b 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 ENDPROC(__lookup_machine_type) 我們可以看到,這和處理器類型查找函數很類似,在這里只進行簡單的解說。 .long __proc_info_begin .long __proc_info_end 3: .long . .long __arch_info_begin .long __arch_info_end __arch_info_begin和__arch_info_end在arch/arm/kernel/vlinux.lds.S中定義: __arch_info_begin = .; *(.arch.info.init) __arch_info_end = .; .arch.info.init段我們可以找到在arch/arm/include/asm/mach/arch.h中有引用: #define MACHINE_START(_type,_name) \ static const struct machine_desc __mach_desc_##_type \ __used \ __attribute__((__section__(".arch.info.init"))) = { \ .nr = MACH_TYPE_##_type, \ .name = _name, #define MACHINE_END \ }; 我們可以在arch/arm/mach-*.c文件中找到一系列關于MACHINE_START所定義的結構。 1.3 __vet_atags() 函數代碼如下: __vet_atags: tst r2, #0x3 @ aligned? bne 1f ldr r5, [r2, #0] @ is first tag ATAG_CORE? subs r5, r5, #ATAG_CORE_SIZE bne 1f ldr r5, [r2, #4] ldr r6, =ATAG_CORE cmp r5, r6 bne 1f mov pc, lr @ atag pointer is ok 1: mov r2, #0 mov pc, lr ENDPROC(__vet_atags) atag是bootloader傳遞給linux內核的參數列表。這個參數列表是以tag的列表形式來表示的。這個列表起始位置的tag是ATAG_CORE,用來表示這是一個有效的tag列表。如果起始tag不是ATAG_CORE,就認為bootloader沒有傳遞tag參數給內核。以下是tag值的定義和描述,以及tag結構的定義。 Tag name Value Size Description ATAG_NONE 0x00000000 2 Empty tag used to end list ATAG_CORE 0x54410001 5 (2 if empty) First tag used to start list ATAG_MEM 0x54410002 4 Describes a physical area of memory ATAG_VIDEOTEXT 0x54410003 5 Describes a VGA text display ATAG_RAMDISK 0x54410004 5 Describes how the ramdisk will be used in kernel ATAG_INITRD2 0x54420005 4 Describes where the compressed ramdisk image is placed in memory ATAG_SERIAL 0x54410006 4 64 bit board serial number ATAG_REVISION 0x54410007 3 32 bit board revision number ATAG_VIDEOLFB 0x54410008 8 Initial values for vesafb-type framebuffers ATAG_CMDLINE 0x54410009 2 + ((length_of_cmdline + 3) / 4) Command line to pass to kernel struct tag_header { __u32 size; __u32 tag; }; struct tag { struct tag_header hdr; union { struct tag_core core; struct tag_mem32 mem; struct tag_videotext videotext; struct tag_ramdisk ramdisk; struct tag_initrd initrd; struct tag_serialnr serialnr; struct tag_revision revision; struct tag_videolfb videolfb; struct tag_cmdline cmdline; struct tag_acorn acorn; struct tag_memclk memclk; } u; }; __vet_atags()函數實現的就是判斷r2是否是有效的tag列表指針,如果不是,就將零指針賦值給r2。 |