由于工作中遇到内核ramdisk参数传递问题,对Uboot与内核参数传递进行了了解
参数传递有两种方式,内核最终都统一为struct tag形式进行解析处理:
1. struct param_struct
这个结构是linux2.4及以前版本采用的参数方式
2. struct tag
Linux2.6开始使用,采用链表形式保存参数,根据TAG定义识别类型
内核代码分析:
arch/arm/rkernel/setup.c
void __init setup_arch(char **cmdline_p)
{
struct tag *tags = (struct tag *)&init_tags;
struct machine_desc *mdesc;
char *from = default_command_line;
unwind_init();
setup_processor();
mdesc = setup_machine(machine_arch_type); // 通过machine_arch_type找mdesc结构, uboot跳转到内核kernel_entry(0, machid, bd->bi_boot_params);
// machid保存在r1寄存器中
machine_name = mdesc->name;
if (mdesc->soft_reboot)
reboot_setup("s");
if (__atags_pointer)
tags = phys_to_virt(__atags_pointer); // uboot传递的参数形式是tag,Uboot跳转到内核后,struct tag指针保存在r2,head.s(head-common.s)中转存
// 到__atags_pointer
else if (mdesc->boot_params)
tags = phys_to_virt(mdesc->boot_params); // uboot传递的参数是param_struct形式,通过内核定义mdesc->boot_params指针找到参数存放位置
/*
* If we have the old style parameters, convert them to
* a tag list.
*/
if (tags->hdr.tag != ATAG_CORE) // 如果是param_struct形式,hdr.tag补位ATAG_CORE,进行转换
convert_to_tag_list(tags);
if (tags->hdr.tag != ATAG_CORE)
tags = (struct tag *)&init_tags;
........
}