转自: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