uboot如何传递参数到内核 tag功能使用方式

tag含义

在做系统开发的时候 希望通过UBOOT可以传递参数到内核,在内核下进行使用
我们选用tag方式进行参数传递
tag是一个数据结构专门用于传递内核参数,如我们平时使用cmdline是通过tag的方式进行传递的
uboot在启动内核的时候会调用 kernel_entry
machid:为机器码

kernel_entry(0, machid, r2);//r2指向tag在内存的地址

r2:可以指向设备树 也可以指向bi_boot_params启动参数:bi_boot_params指向tags结构体在内存的位置

#ifdef CONFIG_OF_LIBFDT
	if (images->ft_len)
		r2 = (unsigned long)images->ft_addr;
	else
#endif
		r2 = gd->bd->bi_boot_params;//指向tag结构体在内核的位置

只要内核在启动时候对r2的地址进行数据结构解析,就可以获取uboot下的参数

tag传输用例

我们在uboot传输一个init型的变量到内核
1.setup.h中增加tag结构体


/* transfer pcb information to kernel */
#define ATAG_TEST_VER 0x41000405//命令唯一码

struct tag_test{
     //test tag结构体
	unsigned int test;
};

struct tag {
     
	struct tag_header hdr;
	union {
     
		struct tag_core		core;
		struct tag_mem32	mem;
		struct tag_videotext	videotext;
		struct tag_ramdisk	ramdisk;
		struct tag_initrd	initrd;
		struct tag_serialnr	serialnr;
		struct tag_revision	revision;
		struct tag_videolfb	videolfb;
		struct tag_cmdline	cmdline;

		/*
		 * Acorn specific
		 */
		struct tag_acorn	acorn;

		/*
		 * DC21285 specific
		 */
		struct tag_memclk	memclk;
		struct tag_test      test;//增加test变量
		
	} u;
};

2.bootm.c中实现tag有效函数

//tag赋值有效函数
static void setup_test_tag(unsigned int test)
{
     
	params->hdr.tag = ATAG_PCB_VER;
	params->hdr.size = tag_size (tag_pcb);
	params->u.test.test = test;
	params = tag_next (params);

}
//设备boot内核之前的运行函数
static void boot_prep_linux(bootm_headers_t *images)
{
     
#ifdef CONFIG_CMDLINE_TAG
	char *commandline = getenv("bootargs");
#endif

#ifdef CONFIG_OF_LIBFDT
	if (images->ft_len) {
     
		debug("using: FDT\n");
		if (create_fdt(images)) {
     
			printf("FDT creation failed! hanging...");
			hang();
		}
	} else
#endif
	{
     
#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
	defined(CONFIG_CMDLINE_TAG) || \
	defined(CONFIG_INITRD_TAG) || \
	defined(CONFIG_SERIAL_TAG) || \
	defined(CONFIG_REVISION_TAG)
		debug("using: ATAGS\n");
		setup_start_tag(gd->bd);
#ifdef CONFIG_SERIAL_TAG
		setup_serial_tag(&params);
#endif
#ifdef CONFIG_CMDLINE_TAG
		setup_commandline_tag(gd->bd, commandline);
#endif
#ifdef CONFIG_REVISION_TAG
		setup_revision_tag(&params);
#endif
#ifdef CONFIG_SETUP_MEMORY_TAGS
		setup_memory_tags(gd->bd);
#endif
		setup_test_tag(0x10101);//传入0x10101
#ifdef CONFIG_INITRD_TAG
		if (images->rd_start && images->rd_end)
			setup_initrd_tag(gd->bd, images->rd_start,
			images->rd_end);
#endif
		setup_board_tags(&params);
		setup_end_tag(gd->bd);
#else /* all tags */
		printf("FDT and ATAGS support not compiled in - hanging\n");
		hang();
#endif /* all tags */
	}
}

3.setup.h中内核下增加tag结构体,注意该tag结构和uboot下保持一致
在这里插入图片描述

/* transfer pcb information to kernel */
#define ATAG_TEST_VER 0x41000405//命令码

struct tag_test{
     //结构体实现
	unsigned int test;
};

struct tag {
     
	struct tag_header hdr;
	union {
     
		struct tag_core		core;
		struct tag_mem32	mem;
		struct tag_videotext	videotext;
		struct tag_ramdisk	ramdisk;
		struct tag_initrd	initrd;
		struct tag_serialnr	serialnr;
		struct tag_revision	revision;
		struct tag_videolfb	videolfb;
		struct tag_cmdline	cmdline;

		/*
		 * Acorn specific
		 */
		struct tag_acorn	acorn;

		/*
		 * DC21285 specific
		 */
		struct tag_memclk	memclk;
		struct tag_test      test;//增加结构体
	} u;
};

2.内核下atags_parse.c中实现tag解析

unsigned int pri_test = 0;
static int __init parse_tag_test(const struct tag *tag)
{
     
	pri_test = tag->u.test.test;
	return 0;
}

__tagtable(ATAG_TEST_VER, parse_tag_test);
unsigned int pri_get_test(void) 
{
     
	return pri_test;
}
EXPORT_SYMBOL(pri_get_test);

3.在main.c中添加测试函数

	parse_early_param();
	parse_args("Booting kernel", static_command_line, __start___param,
		   __stop___param - __start___param,
		   -1, -1, &unknown_bootoption);
	test = pri_get_test();//获取函数

	printk("@@@@@@@@@@@@@@@@pri_get_pcb %x\n",test);//打印信息

4.升级内核查看串口显示结果

[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 32512
[    0.000000] Kernel command line: root=/dev/ram0 console=ttyS0,115200n8 rdinit=/sbin/init mem=128M watchdog=on
[    0.000000] @@@@@@@@@@@@@@@@pri_get_test 10101//测试成功

你可能感兴趣的:(嵌入式,内核,linux,嵌入式,c语言,指针)