Android 9.0 MTK平台Nvram写sn号失败

引言

最近遇到调用Nvram服务写SN号失败的问题,
抓取了日志,没有看到明显的异常

	Line 372: 04-20 12:57:20.187   411   411 D NVRAM   : NVM_GetLIDByName /mnt/vendor/nvdata/APCFG/APRDEB/PRODUCT_INFO 
	Line 373: 04-20 12:57:20.188   411   411 D NVRAM   : NVRAM: NVM_GetLIDByName Lid =61 
	Line 376: 04-20 12:57:20.188   411   411 D NVRAM   : 61 is in new nvram partition!!!
	Line 377: 04-20 12:57:20.188   411   411 D NVRAM   : New NVRAM partition name is /dev/block/platform/bootdevice/by-name/proinfo.
	Line 390: 04-20 12:57:20.194   411   411 D NVRAM   : 61 is in new nvram partition!!!
	Line 391: 04-20 12:57:20.195   411   411 D NVRAM   : Read Done!Size is 64
	Line 392: 04-20 12:57:20.195   411   411 D NVRAM   : nvramstr buff[0]0, buff[1]0, buff[2]0, buff[3]0, buff[4]0, buff[5]0, buff[6]0, buff[7]0, buff[8]0 
	Line 393: 04-20 12:57:20.195   411   411 D NVRAM   : nvramstr 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
	Line 394: 04-20 12:57:20.195   411   411 D NVRAM   : 
	Line 397: 04-20 12:57:20.198   411   411 D NVRAM   : NVM_GetLIDByName /mnt/vendor/nvdata/APCFG/APRDEB/PRODUCT_INFO 
	Line 398: 04-20 12:57:20.198   411   411 D NVRAM   : NVRAM: NVM_GetLIDByName Lid =61 
	Line 399: 04-20 12:57:20.198   411   411 D NVRAM   : 61 is in new nvram partition!!!
	Line 400: 04-20 12:57:20.198   411   411 D NVRAM   : New NVRAM partition name is /dev/block/platform/bootdevice/by-name/proinfo.
	Line 402: 04-20 12:57:20.199   411   411 D NVRAM   : 61 is in new nvram partition!!!
	Line 403: 04-20 12:57:20.199   411   411 D NVRAM   : Read Done!Size is 64
	Line 404: 04-20 12:57:20.199   411   411 D NVRAM   : nvramstr buff[0]0, buff[1]0, buff[2]0, buff[3]0, buff[4]0, buff[5]0, buff[6]0, buff[7]0, buff[8]0 
	Line 405: 04-20 12:57:20.199   411   411 D NVRAM   : nvramstr 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
	Line 406: 04-20 12:57:20.199   411   411 D NVRAM   : 
	Line 468: 04-20 12:57:21.651   411   411 D NVRAM   : NVM_GetLIDByName /mnt/vendor/nvdata/APCFG/APRDEB/PRODUCT_INFO 
	Line 469: 04-20 12:57:21.651   411   411 D NVRAM   : NVRAM: NVM_GetLIDByName Lid =61 
	Line 470: 04-20 12:57:21.652   411   411 D NVRAM   : 61 is in new nvram partition!!!
	Line 471: 04-20 12:57:21.652   411   411 D NVRAM   : New NVRAM partition name is /dev/block/platform/bootdevice/by-name/proinfo.
	Line 472: 04-20 12:57:21.652   411   411 D NVRAM   : RecNum is :1

解决方案

对这一块完全不懂,只能先去网上查查相关资料,这里要感谢大佬的分享资料,对我帮助很大

Android10.0 压力测试–恢复出厂自动测试工具
android10.0(Q) Nvram 新增节点

Nvram新增节点,遇到可读不可写的问题
问题根本原因是正常开机情况下, product info 会被 EMMC 写保护挡下 power on write protect权限问题

解决办法,注释里面的 set_write_protect()调用
vendor\mediatek\proprietary\bootable\bootloader\lk\platform\mt6771\write_protect_ab.c

diff --git a/vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6771/write_protect_ab.c b/vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6771/write_protect_ab.c
index 16f39ed8a9..d280ed1445 100755
--- a/vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6771/write_protect_ab.c
+++ b/vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6771/write_protect_ab.c
@@ -160,9 +160,9 @@ void write_protect_flow(void)
 #endif

        if (!bypass_wp) {
-               ret = set_write_protect();
+               /*ret = set_write_protect();
                if (ret != 0)
-                       pal_log_err("write protect fail! \n");
+                       pal_log_err("write protect fail! \n");*/
                pal_log_err("write protect Done! \n");
        } else
                pal_log_err("Bypass write protect! \n");

编译,刷机,可以读到sn号。

备用丶解决方案

问题到这里还没有完全结束,这种解决方案不是最完美的

int set_write_protect(void)
{
	int err = 0;
	const char *ab_suffix = NULL;
	char wp_start[WRITE_PROTECT_PARTITION_NAME_SZ] = {0};
	char wp_end[WRITE_PROTECT_PARTITION_NAME_SZ] = {0};

	ab_suffix = get_suffix();
	if (ab_suffix == NULL) {
		dprintf(CRITICAL, "[%s] invalid address.\n", __func__);
		return ERR_INVALID_ADDR;
	}

#ifdef MTK_UFS_OTP
	
	/*
	UFS OTP分区
	*所有启动模式均应考虑OTP分区是否需要锁定
	*注意:请确保在执行OTP分区锁定之前先执行其他分区。 因为我们不允许以下情况:
	*-如果当前的安全写保护配置块中已经存在OTP条目,并且OTP分区锁定请求不是第一个请求。 对于这种情况,将返回UFS_OTP_ALREADY_LOCKED
	并跳过后面的所有其他分区锁定。
	* / 
	/* 检查是否需要立即锁定OTP分区 */
	if (ufs_lk_otp_lock_req("otp") == 1) {

		pal_log_info("[%s] Lock OTP partition ... \n", __func__);

		err = partition_write_prot_set("otp", "otp", WP_PERMANENT);

		if (err != 0) {
			pal_log_err("[%s] Lock otp failed: %d\n", __func__, err);
			return err;
		}
	} else
		pal_log_info("[%s] Lock OTP is not required\n", __func__);

#endif /* MTK_UFS_OTP */

#if defined(MTK_POWER_ON_WRITE_PROTECT)
	if (g_boot_mode == NORMAL_BOOT) {
		pal_log_info("[%s] Lock boot region \n", __func__);
		err = partition_write_prot_set("preloader", "preloader", WP_POWER_ON);

		if (err != 0) {
			pal_log_err("[%s] Lock boot region failed: %d\n", __func__, err);
			return err;
		}
		snprintf(wp_start, WRITE_PROTECT_PARTITION_NAME_SZ, "sec1");
		snprintf(wp_end, WRITE_PROTECT_PARTITION_NAME_SZ, "logo");

		pal_log_info("[%s]: Lock %s->%s \n", __func__, wp_start, wp_end);
		err = partition_write_prot_set(wp_start, wp_end, WP_POWER_ON);
		if (err != 0) {
			pal_log_err("[%s]: Lock %s->%s failed:%d\n",
				    __func__, wp_start, wp_end, err);
			return err;
		}

		memset(wp_start, 0, sizeof(char) * WRITE_PROTECT_PARTITION_NAME_SZ);
		memset(wp_end, 0, sizeof(char) * WRITE_PROTECT_PARTITION_NAME_SZ);
		snprintf(wp_start, WRITE_PROTECT_PARTITION_NAME_SZ, "md1img%s", ab_suffix);
#ifdef MTK_SECURITY_SW_SUPPORT
		if (TRUE == seclib_sec_boot_enabled(TRUE))
			snprintf(wp_end, WRITE_PROTECT_PARTITION_NAME_SZ, "system%s", ab_suffix);
		else
			snprintf(wp_end, WRITE_PROTECT_PARTITION_NAME_SZ, "tee%s", ab_suffix);
#else
		snprintf(wp_end, WRITE_PROTECT_PARTITION_NAME_SZ, "tee%s", ab_suffix);
#endif
		pal_log_info("[%s]: Lock %s->%s\n", __func__, wp_start, wp_end);
		err = partition_write_prot_set(wp_start, wp_end, WP_POWER_ON);
		if (err != 0) {
			pal_log_err("[%s]: Lock %s->%s failed:%d\n",
				    __func__, wp_start, wp_end, err);
			return err;
		}
	}

	pal_log_info("[%s] Lock seccfg\n", __func__);
	err = partition_write_prot_set("seccfg", "seccfg", WP_POWER_ON);
	if (err != 0) {
		pal_log_err("[%s]: Lock seccfg failed:%d\n", __func__, err);
		return err;
	}

#endif
	return 0;
}

