earlycon 的使用

关于 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 读取。

  • 0
    点赞
  • 5
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

老碧鹅

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值