日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux kernel中的cmdline的详细介绍

發布時間:2025/3/21 linux 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux kernel中的cmdline的详细介绍 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

cmdline

      • 1、向linux kernel添加cmdline的四種方式
        • (1)、 在dts中的bootargs中添加
        • (2)、在BoardConfig中添加
        • (3)、在uboot中添加
        • (4)、在android的Makefile中添加
      • 2、在uboot中,將cmdline統一放置在FDT中
      • 3、在kernel中,從FDT中解析處cmdline并使用
        • (1)、跳轉linux kernel之前-準備cmdline
        • (2)、kernel啟動-解析cmdline


★★★ 友情鏈接 : 個人博客導讀首頁—點擊此處 ★★★

1、向linux kernel添加cmdline的四種方式

在linux啟動時候,串口log中會打印cmdline

[ 0.000000] c0 0 (swapper) Kernel command line: earlycon androidboot.selinux=permissive uart_dma keep_dbgclk_on clk_ignore_unused initrd=0xd0000000,38711808 rw crash_page=0x8f040000 initrd=/recoveryrc boot_reason=0x2000 ota_status=0x1001

在linux啟動完成后,通過 cat /proc/cmdline也是可以看到cmdline. 那么cmdline是如何添加的呢?

(1)、 在dts中的bootargs中添加

/ {model = "yyyyyyy";compatible = "yyyyyyy", "xxxxxxxx";chosen {/** initrd parameters not set in dts file since the ramdisk.img size* need to check in uboot, and the initrd load address and size will* set in uboot stage.*/bootargs = "earlycon androidboot.selinux=permissive uart_dma keep_dbgclk_on clk_ignore_unused";stdout-path = "serial0:115200";}; ...... }

(2)、在BoardConfig中添加

vim device/xxx/xxx_evb/BoardConfigCommon.mk

BOARD_KERNEL_CMDLINE += androidboot.selinux=enforcing androidboot.hardware=xxxx_phone androidboot.dtbo_idx=0

(3)、在uboot中添加

vim u-boot/common/cmd_bootm.c

append_bootargs("recovery=1");sprintf(dm_buf,"init=/init skip_initramfs rootwait root=/dev/dm-0 dm=\"system none ro,0 1 android-verity /dev/mmcblk0p%d\"",ret); append_bootargs((const char *)dm_buf);

(4)、在android的Makefile中添加

vim build/core/Makefile

INTERNAL_KERNEL_CMDLINE := $(strip $(BOARD_KERNEL_CMDLINE) buildvariant=$(TARGET_BUILD_VARIANT) $(VERITY_KEYID)) ifdef INTERNAL_KERNEL_CMDLINE INTERNAL_BOOTIMAGE_ARGS += --cmdline "$(INTERNAL_KERNEL_CMDLINE)" endif

2、在uboot中,將cmdline統一放置在FDT中

以后再寫,哈哈哈哈

3、在kernel中,從FDT中解析處cmdline并使用

(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 getcorrupted by bogus network packets or disk data. This will saveyou many hours of debug.- Primary CPU general-purpose register settingsx0 = 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)

(2)、kernel啟動-解析cmdline

linux kernel從stext開始啟動,整個流程大概就是讀取X0(FDT地址)保存到X21中,又將X21保存到__fdt_pointer全局變量中
然后再將__fdt_pointer解析處cmdline數據到boot_command_line全局變量中

/** The following callee saved general purpose registers are used on the* primary lowlevel boot path:** Register Scope Purpose* x21 stext() .. start_kernel() FDT pointer passed at boot in x0* x23 stext() .. start_kernel() physical misalignment/KASLR offset* x28 __create_page_tables() callee preserved temp register* x19/x20 __primary_switch() callee preserved temp registers*/ ENTRY(stext)bl preserve_boot_argsbl el2_setup // Drop to EL1, w0=cpu_boot_modeadrp x23, __PHYS_OFFSETand x23, x23, MIN_KIMG_ALIGN - 1 // KASLR offset, defaults to 0bl set_cpu_boot_mode_flagbl __create_page_tables/** The following calls CPU setup code, see arch/arm64/mm/proc.S for* details.* On return, the CPU will be ready for the MMU to be turned on and* the TCR will have been set.*/bl __cpu_setup // initialise processorb __primary_switch ENDPROC(stext)

這里調用了:
preserve_boot_args
__primary_switch

在preserve_boot_args將X0(fdt地址)暫時先保存到了X21中

preserve_boot_args:mov x21, x0 // x21=FDTadr_l x0, boot_args // record the contents ofstp x21, x1, [x0] // x0 .. x3 at kernel entrystp x2, x3, [x0, #16]dmb sy // needed before dc ivac with// MMU offmov x1, #0x20 // 4 x 8 bytesb __inval_dcache_area // tail call ENDPROC(preserve_boot_args) __primary_switch調用了__primary_switched __primary_switch: #ifdef CONFIG_RANDOMIZE_BASEmov x19, x0 // preserve new SCTLR_EL1 valuemrs x20, sctlr_el1 // preserve old SCTLR_EL1 value #endifbl __enable_mmu #ifdef CONFIG_RELOCATABLEbl __relocate_kernel #ifdef CONFIG_RANDOMIZE_BASEldr x8, =__primary_switchedadrp x0, __PHYS_OFFSETblr x8

__primary_switched將X21(fdt地址)保存到了__fdt_pointer全局變量中

__primary_switched:adrp x4, init_thread_unionadd sp, x4, #THREAD_SIZEadr_l x5, init_taskmsr sp_el0, x5 // Save thread_infoadr_l x8, vectors // load VBAR_EL1 with virtualmsr vbar_el1, x8 // vector table addressisbstp xzr, x30, [sp, #-16]!mov x29, spstr_l x21, __fdt_pointer, x5 // Save FDT pointerldr_l x4, kimage_vaddr // Save the offset betweensub x4, x4, x0 // the kernel virtual andstr_l x4, kimage_voffset, x5 // physical mappings// Clear BSSadr_l x0, __bss_startmov x1, xzradr_l x2, __bss_stopsub x2, x2, x0bl __pi_memsetdsb ishst // Make zero page visible to PTW

在setup_arch()的時候,調用setup_machine_fdt將fdt解析到了boot_command_line全局變量中

void __init setup_arch(char **cmdline_p) {pr_info("Boot CPU: AArch64 Processor [%08x]\n", read_cpuid_id()); ......*cmdline_p = boot_command_line; ......setup_machine_fdt(__fdt_pointer); ...... }

setup_machine_fdt()—>early_init_dt_scan()—>early_init_dt_scan_nodes()
在中,將fdt解析到了boot_command_line中
of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line)

static void __init setup_machine_fdt(phys_addr_t dt_phys) {void *dt_virt = fixmap_remap_fdt(dt_phys);const char *name;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();}name = of_flat_dt_get_machine_name();if (!name)return;/* backward-compatibility for third-party applications */machine_desc_set(name);pr_info("Machine model: %s\n", name);dump_stack_set_arch_desc("%s (DT)", name); } bool __init early_init_dt_scan(void *params){bool status;status = early_init_dt_verify(params);if (!status)return false;early_init_dt_scan_nodes();return true;} 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);}

在start_kernel()打印了cmdline.
asmlinkage __visible void __init start_kernel(void)
{

pr_notice(“Kernel command line: %s\n”, boot_command_line);

}

總結

以上是生活随笔為你收集整理的linux kernel中的cmdline的详细介绍的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。