Unverified Commit b1bbc431 authored by Maxime Ripard's avatar Maxime Ripard
Browse files

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: default avatarMaxime Ripard <maxime.ripard@free-electrons.com>
parent cd9e6099
...@@ -48,8 +48,28 @@ static uint32_t uboot_size = 0; /* size of U-Boot binary */ ...@@ -48,8 +48,28 @@ static uint32_t uboot_size = 0; /* size of U-Boot binary */
/* Additional error codes, newly introduced for get_image_type() */ /* Additional error codes, newly introduced for get_image_type() */
#define IH_TYPE_ARCH_MISMATCH -1 #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 * 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 */ ...@@ -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) 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 */ if (len <= HEADER_SIZE) /* insufficient length/size */
return IH_TYPE_INVALID; 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; return IH_TYPE_INVALID;
/* For sunxi, we always expect ARM architecture here */ /* 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; return IH_TYPE_ARCH_MISMATCH;
/* assume a valid header, and return ih_type */ /* assume a valid header, and return ih_type */
return buf[30]; return hdr->ih_type;
} }
void aw_fel_print_version(feldev_handle *dev) 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) ...@@ -740,7 +761,7 @@ void aw_fel_write_uboot_image(feldev_handle *dev, uint8_t *buf, size_t len)
if (len <= HEADER_SIZE) if (len <= HEADER_SIZE)
return; /* Insufficient size (no actual data), just bail out */ 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 */ /* Check for a valid mkimage header */
int image_type = get_image_type(buf, len); 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) ...@@ -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: " pr_fatal("U-Boot image type mismatch: "
"expected IH_TYPE_FIRMWARE, got %02X\n", image_type); "expected IH_TYPE_FIRMWARE, got %02X\n", image_type);
uint32_t data_size = be32toh(buf32[3]); /* Image Data Size */ uint32_t data_size = be32toh(hdr.ih_size); /* Image Data Size */
uint32_t load_addr = be32toh(buf32[4]); /* Data Load Address */ uint32_t load_addr = be32toh(hdr.ih_load); /* Data Load Address */
if (data_size != len - HEADER_SIZE) if (data_size != len - HEADER_SIZE)
pr_fatal("U-Boot image data size mismatch: " pr_fatal("U-Boot image data size mismatch: "
"expected %zu, got %u\n", len - HEADER_SIZE, data_size); "expected %zu, got %u\n", len - HEADER_SIZE, data_size);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment