Boot 传参至 Kernel 的方法
1. 需求¶
将boot中的字符串传到kernel中。
2. 实现方法¶
目前的框架已经有从boot传参到kernel的方法,比如cmdline会把bootargs的数据传到kernel下,我们只需要模拟cmdline的实现方法,添加一个接口即可。
2.1. boot部分修改¶
arch/arm/include/asm/setup.h:
/* command line: \0 terminated string */ #define ATAG_CMDLINE 0x54410009 /* custom atag: char array */ #define ATAG_CUSTOM 0x54410100 struct tag_custom { u8 size; char data[128]; /* this is the minimum size */ }; union { ... ... struct tag_cmdline cmdline; struct tag_custom custom; ... ... } u;
arch/arm/lib/bootm.c:
static void setup_custom_tag(char *data, u8 size) { params->hdr.tag = ATAG_CUSTOM; params->hdr.size = (sizeof (struct tag_header) + size + 4) >> 2; params->u.custom.size = size; memcpy(params->u.custom.data, data, size); params = tag_next (params); } /* Subcommand: PREP */ static void boot_prep_linux(bootm_headers_t *images) { char *commandline = getenv("bootargs"); char *pethaddr = getenv("ethaddr"); if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) { ... ... } else if (BOOTM_ENABLE_TAGS) { ... ... if (BOOTM_ENABLE_CMDLINE_TAG) setup_commandline_tag(gd->bd, commandline); ... .... setup_custom_tag(pethaddr, 128); setup_board_tags(¶ms); setup_end_tag(gd->bd); } else { printf("FDT and ATAGS support not compiled in - hanging\n"); hang(); } }
2.2. kernel部分修改¶
arch/arm/include/uapi/asm/setup.h:
struct tag_cmdline { char cmdline[1]; /* this is the minimum size */ }; /* custom atag: char array */ #define ATAG_CUSTOM 0x54410100 struct tag_custom { __u8 size; char data[128]; /* this is the minimum size */ }; union { ... ... struct tag_cmdline cmdline; struct tag_custom custom; ... ... } u;
arch/arm/mach-sstar/atags_to_fdt.c:
#include <linux/kernel.h> int early_atags_to_fdt(void *atag_list, void *fdt, int total_space) { ... ... for_each_tag(atag, atag_list) { if (atag->hdr.tag == ATAG_CMDLINE) { /* Append the ATAGS command line to the device tree * command line. * NB: This means that if the same parameter is set in * the device tree and in the tags, the one from the * tags will be chosen. */ if (do_extend_cmdline) merge_fdt_bootargs(fdt, atag->u.cmdline.cmdline); else setprop_string(fdt, "/chosen", "bootargs", atag->u.cmdline.cmdline); } else if (atag->hdr.tag == ATAG_CUSTOM) { char data[128]; memcpy(data, atag->u.custom.data, atag->u.custom.size); printk("atag_custom test:%d\n", (int)atag->u.custom.size); printk("atag_custom test:%s\n", atag->u.custom.data); } ... ... } }
3. 检查确认¶
添加成功之后,上电启动,从如下打印信息中,可以看到已经获取到mac addr了。
Starting kernel ... Booting Linux on physical CPU 0x0 CPU: ARMv7 Processor [410fd034] revision 4 (ARMv7), cr=70c5383d CPU: div instructions available: patching division code CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache atag_custom test:128 atag_custom test:00:30:1b:ba:02:db early_atags_to_fdt() success