其他分享
首页 > 其他分享> > arm64 device tree - boot_command_line的获取

arm64 device tree - boot_command_line的获取

作者:互联网

 

调用顺序

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

注意这个__fdt_pointer 是bootloader传递过来的,在 head.S 中保存到__fdt_pointer 这个变量里面的。
参考: https://www.cnblogs.com/zhangzhiwei122/p/16030978.html 中 primary_switched 函数    

setup_machine_fdt

参考: https://www.cnblogs.com/zhangzhiwei122/p/16060453.html   在setup_machine_fdt 中现将代表devicetree的物理地址转成虚拟地址,然后调用early_init_dt_scan 来扫描devicetree中的chosen节点, 其中 chosen节点就表示bootloader传递给kernel的commandline
 

early_init_dt_scan->early_init_dt_scan_nodes

drivers/of/fdt.c  
1185void __init early_init_dt_scan_nodes(void)
1186{
1187        int rc = 0;
1188
1189        /* Retrieve various information from the /chosen node */
1190        rc = of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line);
1191        if (!rc)
1192                pr_warn("No chosen node found, continuing without\n");
1193
1194        /* Initialize {size,address}-cells info */
1195        of_scan_flat_dt(early_init_dt_scan_root, NULL);
1196
1197        /* Setup memory, calling early_init_dt_add_memory_arch */
1198        of_scan_flat_dt(early_init_dt_scan_memory, NULL);
1199}

1190 行,对每一个 node 调用   early_init_dt_scan_chosen  函数来处理。  

  early_init_dt_scan_chosen

1039int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
1040                                     int depth, void *data)
1041{
1042        int l;
1043        const char *p;
1044        const void *rng_seed;
1045
1046        pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
1047
1048        if (depth != 1 || !data ||
1049            (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
1050                return 0;
1051
1052        early_init_dt_check_for_initrd(node);
1053
1054        /* Retrieve command line */
1055        p = of_get_flat_dt_prop(node, "bootargs", &l);
1056        if (p != NULL && l > 0)
1057                strlcpy(data, p, min(l, COMMAND_LINE_SIZE));
1058
1059        /*
1060         * CONFIG_CMDLINE is meant to be a default in case nothing else
1061         * managed to set the command line, unless CONFIG_CMDLINE_FORCE
1062         * is set in which case we override whatever was found earlier.
1063         */
1064#ifdef CONFIG_CMDLINE
1065#if defined(CONFIG_CMDLINE_EXTEND)
1066        strlcat(data, " ", COMMAND_LINE_SIZE);
1067        strlcat(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
1068#elif defined(CONFIG_CMDLINE_FORCE)
1069        strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
1070#else
1071        /* No arguments from boot loader, use kernel's  cmdl*/
1072        if (!((char *)data)[0])
1073                strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
1074#endif
1075#endif /* CONFIG_CMDLINE */
1076
1077        pr_debug("Command line is: %s\n", (char *)data);
1078
1079        rng_seed = of_get_flat_dt_prop(node, "rng-seed", &l);
1080        if (rng_seed && l > 0) {
1081                add_bootloader_randomness(rng_seed, l);
1082
1083                /* try to clear seed so it won't be found. */
1084                fdt_nop_property(initial_boot_params, node, "rng-seed");
1085
1086                /* update CRC check value */
1087                of_fdt_crc32 = crc32_be(~0, initial_boot_params,
1088                                fdt_totalsize(initial_boot_params));
1089        }
1090
1091        /* break now */
1092        return 1;
1093}
  1048 ~ 1050 如果不是 choose 节点,就 return .
1055 是 choose 节点, 通过p = of_get_flat_dt_prop(node, "bootargs", &l); 得到chosen节点中的bootargs,这个就代表commandline
  1057 strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE));将commandline copy到boot_command_line中   1064 ~ 1075 处理 CONFIG_CMDLINE  宏,这个宏是 meke menuconfig 时,填入的字符串。 默认操作,如果 bootloader 没有传递参数,才使用 CONFIG_CMDLINE CMDLINE_EXTEND , 追加 CONFIG_CMDLINE CMDLINE_FORCE,使用 CONFIG_CMDLINE  覆盖 bootloader 的参数。  
devicetree 中的chosen 节点大概是下面这样
    chosen {
        bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
        stdout-path = "serial0:115200n8";
    };

标签:scan,chosen,tree,boot,CMDLINE,init,command,dt,CONFIG
来源: https://www.cnblogs.com/zhangzhiwei122/p/16060542.html