Rockchip | Rockchip U-Boot命令判断存储器是否有RK固件

Posted Neutionwei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Rockchip | Rockchip U-Boot命令判断存储器是否有RK固件相关的知识,希望对你有一定的参考价值。

一、源文件

./cmd/rkimgtest.c

/*
 * (C) Copyright 2019 Rockchip Electronics Co., Ltd
 *
 * SPDX-License-Identifier:     GPL-2.0+
 */

#include <common.h>
#include <malloc.h>

static int do_rkimg_test(cmd_tbl_t *cmdtp, int flag,
			 int argc, char *const argv[])
{
	struct blk_desc *dev_desc;
	u32 *buffer;
	int ret;

	if (argc != 3)
		return CMD_RET_USAGE;

	dev_desc = blk_get_dev(argv[1], simple_strtoul(argv[2], NULL, 16));
	if (!dev_desc) {
		printf("%s: dev_desc is NULL!\\n", __func__);
		return CMD_RET_FAILURE;
	}

	/* read one block from beginning of IDB data */
	buffer = memalign(ARCH_DMA_MINALIGN, 1024);
	ret = blk_dread(dev_desc, 64, 2, buffer);
	if (ret != 2) {
		printf("%s: Failed to read data from IDB\\n", __func__);
		free(buffer);
		return CMD_RET_FAILURE;
	}

	if (buffer[0] == 0xFCDC8C3B) {
		ret = CMD_RET_SUCCESS;

		if (!strcmp("mmc", argv[1]))
			printf("Found IDB in SDcard\\n");
		else
			printf("Found IDB in U-disk\\n");

		/* TAG in IDB */
		if (0 == buffer[128 + 104 / 4]) {
			if (!strcmp("mmc", argv[1]))
				env_update("bootargs", "sdfwupdate");
			else
				env_update("bootargs", "usbfwupdate");
		}
	} else if (buffer[0] == 0x534e4b52 || buffer[0] == 0x534e5252) {
		/* The 0x534e4b52 & 0x534e5252 are the new idb block header tag */
		ret = CMD_RET_SUCCESS;
	} else {
		ret = CMD_RET_FAILURE;
	}

	free(buffer);

	return ret;
}

U_BOOT_CMD(
	rkimgtest, 3, 0,    do_rkimg_test,
	"Test if storage media have rockchip image",
	"<devtype> <devnum>"
);

二、使用方法

例如判断eMMC存储器是否有RK固件:

=> rkimgtest mmc 0

三、原理

rkimgtest命令判断存储器是否有RK固件其实是判断根据存储器的第64个块是否存在IDB data

	/* read one block from beginning of IDB data */
	buffer = memalign(ARCH_DMA_MINALIGN, 1024);
	ret = blk_dread(dev_desc, 64, 2, buffer);
	if (ret != 2) {
		printf("%s: Failed to read data from IDB\\n", __func__);
		free(buffer);
		return CMD_RET_FAILURE;
	}

IDB data被定义为0xFCDC8C3B0x534e4b520x534e5252

	if (buffer[0] == 0xFCDC8C3B) {
		ret = CMD_RET_SUCCESS;
		...
	} else if (buffer[0] == 0x534e4b52 || buffer[0] == 0x534e5252) {
		/* The 0x534e4b52 & 0x534e5252 are the new idb block header tag */
		ret = CMD_RET_SUCCESS;
	} else {
		ret = CMD_RET_FAILURE;
	}

例如以下是RK356x固件的十六进制信息:

$ hexdump -C fw.img |less
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000001c0  00 00 ee 00 00 00 01 00  00 00 ff ff ff ff 00 00  |................|
000001d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|
00000200  45 46 49 20 50 41 52 54  00 00 01 00 5c 00 00 00  |EFI PART....\\...|
00000210  ff 34 32 cd 00 00 00 00  01 00 00 00 00 00 00 00  |.42.............|
00000220  fe ff ff ff 00 00 00 00  22 00 00 00 00 00 00 00  |........".......|
00000230  dd ff ff ff 00 00 00 00  6b 7b 98 73 74 49 94 4c  |........k{.stI.L|
00000240  a3 e8 58 ab 2e b7 a9 46  02 00 00 00 00 00 00 00  |..X....F........|
00000250  80 00 00 00 80 00 00 00  47 c4 3f 3d 00 00 00 00  |........G.?=....|
00000260  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000400  51 d0 08 f8 02 16 cd 4d  94 52 f9 63 7f ef c4 9a  |Q......M.R.c....|
00000410  4e e4 50 b7 3f 83 30 4a  c3 8c b1 17 24 1d 84 d4  |N.P.?.0J....$...|
00000420  00 40 00 00 00 00 00 00  ff 5f 00 00 00 00 00 00  |.@......._......|
00000430  00 00 00 00 00 00 00 00  75 00 62 00 6f 00 6f 00  |........u.b.o.o.|
                                   u NUT b NUT o NUT o NUT
00000440  74 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |t...............|
00000450  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00008000  52 4b 4e 53 00 00 00 00  80 01 02 00 01 00 00 00  |RKNS............|
00008010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*

我们看0x8000地址这一行:

00008000  52 4b 4e 53 00 00 00 00  80 01 02 00 01 00 00 00  |RKNS............|

按照小端模式,这里的开头的数据为0x534e4b52,对应字符数据为RKNS,其实这里就对应源代码中的buffer[0] == 0x534e4b52,那为什么是0x8000地址呢?
我们知道一个块是512字节,所以64 × 512 = 32768 = 0x8000,注意一个地址存储一个字节数据,一个字节为8bit,最大为0xff。

以上是关于Rockchip | Rockchip U-Boot命令判断存储器是否有RK固件的主要内容,如果未能解决你的问题,请参考以下文章

Rockchip | Rockchip Graphics与Display

Rockchip | Rockchip平台SD卡启动idbloader.img打包

Rockchip | Rockchip原始固件与RK固件格式

Rockchip | Rockchip U-Boot命令判断存储器是否有RK固件

RockChip主板系统签名说明

RockChip主板系统签名说明