DRM驱动代码分析:uboot/uefi和kernel之间屏幕是如何匹配的

uboot与kernel之间参数的传递:

dsi_display.c
static char dsi_display_primary[MAX_CMDLINE_PARAM_LEN];
module_param_string(dsi_display0, dsi_display_primary, MAX_CMDLINE_PARAM_LEN,	0600);
MODULE_PARM_DESC(dsi_display0,
	"msm_drm.dsi_display0=<display node>:<configX> where <display node> is 'primary dsi display node name' and <configX> where x represents index in the topology list");

MODULE_PARM_DESC:对参数进行说明

include\linux\moduleparam.h
#define module_param_string(name, string, len, perm)			\
	static const struct kparam_string __param_string_##name		\
		= {
      
       len, string };					\
	__module_param_call(MODULE_PARAM_PREFIX, name,			\
			    &param_ops_string,				\
			    .str = &__param_string_##name, perm, -1, 0);\
	__MODULE_PARM_TYPE(name, "string")

name:参数名字
string:驱动代码里的变量名

#ifdef MODULE
#define MODULE_PARAM_PREFIX /* empty */
#else
#define MODULE_PARAM_PREFIX KBUILD_MODNAME "."
#endif

include\linux\moduleparam.h
#if defined(CONFIG_ALPHA) || defined(CONFIG_IA64) || defined(CONFIG_PPC64)
#define __moduleparam_const
#else
#define __moduleparam_const const
#endif

vendor\qcom\opensource\display-drivers\msm\Android.mk
KBUILD_OPTIONS += MODNAME=msm_drm
注:msm_drm.dsi_display0应该就是这么来的

kernel\params.c
const struct kernel_param_ops param_ops_string = {
    
    
	.set = param_set_copystring,
	.get = param_get_string,
};

替换后得到

static const struct kparam_string __param_string_dsi_display0	= {
    
    MAX_CMDLINE_PARAM_LEN, dsi_display_primary};	\
static const char __param_str_dsi_display0[] = "msm_drm.dsi_display0";		\
static struct kernel_param const __param_dsi_display0 
						__used __section("__param")	__aligned(__alignof__(struct kernel_param))			\
	= {
    
     __param_str_dsi_display0, THIS_MODULE, &param_ops_string,			\
	    VERIFY_OCTAL_PERMISSIONS(0600), -1, 0, {
    
     .str = &__param_string_dsi_display0 } }

__param_dsi_display0 放在__param段中。
将"msm_drm.dsi_display0"和cmdline中的参数进行比较,如果同名,则会调用param_set_copystring,将值拷贝到dsi_display_primary。

static struct dsi_display_boot_param boot_displays[MAX_DSI_ACTIVE_DISPLAY] = {
    
    
	{
    
    .boot_param = dsi_display_primary},
	{
    
    .boot_param = dsi_display_secondary},
};
vendor\qcom\opensource\display-drivers\msm\dsi\dsi_display.c
static int dsi_display_parse_boot_display_selection(void)
{
    
    
	char *pos = NULL;
	char disp_buf[MAX_CMDLINE_PARAM_LEN] = {
    
    '\0'};
	int i, j;

	for (i = 0; i < MAX_DSI_ACTIVE_DISPLAY; i++) {
    
    
		strlcpy(disp_buf, boot_displays[i].boot_param,	MAX_CMDLINE_PARAM_LEN);
		pos = strnstr(disp_buf, ":", strlen(disp_buf));
		/* Use ':' as a delimiter to retrieve the display name */
		if (!pos) {
    
    
			DSI_DEBUG("display name[%s]is not valid\n", disp_buf);
			continue;
		}
		for (j = 0; (disp_buf + j) < pos; j++)
			boot_displays[i].name[j] = *(disp_buf + j);

		boot_displays[i].name[j] = '\0';
		boot_displays[i].boot_disp_en = true;
	}
	return 0;
}

在这里插入图片描述
图片来源:Xiaomi POCO F1 (xiaomi-beryllium)

上图是某一款手机/proc/cmdline的值,能看到屏幕信息变量名是msm_drm.dsi_display0,变量值dsi_tianma_fhd_nt36672a_video_display后面是跟了一个’:'。和上面的代码对应起来了。

dsi_display.c
int dsi_display_dev_probe(struct platform_device *pdev)
{
    
    
	boot_disp = &boot_displays[index];
	node = pdev->dev.of_node;
	if (boot_disp->boot_disp_en) {
    
    
		/* The panel name should be same as UEFI name index */
		panel_node = of_find_node_by_name(mdp_node, boot_disp->name);
		if (!panel_node)
			DSI_WARN("%s panel_node %s not found\n", display->display_type,
					boot_disp->name);
	} else {
    
    
		panel_node = of_parse_phandle(node,
				"qcom,dsi-default-panel", 0);
		if (!panel_node)
			DSI_WARN("%s default panel not found\n", display->display_type);
	}
}

通过屏幕名字在设备树中查找屏幕节点。

问:为什么不在uboot/uefi阶段解析dts?
答:uboot/uefi会将dtb的首地址传给kernel。dts里那么多参数,uboot/uefi解析后怎么传给Kernel?

change list:
2023.4.9 module_param_string的分析更加具体一些;

参考资料:
[1]OnePlusOSS/android_kernel_modules_and_devicetree_oneplus_sm8475
[2]Kernel: Xiaomi kernel changes for Mi 10S and Redmi K40 Android R
[3]Linux驱动代码中MODULE_PARM_DESC的作用
[4]驱动模块传参
[5]CSDN kerneler_《linux kernel的cmdline参数解析原理分析》

猜你喜欢

转载自blog.csdn.net/yuuu_cheer/article/details/129214963