阅读源码,分析一下set_write_protect()方法的逻辑,partition_write_prot_set(wp_start, wp_end, WP_POWER_ON)方法去设置分区的写保护,从wp_start分区到wp_end分区,代码中设置了sec1分区到logo分区的写保护

找到分区的表格,proinfo和nvram都在写保护的区间中
\device\mediatek\build\build\tools\ptgen\MT6771\partition_table_MT6771_emmc.csv
在这里插入图片描述根据代码逻辑,我们缩小写保护分区的大小

diff --git a/vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6771/write_protect_ab.c b/vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6771/write_protect_ab.c
index 23ff5f93e7..16f39ed8a9 100755
--- a/vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6771/write_protect_ab.c
+++ b/vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6771/write_protect_ab.c
@@ -102,9 +102,10 @@ int set_write_protect(void)
                        pal_log_err("[%s] Lock boot region failed: %d\n", __func__, err);
                        return err;
                }
-               snprintf(wp_start, WRITE_PROTECT_PARTITION_NAME_SZ, "sec1");
-               snprintf(wp_end, WRITE_PROTECT_PARTITION_NAME_SZ, "logo");
+               snprintf(wp_start, WRITE_PROTECT_PARTITION_NAME_SZ, "efuse");
+               snprintf(wp_end, WRITE_PROTECT_PARTITION_NAME_SZ, "nvram");

                pal_log_info("[%s]: Lock %s->%s \n", __func__, wp_start, wp_end);
                err = partition_write_prot_set(wp_start, wp_end, WP_POWER_ON);

编译,刷机,写sn号成功。
在已有解决方案的基础上,进一步分析源码,理清代码逻辑,寻找其他解决方案,能加快能力的提升。

注:我修改的是write_protect_ab.c文件,而不是write_protect.c文件,是因为该项目开启了a/b分区。
没有开启a/b分区的,还是应该修改write_protect.c文件。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android框架中,NVRAM(非易失性随机存储器)被用于存储系统相关的配置和参数,如无线通信模块的MAC地址、IMEI码等。NVRAM的读Android设备的系统级别中发挥重要作用。 首先,NVRAM读取功能在Android框架中由系统服务提供,通过封装底层的硬件接口和驱动程序来实现。Android的系统服务负责与硬件之间的通信,从NVRAM中读取所需的参数。在读取过程中,通过定义和使用适当的API,应用程序或系统组件可以请求读取特定的NVRAM值,以进行相关的操作和功能。 其次,NVRAM的入功能也是由系统服务提供的。当应用程序或系统组件需要修改某个NVRAM参数时,可以通过调用相应的API来实现。系统服务将接收到的修改请求转发给硬件接口和驱动程序,然后将新值入NVRAM中。这样,NVRAM中对应的参数将被更新,以满足新的需求。 在Android框架中,NVRAM读功能的正确实现对于系统的正常运行非常重要。它确保各种系统组件可以正确访问配置和参数信息,并确保设备在启动时能够正确初始化。同时,NVRAM的读操作需要受到适当的权限控制,只有具备足够权限的应用程序或系统组件才能进行相关的操作。 综上所述,Android框架中的NVRAM读功能通过系统服务提供,并且在系统级别中发挥重要作用。这种功能确保了系统配置和参数的正确访问和修改,从而保障设备的正常运行。

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值