u_boot和Linux内核之间的参数传递

来源:互联网 发布:淘宝商品加入公益宝贝 编辑:程序博客网 时间:2024/05/21 07:48

今天学了U_boot和Linux内核之间的参数传递,分享一下,写得不好勿怪......

u_boot完成的硬件的相关初始化,是知道Linux内核的相关信息的,但是Linux是直接被加载到内存中去的,刚开始对u_boot是一脸懵逼的,那怎么办呢?当然是u_boot告诉Linux内核一些信息,这就是所谓的参数传递。

u_boot主要传递给Linux内核3个参数:

r0:0x0   

r1 : 开发板的ID         ------------------ r1的参数,是让Linux内核自己去判断,它是否支持当前的开发板

r2 : 其他参数在内存中开始的地址

r2传递的开始地址中含有的信息

(1)内存的信息 -------- 内存的开始地址和内存的大小
   
(2)命令行参数:bootargs的内容--------------- 告诉Linux内核启动后,挂载文件系统的方式(例如:NFS方式)
 
(3)其他信息


r2只传递了开始的地址,并没有告诉Linux内核传递的参数内存的大小,那Linux内核是怎么知道什么时候结束的呢?

u_boot和Linux内核早就谈好了的,我们规定格式,双方按照规矩来办事。


目前Linux内核支持哪些格式的传递呢?

(1):通过struct parm_struct结构体来传递 (Linux 2.6之前使用的方式,已经过时,不便于扩展)

(2):通过tag列表来传递 (Linux 2.6开始使用的方式)       --------      一个tag节点包含了tag头 + 大小 + 内容



(3):通过设备树来传递(Linux 3.0开始使用的方式)   -----   u_boot 修改了设备树的节点,把需要传递的信息放在了设备树中



我的环境是:Linux内核版本----3.2.0-29-generic-pae

                       ubuntu版本是12.04-1

下面是部分源码,大家想看源码的可以去u_boot下的arch/arm/lib/bootm.c查看(这是我的u_boot的路径,不同的内核或者BootLoader都可能不同)

/* Main Entry point for arm bootm implementation * * Modeled after the powerpc implementation * DIFFERENCE: Instead of calling prep and go at the end * they are called if subcommand is equal 0. */int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images){/* No need for those on ARM */if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE)return -1;if (flag & BOOTM_STATE_OS_PREP) {boot_prep_linux(images);return 0;}if (flag & BOOTM_STATE_OS_GO) {boot_jump_linux(images);return 0;}boot_prep_linux(images);boot_jump_linux(images);return 0;}/* Subcommand: PREP */static void boot_prep_linux(bootm_headers_t *images){#ifdef CONFIG_CMDLINE_TAGchar *commandline = getenv("bootargs");#endif#ifdef CONFIG_OF_LIBFDTif (images->ft_len) {debug("using: FDT\n");if (create_fdt(images)) {printf("FDT creation failed! hanging...");hang();}} else#endif/* Subcommand: GO */static void boot_jump_linux(bootm_headers_t *images){unsigned long machid = gd->bd->bi_arch_number;char *s;void (*kernel_entry)(int zero, int arch, uint params);unsigned long r2;kernel_entry = (void (*)(int, int, uint))images->ep;s = getenv("machid");if (s) {strict_strtoul(s, 16, &machid);printf("Using machid 0x%lx from environment\n", machid);}debug("## Transferring control to Linux (at address %08lx)" \"...\n", (ulong) kernel_entry);bootstage_mark(BOOTSTAGE_ID_RUN_OS);announce_and_cleanup();#ifdef CONFIG_OF_LIBFDTif (images->ft_len)r2 = (unsigned long)images->ft_addr;else#endifr2 = gd->bd->bi_boot_params;kernel_entry(0, machid, r2);}




原创粉丝点击