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>
This commit is contained in:
parent
cd9e6099e8
commit
b1bbc431c3
39
fel.c
39
fel.c
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user