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().