Uboot如何传递bootargs

uboot并不是直接将bootargs传递给kernel,而是修改dts中的chosen节点实现的。

在uboot中可以发现该函数:

int fdt_chosen(void *fdt)
{
struct abuf buf = {};
int nodeoffset;
int err;
const char *str; /* used to set string properties */

...
/* find or create "/chosen" node. */
nodeoffset = fdt_find_or_add_subnode(fdt, 0, "chosen");
if (nodeoffset < 0)
return nodeoffset;

...

str = board_fdt_chosen_bootargs(fdt_get_property(fdt, nodeoffset,
"bootargs", NULL));

if (str) {
err = fdt_setprop(fdt, nodeoffset, "bootargs", str,
strlen(str) + 1);
if (err < 0) {
printf("WARNING: could not set bootargs %s.\n",
fdt_strerror(err));
return err;
}
}
...
}

就不用管这个函数是怎么被调用的了,反正一定是会被调用到的。

该函数使用fdt_find_or_add_subnode寻找chosen节点,如果没找到chosen节点,就创建一个,随后返回offset。

随后调用board_fdt_chosen_bootargs函数,该函数定义如下:

/**
* board_fdt_chosen_bootargs - boards may override this function to use
* alternative kernel command line arguments
*/
__weak const char *board_fdt_chosen_bootargs(const struct fdt_property *fdt_ba)
{
return env_get("bootargs");
}

该函数直接将环境变量中的bootargs返回,str被赋值为bootargs。

随后调用 fdt_setprop去设置bootargs。

至此bootargs修改完毕。

总结

情况 最后 kernel 用的 bootargs 来源
U-Boot bootargs 非空 用 U-Boot 传的 bootargs
U-Boot bootargs 为空 用 Linux DTS 自己的 chosen节点作为bootargs