earlycon 的使用【转】

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

 

posted @ 2021-08-17 17:08  Sky&Zhang  阅读(2089)  评论(0)    收藏  举报