轉自:https://blog.csdn.net/wjxcn/article/details/79542406
關於 earlycon 的實現機制,已經有很多文章提及,這裏就不贅述了。 主要就是記錄在某高通平臺打開 earlycon 的一個過程記錄。 使用 earlycon 最好的方式,其參數是從 dtb 取得,也就是我們要在 dts 裏配置 chosen 節點 chosen { bootargs = "sched_enable_hmp=1 sched_enable_power_aware=1 app_setting.use_32bit_app_setting=1"; stdout-path = &uart0; }; 關於 stdout-path ,在這個平臺上並沒有 uart0 這個節點,其 /proc/cmdline 裏控制檯參數是 console=ttyHSL0,115200,n8 查看下它的設備號 # ls -l /dev/ttyHSL0 crw------- 1 root root 240, 0 1970-01-01 06:27 /dev/ttyHSL0 查看下其他相關信息 # cd /sys/dev/char/240:0 /sys/dev/char/240:0 # cat iomem_base 0x75B0000 /sys/dev/char/240:0 # cat uevent MAJOR=240 MINOR=0 DEVNAME=ttyHSL0 /sys/dev/char/240:0 # cd device/ /sys/dev/char/240:0/device # cat uevent e DRIVER=msm_serial_hsl OF_NAME=serial OF_FULLNAME=/soc/serial@075b0000 OF_COMPATIBLE_0=qcom,msm-lsuart-v14 OF_COMPATIBLE_N=1 MODALIAS=of:NserialT<NULL>Cqcom,msm-lsuart-v14 根據 compatible 和 iomem_base 從相關的dtsi 裏確認,其 stdout-path 應該爲 chosen { bootargs = "sched_enable_hmp=1 sched_enable_power_aware=1 app_setting.use_32bit_app_setting=1"; stdout-path = &uartblsp2dm1; }; 找到平臺對應的mk 文件(這裏是BoardConfig.mk)添加 ifneq ($(TARGET_BUILD_VARIANT),user) BOARD_KERNEL_CMDLINE += earlycon endif 結果發現並沒有生效,而是出現這樣的 Kernel log [ 0.000000] Malformed early option 'earlycon' 由網上的文章,我們可以知道,在一個特定系統裏對於 earlycon 支持,關鍵的幾個配置開關 CONFIG_DEBUG_KERNEL=y CONFIG_SERIAL_EARLYCON=y CONFIG_OF_EARLY_FLATTREE=Y 幾個定義 EARLYCON_DECLARE OF_EARLYCON_DECLARE 在代碼裏查找,發現使用的是 EARLYCON_DECLARE(msm_hsl_uart, msm_hsl_earlycon_setup); OF_EARLYCON_DECLARE(msm_hsl_uart, "qcom,msm_hsl_uart", msm_hsl_earlycon_setup); 由 fdt.c 裏的相關源碼 #ifdef CONFIG_SERIAL_EARLYCON extern struct of_device_id __earlycon_of_table[]; static int __init early_init_dt_scan_chosen_serial(void) { int offset; const char *p; int l; const struct of_device_id *match = __earlycon_of_table; const void *fdt = initial_boot_params; offset = fdt_path_offset(fdt, "/chosen"); if (offset < 0) offset = fdt_path_offset(fdt, "/chosen@0"); if (offset < 0) return -ENOENT; p = fdt_getprop(fdt, offset, "stdout-path", &l); if (!p) p = fdt_getprop(fdt, offset, "linux,stdout-path", &l); if (!p || !l) return -ENOENT; /* Get the node specified by stdout-path */ offset = fdt_path_offset(fdt, p); if (offset < 0) return -ENODEV; while (match->compatible[0]) { unsigned long addr; if (fdt_node_check_compatible(fdt, offset, match->compatible)) { match++; continue; } addr = fdt_translate_address(fdt, offset); if (!addr){ return -ENXIO; } of_setup_earlycon(addr, match->data); return 0; } return -ENODEV; } static int __init setup_of_earlycon(char *buf) { if (buf) return 0; return early_init_dt_scan_chosen_serial(); } early_param("earlycon", setup_of_earlycon); #endif 在進行 of 掃描時,會檢查 compatible,因此換裏這裏的 OF_EARLYCON_DECLARE(msm_hsl_uart, "qcom,msm_hsl_uart", msm_hsl_earlycon_setup); 應當改爲 OF_EARLYCON_DECLARE(msm_hsl_uart, "qcom,msm-lsuart-v14", msm_hsl_earlycon_setup); 重新編譯下載 boot.img,果然 OK 。 後續閱讀 Documentation/kernel-parameters.txt,關於 earlycon 還有與msm_hsl_uart 相關的一段說明 earlycon= [KNL] Output early console device and options. . . . msm_hsl_uart,<addr> Start an early, polled-mode console on an msm serial port at the specified address. The serial port must already be setup and configured. Options are not yet supported. . . . 我們如果只修改 kernel 的命令行 BOARD_KERNEL_CMDLINE += earlycon=msm_hsl_uart,0x075b0000 也是可以的,但是這樣,參數就不是從 dtb 讀取。 ———————————————— 版權聲明:本文爲CSDN博主「wjxcn」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。 原文鏈接:https://blog.csdn.net/wjxcn/article/details/79542406