arm64+devicetree 组合中的boot_command_line的获取

setup_arch(&command_line)->setup_machine_fdt(__fdt_pointer);需要注意的是*command_line 是指向到 boot_command_line;而boot_command_line是一个静态数组,在arm64的环境下是2048,也就是说bootloader传递给kernel的commandline超过2048就要修改kernel源代码加这个数组加大。
char __initdata boot_command_line[COMMAND_LINE_SIZE];

注意这个__fdt_pointer 是bootloader传递过来的,代表devicetree在内存中的地址
static void __init setup_machine_fdt(phys_addr_t dt_phys)
{
    void *dt_virt = fixmap_remap_fdt(dt_phys);

    if (!dt_virt || !early_init_dt_scan(dt_virt)) {
        pr_crit("\n"
            "Error: invalid device tree blob at physical address %pa (virtual address 0x%p)\n"
            "The dtb must be 8-byte aligned and must not exceed 2 MB in size\n"
            "\nPlease check your bootloader.",
            &dt_phys, dt_virt);

        while (true)
            cpu_relax();
    }

}
在setup_machine_fdt 中现将代表devicetree的物理地址转成虚拟地址,然后调用early_init_dt_scan 来扫描devicetree中的chosen节点,其中 chosen节点就表示bootloader传递给kernel的commandline
early_init_dt_scan->early_init_dt_scan_nodes
void __init early_init_dt_scan_nodes(void)
{
    /* Retrieve various information from the /chosen node */
    of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line);

    /* Initialize {size,address}-cells info */
    of_scan_flat_dt(early_init_dt_scan_root, NULL);

    /* Setup memory, calling early_init_dt_add_memory_arch */
    of_scan_flat_dt(early_init_dt_scan_memory, NULL);
}
在early_init_dt_scan_nodes 中首先调用early_init_dt_scan_chosen 来扫描chosen节点
int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
                     int depth, void *data)
{
    int l;
    const char *p;

    pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);

    if (depth != 1 || !data ||
        (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
        return 0;

    early_init_dt_check_for_initrd(node);

    /* Retrieve command line */
    p = of_get_flat_dt_prop(node, "bootargs", &l);
    if (p != NULL && l > 0)
        strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE));

    /*
     * CONFIG_CMDLINE is meant to be a default in case nothing else
     * managed to set the command line, unless CONFIG_CMDLINE_FORCE
     * is set in which case we override whatever was found earlier.
     */
#ifdef CONFIG_CMDLINE
#if defined(CONFIG_CMDLINE_EXTEND)
    strlcat(data, " ", COMMAND_LINE_SIZE);
    strlcat(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
#elif defined(CONFIG_CMDLINE_FORCE)
    strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
#else
    /* No arguments from boot loader, use kernel's  cmdl*/
    if (!((char *)data)[0])
        strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
#endif
#endif /* CONFIG_CMDLINE */

    pr_debug("Command line is: %s\n", (char*)data);

    /* break now */
    return 1;
}
early_init_dt_scan_chosen 中通过p = of_get_flat_dt_prop(node, "bootargs", &l); 得到chosen节点中的bootargs,这个就代表commandline
然后通过strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE));将commandline copy到boot_command_line中

devicetree 中的chosen 节点大概是下面这样
    chosen {
        bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
        stdout-path = "serial0:115200n8";
    };

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值