参考:
linux kernel中的cmdline的详细介绍_kernel command line-CSDN博客
cmdline(二):uboot cmdline怎么传?&&cmdline kernel怎么用?-CSDN博客
linux kernel的启动参数是怎么拿到的-以arm64为例 - 半山随笔 - 博客园 (cnblogs.com)
Kernel怎么解析这个传过来的参数呢?
(1)、跳转linux kernel之前-准备cmdline
在跳转linux kernel之前(如uboot中),将cmdline数据放到了FDT中,然后将FDT的地址写入到了X0中。然后再跳转linux kernel.
请看kernel-4.14/Documentation/arm64/booting.txt
Before jumping into the kernel, the following conditions must be met:
- Quiesce all DMA capable devices so that memory does not get
corrupted by bogus network packets or disk data. This will save
you many hours of debug.
- Primary CPU general-purpose register settings
x0 = physical address of device tree blob (dtb) in system RAM.
x1 = 0 (reserved for future use)
x2 = 0 (reserved for future use)
x3 = 0 (reserved for future use)
arm64即时采用uefi也依然会通过fdt传递内核参数:
/sys/firmware/fdt
/dts-v1/;
// magic: 0xd00dfeed
// totalsize: 0x29d (669)
// off_dt_struct: 0x38
// off_dt_strings: 0x1c8
// off_mem_rsvmap: 0x28
// version: 17
// last_comp_version: 17
// boot_cpuid_phys: 0x0
// size_dt_strings: 0xd5
// size_dt_struct: 0x190/ {
#size-cells = <0x00000002>;
#address-cells = <0x00000002>;
chosen {
linux,uefi-mmap-desc-ver = <0x00000001>;
linux,uefi-mmap-desc-size = <0x00000030>;
linux,uefi-mmap-size = <0x00000f90>;
linux,uefi-mmap-start = <0x00000000 0xf67b1018>;
linux,uefi-system-table = <0x00000000 0xfbfe0018>;
bootargs = "BOOT_IMAGE=/vmlinuz-5.15.0-g8223071764d2-dirty root=UUID=e50cdacd-1591-485d-8b81-f6c611309734 ro video=VGA-1:640x480-32@60me cgroup_disable=files apparmor=0 crashkernel=1024M,high smmu.bypassdev=0x1000:0x17 smmu.bypassdev=0x1000:0x15 console=tty0";
linux,initrd-end = <0x00000000 0xef09a6e3>;
linux,initrd-start = <0x00000000 0xedc1b000>;
};
};
uefi将内核当成efi文件执行入口:
efi_pe_entry:
{
cmdline_ptr = efi_convert_cmdline(image, &cmdline_size); //获取cmdline 启动参数
efi_info("Booting Linux Kernel...\n");
si = setup_graphics();
status = handle_kernel_image(&image_addr, &image_size,
&reserve_addr,
&reserve_size,
image); //重新将内核镜像移动位置,地址保存在image_addr
status = allocate_new_fdt_and_exit_boot(handle, &fdt_addr,
initrd_addr, initrd_size,
cmdline_ptr, fdt_addr, fdt_size);