cmdline -[command line,__fdt_pointer,initial_boot_params] boot_command_line 获取

[boot_command_line,cmdline,commandline,devicetree地址]

head.S->start_kernel(), head.S mainly obtains the address of dt:

str_l    x21, __fdt_pointer, x5        // Save FDT pointer

>>start_kernel() -- main.c

        >>setup_arch() --setup.c

                >>setup_machine_fdt()

                        >>early_init_dt_scan()  --fdt.c

                                >>early_init_dt_verify() --fdt.c ; After checking __fdt_pointer , assign it to initial_boot_params

                                >> early_init_dt_scan_nodes()   --fdt.c  ; finally get devicetree parameters

                                     >> early_init_dt_scan_chosen  --fdt.c; get command line parameters

setup_arch(&command_line);

command_line is a reference to the global variable boot_command_line

setup_machine_fdt()

After __fdt_pointer is mapped by fixmap_remap_fdt(dt_phys), pass the parameters down

early_init_dt_scan_nodes

Get the command_line parameter and assign a value to boot_command_line

Get the memory parameter

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));   //拷贝到 boot_command_line

    /*
     * 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;
}



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);
}

bootloader parameter passing 

Our usual method is to pass directly through bootargs (arm64) in the bootload, just modify it in the BootLinuxBootParamlistPtr.CmdLine function, and paste a string ( ql_crash_mode=0,0) behind the variable. In the UpdateCmdLine function, a series (many, many) cmdlines are preprocessed

EFI_STATUS BootLinux (BootInfo *Info)
{

    xxxxxxxxxx
    #ifdef QL_DEBUG_MODE
    if ( Info->BootWithDebug == TRUE){
        AsciiStrCatS (BootParamlistPtr.CmdLine, BOOT_ARGS_SIZE, " debug=1");
    }
    #endif

    #ifdef QL_DUMP_MODE
    if ( Info->BootWithDump == TRUE){
        AsciiStrCatS (BootParamlistPtr.CmdLine, BOOT_ARGS_SIZE, " ql_crash_mode=0,0");
    }
    #endif
    Status = UpdateCmdLine (BootParamlistPtr.CmdLine, FfbmStr, Recovery,
                    AlarmBoot, Info->VBCmdLine, &BootParamlistPtr.FinalCmdLine,
                    &BootParamlistPtr.FinalBootConfig,
                    &BootParamlistPtr.FinalBootConfigLen,
                    Info->HeaderVersion,
                    (VOID *)BootParamlistPtr.DeviceTreeLoadAddr);

    xxxxxxxxxx
  
    Status = LoadAddrAndDTUpdate (Info, &BootParamlistPtr);
    if (Status != EFI_SUCCESS) {
        return Status;
    }
    xxxxxxxxxx
}
 

 

After the processing of UpdateCmdLine is completed, LoadAddrAndDTUpdate carries the BootParamlistPtr parameter and after a series of subsequent calls, all the data recorded in cmdline will be added to the device node of  bootargs in the UpdateDeviceTree  function.

EFI_STATUS UpdateDeviceTree (VOID *fdt,CONST CHAR8 *cmdline,VOID *ramdisk,UINT32 RamDiskSize,BOOLEAN BootWith32Bit)
{
  xxxxxxxxxxxx
  if (cmdline) {
    /* Adding the cmdline to the chosen node */
    FdtPropUpdateFunc (fdt, offset, (CONST char *)"bootargs",
                      (CONST VOID *)cmdline, fdt_appendprop_string, ret);
    if (ret) {
      DEBUG ((EFI_D_ERROR,
              "ERROR: Cannot update chosen node [bootargs] - 0x%x\n", ret));
      return EFI_LOAD_ERROR;
    }
  }
  xxxxxxxxxxxx
}
 

FdtPropUpdateFunc: add parameters to fdt bootargs

Parameter reception processing

 After the bootload is transferred to the cmdline, we only need to add the kernel parameter processing function at the appropriate position. If the parameter passed by the bootloader when starting the kernel is "ql_crash_mode=xxx", the set_crash_mode function will be called automatically when the kernel is running, and the parameters carried by the cmdline will be brought into the function through the s parameter.

static int __init set_crash_mode(char *s)

{

xxxxxxxxxx

}

__setup("ql_crash_mode=", set_crash_mode);

Note: Refer to the kernel parameter cmdline follow-up processing source code analysis-1

Guess you like

Origin blog.csdn.net/y13182588139/article/details/125827493