MIPS架构UBOOT和Linux参数传递


base projcet:dgn1000
cpu:amazon_se
一:in uboot
1. 传给内核参数的地址:
首先设置参数存放在内存中的地址:
in file:lib_mips/board.c

    addr_sp -= CFG_BOOTPARAMS_LEN;    bd->bi_boot_params = addr_sp;//  bd->bi_boot_params = 0x80001000;参数bd->bi_boot_params默认时可以从uboot的前面,这个参数我们是可以改的,我要把传给kernel的参数放到0x80001000的地方,
直接把上面的改成:

bd->bi_boot_params = 0x80001000;就可以了。 2. 把要传给内核的参数写到相应的地址上
in file:lib_mips/mips_linux.c
在uboot的执行的最后一句话为:

theKernel (linux_argc, linux_argv, linux_env, 0);其中:

linux_argc:环境变量bootargv中的包含参数的个数加1。linux_argv:就是环境变量。linux_env: 其他一些必要的参数。最后一个参数0: 暂时是没有使用的。如果:dgn1000的

bootargv= root=/dev/mtdblock4 ip=192.168.1.1:12.168.1.2::::eth0:on console=ttyS0, 115200 eth=00:c0:02:11:22:33 mem=16M panic=1(注:在这里每两个空格之间成为一个参数,如mem=16M)
这里的linux_argc=7。
前面0x400个字节是用于存放每个参数的起始位置,是一个指针,每个指针占四个字节,所以最多可以存放256个参数。
从0x80004000开始存放参数,每个参数都是一“0”结束,如上图红色所示。

linux_env是用于存放其他一些必要的参数,如"memsize", "initrd_start","flash_size"等,linux_env的地址在linux_argv的下面,位置关系为:

linux_env = (char **) (((ulong) argp + 15) & ~15);   //argp指向linux_argv的末尾。存放规则和linux_env是一样的,最多也只能存放256个参数。theKernel的第四个参数,暂时没有起任何作用,我感觉这个参数是起到扩展作用的,如果要传递自己定义的参数,可以按照linux_argv的规则添加。

二:in kernel:
1. 在kernel中会从arch/mips/kernel/head.S中的kernel_entry开始执行:
在函数kernel_entry中有这么一段程序:

     LONG_S      a0, fw_arg0     # firmware arguments    LONG_S      a1, fw_arg1    LONG_S      a2, fw_arg2    LONG_S      a3, fw_arg3(在"include/asm-mips/asm.h"中定义:#define LONG_S sw)在mips架构中,寄存器a0,a1,a2,a3是用于子函数调用传递给子函数参数的,所以fw_arg0=linux_argc,fw_arg1=linux_argv,fw_arg2=linux_env,fw_arg3=0

2. 在函数void __init prom_init(void)中会读取fw_arg0等从uboot传递给kernel的参数。
in file "arch/mips/infineon/amazon_se/basic/prom.c"

start_kernel->setup_arch(&command_line)->prom_init().

相关内容