linux cmdline介绍

   uboot向内核传递bootargs参数有两种方式,一种是通过truct tag 数据结构,U-boot 把要传递给 kernel 的东西保存在 struct tag 数据结构中,启动 kernel 时,把这个结构体的物理地址传给 kernel ; Linux kernel 通过这个地址,用 parse_tags 分析出传递过来的参数。另一种是通过设备树的bootargs节点,uboot把bootargs参数写入到设备数的bootargs节点中,内核启动时会去设备树读取保存在cmdline中。下面讨论一下设备树的传递方式。

  在run_main_loop中uboot启动等待几秒没进入命令模式就会执行bootcmd启动内核,这个命令会执行以下几个函数来设置bootargs到设备数中:

  

  -->do_bootm_linux         //uboot/arch/arm/lib/bootm.c

    -->boot_prep_linux       //可以在这个函数中加一些自己定义的参数

      -->image_setup_linux    //uboot/common/image.c

        -->image_setup_libfdt  //uboot/common/image-fdt.c

          -->fdt_chosen    //这个函数会将ubootde bootargs参数写入到设备数bootargs节点中

 

在kernel/init/main.c中定义了一个全局变量boot_command_line,该变量就是用来存放/proc/cmdline 的内容

  

下面看一/proc/cmdline是如何获取的

  

  -->start_kernel  //kernel/init/main.c

    -->setup_arch //kernel/arch/arm64/kernel/setup.c

      -->setup_machine_fdt

        -->early_init_dt_scan

          -->early_init_dt_scan_nodes  //kernel/drivers/of/fdt.c

 

setup_machine_fdt 函数位于kernel/arch/arm64/kernel/setup.c中
static void __init setup_machine_fdt(phys_addr_t dt_phys)
{
    void *dt_virt = fixmap_remap_fdt(dt_phys);  //dt_phys是设备树的物理地址,这里转换为虚拟地址
    const char *name;

    if (!dt_virt || !early_init_dt_scan(dt_virt)) {  //这个函数将获取设备树bootargs节点的值保存在boot_command_line全局变量中
        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();
    }

    name = of_flat_dt_get_machine_name();  //这个函数是获取设备数中model的值
    if (!name)
        return;

    pr_info("Machine model: %s\n", name);
    dump_stack_set_arch_desc("%s (DT)", name);
}

 

posted @ 2024-12-16 20:57  YYFaGe  阅读(12)  评论(0编辑  收藏  举报