微网站如何制作,网站空间不能读数据库,做淘宝站外推广网站,网络推广的方法有哪些U-BOOT 在启动内核时,会向内核传递一些参数.而这些参数是通过 structtag来传递的。
U-boot 把要传递给 kernel 的东西保存在 struct tag数据结构中#xff0c;启动 kernel 时#xff0c;把这个结构体的物理地址传给 kernel#xff1b;Linux kernel通过这个地址分析出u-boot传…U-BOOT 在启动内核时,会向内核传递一些参数.而这些参数是通过 structtag来传递的。
U-boot 把要传递给 kernel 的东西保存在 struct tag数据结构中启动 kernel 时把这个结构体的物理地址传给 kernelLinux kernel通过这个地址分析出u-boot传递的参数。例如u-boot-1.3.4在arm平台下,该函数的实现位于:lib_arm\Bootm.c文件中. 在文件中有如下代码:可以参照《完全手册》的244页 #if defined (CONFIG_SETUP_MEMORY_TAGS) || \ defined(CONFIG_CMDLINE_TAG) || \ defined(CONFIG_INITRD_TAG) || \ defined(CONFIG_SERIAL_TAG) || \ defined(CONFIG_REVISION_TAG) || \ defined(CONFIG_LCD) || \ defined(CONFIG_VFD) static void setup_start_tag (bd_t *bd) { params (struct tag *) bd-bi_boot_params; params-hdr.tag ATAG_CORE; params-hdr.size tag_size (tag_core); params-u.core.flags 0; params-u.core.pagesize 0; params-u.core.rootdev 0; params tag_next (params); } 上面是初始化tag链表在SDRAM里最后一句是作为链表的最关键部分它的定义是 #definetag_next(t) ((struct tag *)((u32 *)(t) (t)-hdr.size)) 作用是指向下一个tag结构体。 其中 defined (CONFIG_SETUP_MEMORY_TAGS) 和defined (CONFIG_CMDLINE_TAG)是必不可少的。前者是标记内存的信息而后者是设置命令行标记比如“root/dev/mtdblock2init/linuxrc consolettySAC0” /common/cmd_bootm.c文件中 bootm 命令对应的do_bootm函数当分析 uImage 中信息发现 OS 是 Linux 时 调用./lib_arm/bootm.c文件中的 do_bootm_linux函数来启动 Linuxkernel 。 在 do_bootm_linux函数中 voiddo_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char*argv[], ulong addr, ulong *len_ptr, int verify) { ...... #if defined(CONFIG_SETUP_MEMORY_TAGS) || \ defined (CONFIG_CMDLINE_TAG) || \ defined (CONFIG_INITRD_TAG) || \ defined (CONFIG_SERIAL_TAG) || \ defined (CONFIG_REVISION_TAG) || \ defined (CONFIG_LCD) || \ defined (CONFIG_VFD) setup_start_tag(bd); // 初始化tag 结构体开始 #ifdefCONFIG_SERIAL_TAG setup_serial_tag(params); #endif #ifdefCONFIG_REVISION_TAG setup_revision_tag(params); #endif #ifdefCONFIG_SETUP_MEMORY_TAGS setup_memory_tags(bd); // 设置 RAM 参数 #endif #ifdefCONFIG_CMDLINE_TAG setup_commandline_tag (bd, commandline); #endif #ifdefCONFIG_INITRD_TAG if (initrd_start initrd_end) setup_initrd_tag (bd, initrd_start,initrd_end); #endif #if defined(CONFIG_VFD) || defined (CONFIG_LCD) setup_videolfb_tag ((gd_t *) gd); #endif setup_end_tag(bd); // 初始化tag 结构体结束 #endif ...... ...... theKernel (0, machid,bd-bi_boot_params); // 传给 Kernel 的参数(struct tag*) 型的 bd-bi_boot_params 当然,有很多的宏来选择是否传递相应的tag到linuxkenel.实际是这些所以针对于 bd-bi_boot_params这个变量.这个变量是个整形变量,代表存放所有tag的buffer的地址. 例如,在 smdk2410.c 中的 board_init() 函数中,对于这个变量进行了如下赋值: gd-bd-bi_boot_params 0x30000100; 0x30000100这个值可以随意指定, 但是要保证和内核中相应的mach_type 一致.以smdk2410为例: 在内核中始终这个值的地方是: arch\arm\mach-s3c2410\mach-smdk2410.c的最后 MACHINE_START(SMDK2410, SMDK2410) .phys_ram S3C2410_SDRAM_PA, .phys_io S3C2410_PA_UART, .io_pg_offst (((u32)S3C24XX_VA_UART) 18) 0xfffc, .boot_params S3C2410_SDRAM_PA 0x100, .map_io smdk2410_map_io, .init_irq smdk2410_init_irq, .timer s3c24xx_timer, MACHINE_END 红色部分的值, 必须等于0x30000100, 否者将会出现无法启动的问题. 内核启动后,会读取0x300000100位置的值, 当然,内核会把这个地址转换成逻辑地址在操作. 因为内核跑起来后,MMU已经工作,必须要把0x300000100这个物理地址转成逻辑地址然后在操作. 对于u- boot传给内核的参数中(tag), 内核比较关系memory的信息,比如memory地址的起始,大小等. 如果没有得到,那么内核无法启 动,内核会进入BUG()函数,然后死在那里. 而memory的信息是由CONFIG_SETUP_MEMORY_TAGS宏决定的. 因此当这个宏没有被定义时,内核跑不起来. 初始化meminfo时会失败.现象就是: Starting Kernel ... 死掉. 一般需要定义: #defineCONFIG_SETUP_MEMORY_TAGS #defineCONFIG_CMDLINE_TAG