2014-04-12 21:21:14 +00:00
|
|
|
From 43b9a7c9b903302c56d0a1d292a146dbf4de8e49 Mon Sep 17 00:00:00 2001
|
|
|
|
From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
|
|
|
|
Date: Mon, 12 Aug 2013 01:17:08 +0200
|
|
|
|
Subject: tools: lantiq: add NAND SPL support
|
|
|
|
|
|
|
|
Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
|
|
|
|
|
|
|
|
--- a/tools/ltq-boot-image.c
|
|
|
|
+++ b/tools/ltq-boot-image.c
|
|
|
|
@@ -14,7 +14,8 @@
|
|
|
|
|
|
|
|
enum image_types {
|
|
|
|
IMAGE_NONE,
|
|
|
|
- IMAGE_SFSPL
|
|
|
|
+ IMAGE_SFSPL,
|
|
|
|
+ IMAGE_NANDSPL
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Lantiq non-volatile bootstrap command IDs */
|
|
|
|
@@ -43,6 +44,8 @@ enum nvb_cmd_flags {
|
|
|
|
struct args {
|
|
|
|
enum image_types type;
|
|
|
|
__u32 entry_addr;
|
2017-01-25 07:29:14 +00:00
|
|
|
+ off_t uboot_offset;
|
2014-04-12 21:21:14 +00:00
|
|
|
+ unsigned int page_size;
|
|
|
|
const char *uboot_bin;
|
|
|
|
const char *spl_bin;
|
|
|
|
const char *out_bin;
|
|
|
|
@@ -50,10 +53,11 @@ struct args {
|
|
|
|
|
|
|
|
static void usage_msg(const char *name)
|
|
|
|
{
|
|
|
|
- fprintf(stderr, "%s: [-h] -t type -e entry-addr -u uboot-bin [-s spl-bin] -o out-bin\n",
|
|
|
|
+ fprintf(stderr, "%s: [-h] -t type -e entry-addr [-x uboot-offset] [-p page-size] -u uboot-bin [-s spl-bin] -o out-bin\n",
|
|
|
|
name);
|
|
|
|
fprintf(stderr, " Image types:\n"
|
|
|
|
- " sfspl - SPL + [compressed] U-Boot for SPI flash\n");
|
|
|
|
+ " sfspl - SPL + [compressed] U-Boot for SPI flash\n"
|
|
|
|
+ " nandspl - SPL + [compressed] U-Boot for NAND flash\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
static enum image_types parse_image_type(const char *type)
|
2014-04-22 08:08:19 +00:00
|
|
|
@@ -64,6 +68,9 @@ static enum image_types parse_image_type
|
2014-04-12 21:21:14 +00:00
|
|
|
if (!strncmp(type, "sfspl", 6))
|
|
|
|
return IMAGE_SFSPL;
|
|
|
|
|
|
|
|
+ if (!strncmp(type, "nandspl", 6))
|
|
|
|
+ return IMAGE_NANDSPL;
|
|
|
|
+
|
|
|
|
return IMAGE_NONE;
|
|
|
|
}
|
|
|
|
|
2014-04-22 08:08:19 +00:00
|
|
|
@@ -73,7 +80,7 @@ static int parse_args(int argc, char *ar
|
2014-04-12 21:21:14 +00:00
|
|
|
|
|
|
|
memset(arg, 0, sizeof(*arg));
|
|
|
|
|
|
|
|
- while ((opt = getopt(argc, argv, "ht:e:u:s:o:")) != -1) {
|
|
|
|
+ while ((opt = getopt(argc, argv, "ht:e:x:p:u:s:o:")) != -1) {
|
|
|
|
switch (opt) {
|
|
|
|
case 'h':
|
|
|
|
usage_msg(argv[0]);
|
2014-04-22 08:08:19 +00:00
|
|
|
@@ -84,6 +91,12 @@ static int parse_args(int argc, char *ar
|
2014-04-12 21:21:14 +00:00
|
|
|
case 'e':
|
|
|
|
arg->entry_addr = strtoul(optarg, NULL, 16);
|
|
|
|
break;
|
|
|
|
+ case 'x':
|
|
|
|
+ arg->uboot_offset = strtoul(optarg, NULL, 16);
|
|
|
|
+ break;
|
|
|
|
+ case 'p':
|
|
|
|
+ arg->page_size = strtoul(optarg, NULL, 10);
|
|
|
|
+ break;
|
|
|
|
case 'u':
|
|
|
|
arg->uboot_bin = optarg;
|
|
|
|
break;
|
2014-04-22 08:08:19 +00:00
|
|
|
@@ -114,11 +127,22 @@ static int parse_args(int argc, char *ar
|
2014-04-12 21:21:14 +00:00
|
|
|
goto parse_error;
|
|
|
|
}
|
|
|
|
|
|
|
|
- if (arg->type == IMAGE_SFSPL && !arg->spl_bin) {
|
|
|
|
+ if ((arg->type == IMAGE_SFSPL || arg->type == IMAGE_NANDSPL) &&
|
|
|
|
+ !arg->spl_bin) {
|
|
|
|
fprintf(stderr, "Missing SPL binary\n");
|
|
|
|
goto parse_error;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ if (arg->type == IMAGE_NANDSPL && !arg->uboot_offset) {
|
|
|
|
+ fprintf(stderr, "Missing U-Boot offset\n");
|
|
|
|
+ goto parse_error;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (arg->type == IMAGE_NANDSPL && !arg->page_size) {
|
|
|
|
+ fprintf(stderr, "Missing NAND page size\n");
|
|
|
|
+ goto parse_error;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
parse_error:
|
2014-04-22 08:08:19 +00:00
|
|
|
@@ -174,6 +198,19 @@ static int write_nvb_start_header(int fd
|
2014-04-12 21:21:14 +00:00
|
|
|
return write_header(fd, hdr, sizeof(hdr));
|
|
|
|
}
|
|
|
|
|
|
|
|
+#if 0
|
|
|
|
+static int write_nvb_regcfg_header(int fd, __u32 addr)
|
|
|
|
+{
|
|
|
|
+ __u32 hdr[2];
|
|
|
|
+
|
|
|
|
+ hdr[0] = build_nvb_command(NVB_CMD_REGCFG, NVB_FLAG_SDBG |
|
|
|
|
+ NVB_FLAG_DBG);
|
|
|
|
+ hdr[1] = cpu_to_be32(addr);
|
|
|
|
+
|
|
|
|
+ return write_header(fd, hdr, sizeof(hdr));
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
static int open_input_bin(const char *name, void **ptr, size_t *size)
|
|
|
|
{
|
|
|
|
struct stat sbuf;
|
2014-04-22 08:08:19 +00:00
|
|
|
@@ -238,9 +275,37 @@ static int open_output_bin(const char *n
|
2014-04-12 21:21:14 +00:00
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
-static int create_sfspl(const struct args *arg)
|
2017-01-25 07:29:14 +00:00
|
|
|
+static int pad_to_offset(int fd, off_t offset)
|
2014-04-12 21:21:14 +00:00
|
|
|
{
|
|
|
|
- int out_fd, uboot_fd, spl_fd, ret;
|
2017-01-25 07:29:14 +00:00
|
|
|
+ off_t pos;
|
2014-04-12 21:21:14 +00:00
|
|
|
+ size_t size;
|
|
|
|
+ ssize_t n;
|
|
|
|
+ __u8 *buf;
|
|
|
|
+
|
|
|
|
+ pos = lseek(fd, 0, SEEK_CUR);
|
|
|
|
+ size = offset - pos;
|
|
|
|
+
|
|
|
|
+ buf = malloc(size);
|
|
|
|
+ if (!buf) {
|
|
|
|
+ fprintf(stderr, "Failed to malloc buffer\n");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ memset(buf, 0xff, size);
|
|
|
|
+ n = write(fd, buf, size);
|
|
|
|
+ free(buf);
|
|
|
|
+
|
|
|
|
+ if (n != size) {
|
|
|
|
+ fprintf(stderr, "Failed to write pad bytes\n");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int create_spl_image(const struct args *arg)
|
|
|
|
+{
|
|
|
|
+ int out_fd, uboot_fd, spl_fd, ret = 0;
|
|
|
|
void *uboot_ptr, *spl_ptr;
|
|
|
|
size_t uboot_size, spl_size;
|
|
|
|
|
2014-04-22 08:08:19 +00:00
|
|
|
@@ -256,9 +321,22 @@ static int create_sfspl(const struct arg
|
2014-04-12 21:21:14 +00:00
|
|
|
if (0 > uboot_fd)
|
|
|
|
goto err_uboot;
|
|
|
|
|
|
|
|
+#if 0
|
|
|
|
+ ret = write_nvb_regcfg_header(out_fd, 0);
|
|
|
|
+ if (ret)
|
|
|
|
+ goto err_write;
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
ret = write_nvb_dwnld_header(out_fd, spl_size, arg->entry_addr);
|
|
|
|
if (ret)
|
|
|
|
goto err_write;
|
|
|
|
+#if 0
|
|
|
|
+ if (arg->page_size) {
|
|
|
|
+ ret = pad_to_offset(out_fd, arg->page_size);
|
|
|
|
+ if (ret)
|
|
|
|
+ goto err_write;
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
|
|
|
|
ret = copy_bin(out_fd, spl_ptr, spl_size);
|
|
|
|
if (ret)
|
2014-04-22 08:08:19 +00:00
|
|
|
@@ -268,16 +346,16 @@ static int create_sfspl(const struct arg
|
2014-04-12 21:21:14 +00:00
|
|
|
if (ret)
|
|
|
|
goto err_write;
|
|
|
|
|
|
|
|
+ if (arg->uboot_offset) {
|
|
|
|
+ ret = pad_to_offset(out_fd, arg->uboot_offset);
|
|
|
|
+ if (ret)
|
|
|
|
+ goto err_write;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
ret = copy_bin(out_fd, uboot_ptr, uboot_size);
|
|
|
|
if (ret)
|
|
|
|
goto err_write;
|
|
|
|
|
|
|
|
- close_input_bin(uboot_fd, uboot_ptr, uboot_size);
|
|
|
|
- close_input_bin(spl_fd, spl_ptr, spl_size);
|
|
|
|
- close(out_fd);
|
|
|
|
-
|
|
|
|
- return 0;
|
|
|
|
-
|
|
|
|
err_write:
|
|
|
|
close_input_bin(uboot_fd, uboot_ptr, uboot_size);
|
|
|
|
err_uboot:
|
|
|
|
@@ -285,7 +363,7 @@ err_uboot:
|
|
|
|
err_spl:
|
|
|
|
close(out_fd);
|
|
|
|
err:
|
|
|
|
- return -1;
|
|
|
|
+ return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
|
|
@@ -299,7 +377,8 @@ int main(int argc, char *argv[])
|
|
|
|
|
|
|
|
switch (arg.type) {
|
|
|
|
case IMAGE_SFSPL:
|
|
|
|
- ret = create_sfspl(&arg);
|
|
|
|
+ case IMAGE_NANDSPL:
|
|
|
|
+ ret = create_spl_image(&arg);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
fprintf(stderr, "Image type not implemented\n");
|