【正文】
0。 * r5: initrd_end unused if r4 is 0 * r6: Start of mand line string * r7: End of mand line string */ debug ( Booting using board info.../n)。 (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end)。 /* does not return */ }如果未定義CONFIG_OF_LIBFDT或者當(dāng)前bootm命令沒有FDT參數(shù)時(shí)則采用傳統(tǒng)的方式啟動(dòng)內(nèi)核。啟動(dòng)命令格式如下:Bootm kernel_addr ramdisk_addr/ fdt_addr當(dāng)不采用ramdisk時(shí),第二個(gè)參數(shù)為“”5 內(nèi)核如何解析設(shè)備樹1)首先將從uboot 傳遞過來的映像基地址和dtb 文件映像基地址保存通用寄存器r30,r31;2)通過調(diào)用machine_init()、early_init_devtree()函數(shù)來獲取內(nèi)核前期初始化所需的bootargs,cmd_line等系統(tǒng)引導(dǎo)參數(shù);3)調(diào)用start_kernel()、setup_arch()、unflatten_device_tree()函數(shù)來解析dtb 文件,構(gòu)建一個(gè)由device_node 結(jié)構(gòu)連接而成的單項(xiàng)鏈表,并使用全局變量allnodes 指針來保存這個(gè)鏈表的頭指針;4)內(nèi)核調(diào)用OF 提供的API 函數(shù)獲取allnodes鏈表信息來初始化內(nèi)核其他子系統(tǒng)、設(shè)備等。/** This is where the main kernel code starts.*/start_here:。/** Do early platformspecific initialization,* and set up the MMU.*/ mr r3,r31 mr r4,r30 bl machine_init/** Find out what kind of machine we39。re on and save any data we need* from the early boot process (devtree is copied on pmac by prom_init()).* This is called very early on the boot process, after a minimal* MMU environment has been set up but before MMU_init is called.*/void __init machine_init(unsigned long dt_ptr, unsigned long phys){ /* If btext is enabled, we might have a BAT setup for early display, * thus we do enable some very basic udbg output */ifdef CONFIG_BOOTX_TEXT udbg_putc = btext_drawchar。endif /* Do some early initialization based on the flat device tree */ early_init_devtree(__va(dt_ptr))。}/* Warning, IO base is not yet inited */void __init setup_arch(char **cmdline_p){ *cmdline_p = cmd_line。 /* so udelay does something sensible, assume = 1000 bogomips */ loops_per_jiffy = 500000000 / HZ。 unflatten_device_tree()?!?.}/*** unflattens the devicetree passed by the firmware, creating the* tree of struct device_node. It also fills the name and type* pointers of the nodes so the normal devicetree walking functions* can be used (this used to be done by finish_device_tree)*/void __init unflatten_device_tree(void){ unsigned long start, mem, size。 struct device_node **allnextp = amp。allnodes。 DBG( unflatten_device_tree()/n)。 /* First pass, scan for size */ start = ((unsigned long)initial_boot_params) + initial_boot_paramsoff_dt_struct。 size = unflatten_dt_node(0, amp。start, NULL, NULL, 0)。 size = (size | 3) + 1。 DBG( size is %lx, allocating.../n, size)。 /* Allocate memory for the expanded device tree */ mem = lmb_alloc(size + 4, __alignof__(struct device_node))。 mem = (unsigned long) __va(mem)。 ((u32 *)mem)[size / 4] = 0xdeadbeef。 DBG( unflattening %lx.../n, mem)。 /* Second pass, do actual unflattening */ start = ((unsigned long)initial_boot_params) + initial_boot_paramsoff_dt_struct。 unflatten_dt_node(mem, amp。start, NULL, amp。allnextp, 0)。 if (*((u32 *)start) != OF_DT_END) printk(KERN_WARNING Weird tag at end of tree: %08x/n, *((u32 *)start))。 if (((u32 *)mem)[size / 4] != 0xdeadbeef) printk(KERN_WARNING End of tree marker overwritten: %08x/n, ((u32 *)mem)[size / 4] )。 *allnextp = NULL。 /* Get pointer to OF /chosen node for use everywhere */ of_chosen = of_find_node_by_path(/chosen)。 if (of_chosen == NULL) of_chosen = of_find_node_by_path(/chosen@0)。 DBG( unflatten_device_tree()/n)。}6 設(shè)備樹對(duì)驅(qū)動(dòng)設(shè)計(jì)產(chǎn)生的影響TBD