瀏覽代碼

spl_tool: Add parse_args function and update usage.

Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
Samin Guo 1 年之前
父節點
當前提交
fd67300a93
共有 1 個文件被更改,包括 116 次插入21 次删除
  1. 116 21
      spl_tool/jh7110_uboot_spl.c

+ 116 - 21
spl_tool/jh7110_uboot_spl.c

@@ -2,10 +2,12 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <getopt.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
 #include <string.h>
+#include <stdbool.h>
 #include <unistd.h>
 #include <endian.h>
 #include <errno.h>
@@ -18,23 +20,32 @@ extern uint32_t crc32_final(uint32_t iv);
 
 /* all uint32_t ends up little endian in output header */
 struct __attribute__((__packed__)) ubootsplhdr {
-	uint32_t sofs;		/* offset of "second?" header: 0x240, dunno */
+	uint32_t sofs;		/* offset of spl header: 64+256+256 = 0x240 */
 	uint32_t bofs;		/* SBL_BAK_OFFSET: Offset of backup SBL from Flash info start (from input_sbl_normal.cfg) */
 	uint8_t  zro2[636];
 	uint32_t vers;		/* version: shall be 0x01010101
 				 * (from https://doc-en.rvspace.org/VisionFive2/SWTRM/VisionFive2_SW_TRM/create_spl.html) */
 	uint32_t fsiz;		/* u-boot-spl.bin size in bytes */
-	uint32_t res1;		/* unknown, 0x400 (00 04 00 00) currently */
+	uint32_t res1;		/* Offset from HDR to SPL_IMAGE, 0x400 (00 04 00 00) currently */
 	uint32_t crcs;		/* CRC32 of u-boot-spl.bin */
 	uint8_t  zro3[364];
 };
 
+struct hdr_conf_t {
+	const char name[PATH_MAX];
+	uint32_t vers;
+	uint32_t bofs;
+	bool creat_hdr_flag;
+};
+
 static struct ubootsplhdr ubsplhdr;
+static struct hdr_conf_t g_hdr_conf;
 
 static char ubootspl[131072-sizeof(struct ubootsplhdr)+1];
 static char outpath[PATH_MAX];
 
 #define DEFVERSID 0x01010101
+#define DEFBACKUP 0x200000U
 
 static void xerror(int errnoval, const char *s)
 {
@@ -45,44 +56,123 @@ static void xerror(int errnoval, const char *s)
 
 static void usage(void)
 {
-	printf("usage: jh7110_uboot_spl u-boot-spl.bin [version]\n");
-	printf("u-boot-spl.bin is path to input U-Boot SPL file\n");
-	printf("if version specified, shall be 0x01010101\n");
-	printf("output will be written to u-boot-spl.bin.out\n");
-	exit(1);
+	const char help[] = {
+		"\n            StarFive spl tool\n\n"
+		"usage:\n"
+		"-c, --creat-splhdr	creat spl hdr\n"
+		"-a, --spl-bak-addr	set backup SPL addr(default: 0x200000)\n"
+		"-v, --version		set version (default: 0x01010101)\n"
+		"-f, --file		input file name(spl/img)\n"
+		"-h, --help		show this information\n"
+	};
+	puts(help);
 }
 
-int main(int argc, char **argv)
+static int parse_args(int argc, char **argv)
+{
+	uint32_t v;
+
+	enum {
+		OPTION_CREAD_HDR = 1,
+		OPTION_SBL_BAK_OFFSET,
+		OPTION_VERSION,
+		OPTION_FILENAME,
+		OPTION_HELP,
+	};
+
+	static struct option long_options[] =
+	{
+		{"creat-splhdr" , no_argument, NULL, OPTION_CREAD_HDR},
+		{"spl-bak-addr" , required_argument, NULL, OPTION_SBL_BAK_OFFSET},
+		{"version", required_argument, NULL, OPTION_VERSION},
+		{"file", required_argument, NULL, OPTION_FILENAME},
+		{"help", no_argument, NULL, OPTION_HELP},
+		{0, 0, 0, 0}
+	};
+
+	while (1)
+	{
+		/* getopt_long stores the option index here. */
+		int option_index = 0;
+
+		int c = getopt_long(argc, argv, "cio:v:f:h", long_options, &option_index);
+
+		/* Detect the end of the options. */
+		if (c == -1)
+		    break;
+
+		switch (c) {
+		case 0:
+			/* If this option set a flag, do nothing else now. */
+			if (long_options[option_index].flag != 0)
+			break;
+
+		case 'c':
+		case OPTION_CREAD_HDR:
+			g_hdr_conf.creat_hdr_flag = true;
+			break;
+
+		case 'a':
+		case OPTION_SBL_BAK_OFFSET:
+			v = (uint32_t)strtoul(optarg, NULL, 16);
+			v = htole32(v);
+			g_hdr_conf.bofs = v;
+			break;
+
+		case 'v':
+		case OPTION_VERSION:
+			v = (uint32_t)strtoul(optarg, NULL, 16);
+			v = htole32(v);
+			g_hdr_conf.vers = v;
+			break;
+
+		case 'f':
+		case OPTION_FILENAME:
+			strcpy((char*)g_hdr_conf.name, optarg);
+			break;
+
+		case 'h':
+		case OPTION_HELP:
+			usage();
+			break;
+
+		default:
+			usage();
+			break;
+		}
+	}
+	return 0;
+}
+
+int spl_creat_hdr(struct hdr_conf_t *conf)
 {
 	int fd;
 	uint32_t v;
 	size_t sz;
 
-	if (argc < 2) usage();
-
-	fd = open(argv[1], O_RDONLY);
-	if (fd == -1) xerror(errno, argv[1]);
+	if (!conf->creat_hdr_flag)
+		return 0;
 
 	ubsplhdr.sofs = htole32(0x240U);
-	ubsplhdr.bofs = htole32(0x200000U);
 	ubsplhdr.res1 = htole32(0x400U);
+	ubsplhdr.bofs = conf->bofs ? conf->bofs : htole32(DEFBACKUP);
+	ubsplhdr.vers = conf->vers ? conf->vers : htole32(DEFVERSID);
 
-	if (argc >= 3) {
-		v = (uint32_t)strtoul(argv[2], NULL, 16);
-		v = htole32(v);
-		ubsplhdr.vers = v;
-	}
-	else ubsplhdr.vers = htole32(DEFVERSID);
+	printf("ubsplhdr.sofs:%#x, ubsplhdr.bofs:%#x, ubsplhdr.vers:%#x name:%s\n",
+		ubsplhdr.sofs, ubsplhdr.bofs, ubsplhdr.vers, conf->name);
+
+	fd = open(conf->name, O_RDONLY);
+	if (fd == -1) xerror(errno, conf->name);
 
 	sz = (size_t)read(fd, ubootspl, sizeof(ubootspl));
-	if (sz == NOSIZE) xerror(errno, argv[1]);
+	if (sz == NOSIZE) xerror(errno, conf->name);
 	if (sz >= (sizeof(ubootspl)))
 		xerror(0, "File too large! Please rebuild your SPL with -Os. Maximum allowed size is 130048 bytes.");
 	v = htole32((uint32_t)sz);
 	ubsplhdr.fsiz = v;
 
 	close(fd);
-	snprintf(outpath, sizeof(outpath), "%s.out", argv[1]);
+	snprintf(outpath, sizeof(outpath), "%s.normal.out", conf->name);
 	fd = creat(outpath, 0666);
 	if (fd == -1) xerror(errno, outpath);
 
@@ -100,3 +190,8 @@ int main(int argc, char **argv)
 
 	return 0;
 }
+int main(int argc, char **argv)
+{
+	parse_args(argc, argv);
+	spl_creat_hdr(&g_hdr_conf);
+}