繁体   English   中英

使用设备树时将内核参数从U-Boot传递到ARM Linux

[英]Passing kernel params from U-Boot to ARM Linux when device tree is used

我一直在研究对某些嵌入式软件的更改,因为我们希望U-Boot能够将特定的命令行参数传递给内核,而这些参数不一定是事先已知的。

这样内核就可以知道它是从哪个 U-Boot分区启动的(我们有两个副本,一个在/dev/mmc3boot0/dev/mmc3boot1 ,它们都共享一个(冗余)环境空间,因此我们可以不能单独使用它来唯一标识实例)。

一种想法是在引导时将每个U-Boot简单地将其ID写入共享环境,但这有一个缺点,就是目前有一些变体目前不执行此操作。 因此,如果我们从一个不启动的启动,它将写入其ID;如果从一个不启动的启动,则它将写入ID,如果依赖它,它将不会将ID 回空白,从而导致信息不正确。

这就是为什么我们考虑使用内核参数的原因-由于较早版本的U-Boot实例从不提供ID,因此我们知道它在boot0运行。 较新的样式将提供其实际ID,因此我们可以搜索两个boot分区以查看其所在的分区。

为此,我修改了U-Boot,以便它设置ATAG以传递所需的额外参数。 特别:

  • 我在arch\\arm\\include\\asm\\config.h定义了CONFIG_SYS_BOOT_GET_CMDLINE ,以便调用boot_get_cmdline()
  • 我已经修改了boot_get_cmdline()函数,以便附加普通参数之前先设置一个特定参数。 换句话说,我们现在得到的不仅仅是plugh=xyzzy ,而是uboot_instance=42 plugh=xyzzy

所有这些都可以正常编译,并且U-Boot成功启动了内核,但是额外的信息没有反映在Linux内核中,该内核的内核参数设置为常规的plugh=xyzzy

在进一步的研究中,似乎我们不符合调用内核的两种可能方式。 其中之一与ATAG一起使用,一个与扁平设备树(FDT)一起使用,并且它们似乎是互斥的(内核启动代码根据传递的签名选择一个或另一个,该签名通过引用ATAG或FDT结构的指针传递)。

所以我的问题是这个。 假设设备树是您要描述的设备的固定结构,那么当引导加载程序调用内核时,如何传递任意的内核命令行参数(在运行时计算)?

您可以在include/configs/<board>.h为您的平台使用虚拟环境变量。

例如,假定您具有以下(简化的)UBoot环境变量用于引导:

bootcmd=run mmcargs
        run loadimage loadfdt
        bootz ${loadaddr} - ${fdt_addr}
mmcargs=setenv bootargs blah=blah

这使用mmcargs设置要使用的内核命令行。 我们需要做的是以当前UBoot实例不提供任何内容而新的实例提供实际ID的方式插入该虚拟环境变量。 只需进行以下更改即可完成:

mmcargs=setenv bootargs ${uboot_id_stanza} blah=blah

然后,板的初始化过程中,您可以通过设置此变量env_set API专门写自己的自定义, board_late_init在板初始化代码的board/<vendor>/<init_code>.c

以下行应放在board_late_init函数的末尾:

setenv("uboot_id_stanza", "uboot_id=<uniqueId>");

这样, uboot_id变量设置将添加到内核命令行,但是由于您没有执行saveenv ,因此它不会持久化。 每个UBoot实例都将设置正确的ID(包括设置ID的旧ID)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM