前言

        通常硬件设计会经常更新版本和⼀些元器件,⽐如:屏幕、wifi 模组等。如果每⼀个硬件版本都要对应⼀套软件,维护起来就⽐较⿇烦。所以需要 HW_ID 功能实现⼀套软件可以适配不同版本的硬件。
        针对不同硬件版本,软件上需要提供对应的 dtb ⽂件,同时还要提供 ADC/GPIO 硬件唯⼀值⽤于表征当前硬件版本(⽐如:固定的 adc 值、固定的某 GPIO 电平)。
⽤⼾把这些和硬件版本对应的 dtb ⽂件全打包进同⼀个 resource.img,U-Boot 引导 kernel 时会检测硬件唯⼀值,从 resource.img ⾥找出和当前硬件版本匹配的 dtb 传给 kernel。

根据SN选择dtb

直接上代码

在rk的uboot里面的resource_read_hwid_dtb  只用改这里,其他地方不用改

记得把这个配置开启:CONFIG_ROCKCHIP_HWID_DTB=y

根据这个函数修改

#include <asm/arch/vendor.h>





struct resource_file *resource_read_hwid_dtb(void)
{
	int ret;
	struct resource_file *file;
	struct list_head *node;
	char serialno_str[VENDOR_SN_MAX];
	int j,i;
	char uuid[5]; 

	hwid_init_data();

	ret = vendor_storage_read(SN_ID, serialno_str, (VENDOR_SN_MAX-1));

	if (ret > 0) {
		j = strlen(serialno_str);
		for (i = 0; i < j; i++) {
			if ((serialno_str[i] >= 'a' && serialno_str[i] <= 'z') ||
			    (serialno_str[i] >= 'A' && serialno_str[i] <= 'Z') ||
			    (serialno_str[i] >= '0' && serialno_str[i] <= '9'))
				continue;
			else
				break;
		}

		/* valid character count > 0 */
		if (i > 0) {
			serialno_str[i + 1] = 0x0;	
		}
		printk("%d %s line %d serialno_str =  %s \n", ret ,__FUNCTION__, __LINE__,serialno_str);
	}
	 
	strncpy(uuid, serialno_str, 4);
	uuid[4] = '\0';
	printf("uuid: %s\n", uuid);

	list_for_each(node, &entry_head) {
		file = list_entry(node, struct resource_file, link);
		printk("%s line %d file->name =  %s \n" ,__FUNCTION__, __LINE__,file->name);
		if (!strstr(file->name, DTB_SUFFIX))
			continue;

		if (strstr(file->name, KEY_WORDS_ADC_CTRL) &&
		    strstr(file->name, KEY_WORDS_ADC_CH) &&
		    hwid_adc_find_dtb(file->name)) {
			return file;
		} else if (strstr(file->name, KEY_WORDS_GPIO) &&
			   hwid_gpio_find_dtb(file->name)) {
			return file;
		}
	}

	list_for_each(node, &entry_head) {
		file = list_entry(node, struct resource_file, link);
		printk("%s line %d file->name =  %s \n" ,__FUNCTION__, __LINE__,file->name);
		if (!strcmp(uuid, "1111")  && !strcmp(file->name, "rk-kernel.dtb")) {
			printk(" useing rk-kernel.dtb \n");
			return file;
		}else if (!strcmp(uuid, "2222")  && !strcmp(file->name, "1.dtb")) {
			printk(" useing 1.dtb \n");
			return file;
		}else if (!strcmp(uuid, "3333")  && !strcmp(file->name, "2.dtb")) {
			printk(" useing 2.dtb \n");
			return file;
		}
	}
	return NULL;
}

把其他dtb打包到内核镜像里面

dtb文件是放在resource.img

Image:  resource.img (with 1.dtb 2.dtb  logo.bmp logo_kernel.bmp) is ready
Image:  boot.img (with Image  resource.img) is ready

diff --git a/scripts/mkimg b/scripts/mkimg
index 5728db10c5c4..a487171213bb 100755
--- a/scripts/mkimg
+++ b/scripts/mkimg
@@ -250,9 +250,13 @@ if [ "${srctree}" != "${objtree}" ]; then
 		cp -a ${LOGO_KERNEL_PATH} ${objtree}/;
 	fi
 fi

+scripts/resource_tool ${DTB_PATH} ${LOGO} ${LOGO_KERNEL} 1.dtb 2.dtb 

uboot运行结果

举例图片

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