diff options
author | Maxime Ripard <maxime.ripard@free-electrons.com> | 2017-11-06 13:37:38 +0300 |
---|---|---|
committer | Maxime Ripard <maxime.ripard@free-electrons.com> | 2017-11-06 13:42:35 +0300 |
commit | b1bbc431c33652ba670a6b23d773f220a7b5765f (patch) | |
tree | 71dc7dc438a3516cd3e333dd7c9dbca14b0b6b6a /fel.c | |
parent | cd9e6099e8668f4aa25d3ffc71283c0b138af1b7 (diff) |
fel: Use U-Boot's header structure
The U-Boot image parsing code so far has been relying on hardcoded offsets
directly into the image's buffer.
While that works, it's a bit obscure and isn't practical to understand and
modify.
Let's add the structure definition, and convert the code to use it.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Diffstat (limited to 'fel.c')
-rw-r--r-- | fel.c | 39 |
1 files changed, 30 insertions, 9 deletions
@@ -48,8 +48,28 @@ static uint32_t uboot_size = 0; /* size of U-Boot binary */ /* Additional error codes, newly introduced for get_image_type() */ #define IH_TYPE_ARCH_MISMATCH -1 -#define HEADER_NAME_OFFSET 32 /* offset of name field */ -#define HEADER_SIZE (HEADER_NAME_OFFSET + IH_NMLEN) +/* + * Legacy format image U-Boot header, + * all data in network byte order (aka natural aka bigendian). + * Taken from ${U-BOOT}/include/image.h + */ +typedef struct image_header { + uint32_t ih_magic; /* Image Header Magic Number */ + uint32_t ih_hcrc; /* Image Header CRC Checksum */ + uint32_t ih_time; /* Image Creation Timestamp */ + uint32_t ih_size; /* Image Data Size */ + uint32_t ih_load; /* Data Load Address */ + uint32_t ih_ep; /* Entry Point Address */ + uint32_t ih_dcrc; /* Image Data CRC Checksum */ + uint8_t ih_os; /* Operating System */ + uint8_t ih_arch; /* CPU architecture */ + uint8_t ih_type; /* Image Type */ + uint8_t ih_comp; /* Compression Type */ + uint8_t ih_name[IH_NMLEN]; /* Image Name */ +} image_header_t; + +#define HEADER_NAME_OFFSET offsetof(image_header_t, ih_name) +#define HEADER_SIZE sizeof(image_header_t) /* * Utility function to determine the image type from a mkimage-compatible @@ -63,18 +83,19 @@ static uint32_t uboot_size = 0; /* size of U-Boot binary */ */ int get_image_type(const uint8_t *buf, size_t len) { - uint32_t *buf32 = (uint32_t *)buf; + image_header_t *hdr = (image_header_t *)buf; if (len <= HEADER_SIZE) /* insufficient length/size */ return IH_TYPE_INVALID; - if (be32toh(buf32[0]) != IH_MAGIC) /* signature mismatch */ + + if (be32toh(hdr->ih_magic) != IH_MAGIC) /* signature mismatch */ return IH_TYPE_INVALID; /* For sunxi, we always expect ARM architecture here */ - if (buf[29] != IH_ARCH_ARM) + if (hdr->ih_arch != IH_ARCH_ARM) return IH_TYPE_ARCH_MISMATCH; /* assume a valid header, and return ih_type */ - return buf[30]; + return hdr->ih_type; } void aw_fel_print_version(feldev_handle *dev) @@ -740,7 +761,7 @@ void aw_fel_write_uboot_image(feldev_handle *dev, uint8_t *buf, size_t len) if (len <= HEADER_SIZE) return; /* Insufficient size (no actual data), just bail out */ - uint32_t *buf32 = (uint32_t *)buf; + image_header_t hdr = *(image_header_t *)buf; /* Check for a valid mkimage header */ int image_type = get_image_type(buf, len); @@ -762,8 +783,8 @@ void aw_fel_write_uboot_image(feldev_handle *dev, uint8_t *buf, size_t len) pr_fatal("U-Boot image type mismatch: " "expected IH_TYPE_FIRMWARE, got %02X\n", image_type); - uint32_t data_size = be32toh(buf32[3]); /* Image Data Size */ - uint32_t load_addr = be32toh(buf32[4]); /* Data Load Address */ + uint32_t data_size = be32toh(hdr.ih_size); /* Image Data Size */ + uint32_t load_addr = be32toh(hdr.ih_load); /* Data Load Address */ if (data_size != len - HEADER_SIZE) pr_fatal("U-Boot image data size mismatch: " "expected %zu, got %u\n", len - HEADER_SIZE, data_size); |