X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=include%2Fimage.h;h=c31e862d32252da2bb2356e0f8e6d3f32af0344a;hb=2f795ac74eceea36199f07b385d2c85f61396a04;hp=aab3f44ccbfb0c97859227368abd7784411dd841;hpb=559316faf7eae0614c91d77f509b57d6c4c091ba;p=u-boot diff --git a/include/image.h b/include/image.h index aab3f44ccb..c31e862d32 100644 --- a/include/image.h +++ b/include/image.h @@ -33,9 +33,29 @@ #ifndef __IMAGE_H__ #define __IMAGE_H__ -#include -#ifndef USE_HOSTCC -#include +#include "compiler.h" + +#ifdef USE_HOSTCC + +/* new uImage format support enabled on host */ +#define CONFIG_FIT 1 +#define CONFIG_OF_LIBFDT 1 +#define CONFIG_FIT_VERBOSE 1 /* enable fit_format_{error,warning}() */ + +#else + +#include +#include +#include + +#endif /* USE_HOSTCC */ + +#if defined(CONFIG_FIT) +#include +#include +#include +#define CONFIG_MD5 /* FIT images need MD5 support */ +#define CONFIG_SHA1 /* and SHA1 */ #endif /* @@ -62,6 +82,8 @@ #define IH_OS_RTEMS 18 /* RTEMS */ #define IH_OS_ARTOS 19 /* ARTOS */ #define IH_OS_UNITY 20 /* Unity OS */ +#define IH_OS_INTEGRITY 21 /* INTEGRITY */ +#define IH_OS_OSE 22 /* OSE */ /* * CPU Architecture Codes (supported by Linux) @@ -79,7 +101,6 @@ #define IH_ARCH_SPARC 10 /* Sparc */ #define IH_ARCH_SPARC64 11 /* Sparc 64 Bit */ #define IH_ARCH_M68K 12 /* M68K */ -#define IH_ARCH_NIOS 13 /* Nios-32 */ #define IH_ARCH_MICROBLAZE 14 /* MicroBlaze */ #define IH_ARCH_NIOS2 15 /* Nios-II */ #define IH_ARCH_BLACKFIN 16 /* Blackfin */ @@ -134,6 +155,8 @@ #define IH_TYPE_SCRIPT 6 /* Script file */ #define IH_TYPE_FILESYSTEM 7 /* Filesystem Image (any type) */ #define IH_TYPE_FLATDT 8 /* Binary Flat Device Tree Blob */ +#define IH_TYPE_KWBIMAGE 9 /* Kirkwood Boot Image */ +#define IH_TYPE_IMXIMAGE 10 /* Freescale IMXBoot Image */ /* * Compression Types @@ -141,14 +164,16 @@ #define IH_COMP_NONE 0 /* No Compression Used */ #define IH_COMP_GZIP 1 /* gzip Compression Used */ #define IH_COMP_BZIP2 2 /* bzip2 Compression Used */ +#define IH_COMP_LZMA 3 /* lzma Compression Used */ +#define IH_COMP_LZO 4 /* lzo Compression Used */ #define IH_MAGIC 0x27051956 /* Image Magic Number */ #define IH_NMLEN 32 /* Image Name Length */ /* - * all data in network byte order (aka natural aka bigendian) + * Legacy format image header, + * all data in network byte order (aka natural aka bigendian). */ - typedef struct image_header { uint32_t ih_magic; /* Image Header Magic Number */ uint32_t ih_hcrc; /* Image Header CRC Checksum */ @@ -164,114 +189,298 @@ typedef struct image_header { uint8_t ih_name[IH_NMLEN]; /* Image Name */ } image_header_t; +typedef struct image_info { + ulong start, end; /* start/end of blob */ + ulong image_start, image_len; /* start of image within blob, len of image */ + ulong load; /* load addr for the image */ + uint8_t comp, type, os; /* compression, type of image, os type */ +} image_info_t; + +/* + * Legacy and FIT format headers used by do_bootm() and do_bootm_() + * routines. + */ +typedef struct bootm_headers { + /* + * Legacy os image header, if it is a multi component image + * then boot_get_ramdisk() and get_fdt() will attempt to get + * data from second and third component accordingly. + */ + image_header_t *legacy_hdr_os; /* image header pointer */ + image_header_t legacy_hdr_os_copy; /* header copy */ + ulong legacy_hdr_valid; + +#if defined(CONFIG_FIT) + const char *fit_uname_cfg; /* configuration node unit name */ + + void *fit_hdr_os; /* os FIT image header */ + const char *fit_uname_os; /* os subimage node unit name */ + int fit_noffset_os; /* os subimage node offset */ + + void *fit_hdr_rd; /* init ramdisk FIT image header */ + const char *fit_uname_rd; /* init ramdisk subimage node unit name */ + int fit_noffset_rd; /* init ramdisk subimage node offset */ + + void *fit_hdr_fdt; /* FDT blob FIT image header */ + const char *fit_uname_fdt; /* FDT blob subimage node unit name */ + int fit_noffset_fdt;/* FDT blob subimage node offset */ +#endif + +#ifndef USE_HOSTCC + image_info_t os; /* os image info */ + ulong ep; /* entry point of OS */ + + ulong rd_start, rd_end;/* ramdisk start/end */ + +#ifdef CONFIG_OF_LIBFDT + char *ft_addr; /* flat dev tree address */ +#endif + ulong ft_len; /* length of flat device tree */ + + ulong initrd_start; + ulong initrd_end; + ulong cmdline_start; + ulong cmdline_end; + bd_t *kbd; +#endif + + int verify; /* getenv("verify")[0] != 'n' */ + +#define BOOTM_STATE_START (0x00000001) +#define BOOTM_STATE_LOADOS (0x00000002) +#define BOOTM_STATE_RAMDISK (0x00000004) +#define BOOTM_STATE_FDT (0x00000008) +#define BOOTM_STATE_OS_CMDLINE (0x00000010) +#define BOOTM_STATE_OS_BD_T (0x00000020) +#define BOOTM_STATE_OS_PREP (0x00000040) +#define BOOTM_STATE_OS_GO (0x00000080) + int state; + +#ifdef CONFIG_LMB + struct lmb lmb; /* for memory mgmt */ +#endif +} bootm_headers_t; + /* * Some systems (for example LWMON) have very short watchdog periods; * we must make sure to split long operations like memmove() or - * crc32() into reasonable chunks. + * checksum calculations into reasonable chunks. */ +#ifndef CHUNKSZ #define CHUNKSZ (64 * 1024) +#endif -#define image_to_cpu(x) ntohl(x) -#define cpu_to_image(x) htonl(x) +#ifndef CHUNKSZ_CRC32 +#define CHUNKSZ_CRC32 (64 * 1024) +#endif + +#ifndef CHUNKSZ_MD5 +#define CHUNKSZ_MD5 (64 * 1024) +#endif + +#ifndef CHUNKSZ_SHA1 +#define CHUNKSZ_SHA1 (64 * 1024) +#endif + +#define uimage_to_cpu(x) be32_to_cpu(x) +#define cpu_to_uimage(x) cpu_to_be32(x) + +/* + * Translation table for entries of a specific type; used by + * get_table_entry_id() and get_table_entry_name(). + */ +typedef struct table_entry { + int id; + char *sname; /* short (input) name to find table entry */ + char *lname; /* long (output) name to print for messages */ +} table_entry_t; + +/* + * get_table_entry_id() scans the translation table trying to find an + * entry that matches the given short name. If a matching entry is + * found, it's id is returned to the caller. + */ +int get_table_entry_id(const table_entry_t *table, + const char *table_name, const char *name); +/* + * get_table_entry_name() scans the translation table trying to find + * an entry that matches the given id. If a matching entry is found, + * its long name is returned to the caller. + */ +char *get_table_entry_name(const table_entry_t *table, char *msg, int id); + +const char *genimg_get_os_name (uint8_t os); +const char *genimg_get_arch_name (uint8_t arch); +const char *genimg_get_type_name (uint8_t type); +const char *genimg_get_comp_name (uint8_t comp); +int genimg_get_os_id (const char *name); +int genimg_get_arch_id (const char *name); +int genimg_get_type_id (const char *name); +int genimg_get_comp_id (const char *name); +void genimg_print_size (uint32_t size); +#ifndef USE_HOSTCC +/* Image format types, returned by _get_format() routine */ +#define IMAGE_FORMAT_INVALID 0x00 +#define IMAGE_FORMAT_LEGACY 0x01 /* legacy image_header based format */ +#define IMAGE_FORMAT_FIT 0x02 /* new, libfdt based format */ + +int genimg_get_format (void *img_addr); +int genimg_has_config (bootm_headers_t *images); +ulong genimg_get_image (ulong img_addr); + +int boot_get_ramdisk (int argc, char * const argv[], bootm_headers_t *images, + uint8_t arch, ulong *rd_start, ulong *rd_end); + + +#ifdef CONFIG_OF_LIBFDT +int boot_get_fdt (int flag, int argc, char * const argv[], bootm_headers_t *images, + char **of_flat_tree, ulong *of_size); +void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob); +int boot_relocate_fdt (struct lmb *lmb, char **of_flat_tree, ulong *of_size); +#endif + +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH +int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, + ulong *initrd_start, ulong *initrd_end); +#endif /* CONFIG_SYS_BOOT_RAMDISK_HIGH */ +#ifdef CONFIG_SYS_BOOT_GET_CMDLINE +int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end); +#endif /* CONFIG_SYS_BOOT_GET_CMDLINE */ +#ifdef CONFIG_SYS_BOOT_GET_KBD +int boot_get_kbd (struct lmb *lmb, bd_t **kbd); +#endif /* CONFIG_SYS_BOOT_GET_KBD */ +#endif /* !USE_HOSTCC */ + +/*******************************************************************/ +/* Legacy format specific code (prefixed with image_) */ +/*******************************************************************/ static inline uint32_t image_get_header_size (void) { return (sizeof (image_header_t)); } #define image_get_hdr_l(f) \ - static inline uint32_t image_get_##f(image_header_t *hdr) \ + static inline uint32_t image_get_##f(const image_header_t *hdr) \ { \ - return image_to_cpu (hdr->ih_##f); \ + return uimage_to_cpu (hdr->ih_##f); \ } -image_get_hdr_l (magic); -image_get_hdr_l (hcrc); -image_get_hdr_l (time); -image_get_hdr_l (size); -image_get_hdr_l (load); -image_get_hdr_l (ep); -image_get_hdr_l (dcrc); +image_get_hdr_l (magic) /* image_get_magic */ +image_get_hdr_l (hcrc) /* image_get_hcrc */ +image_get_hdr_l (time) /* image_get_time */ +image_get_hdr_l (size) /* image_get_size */ +image_get_hdr_l (load) /* image_get_load */ +image_get_hdr_l (ep) /* image_get_ep */ +image_get_hdr_l (dcrc) /* image_get_dcrc */ #define image_get_hdr_b(f) \ - static inline uint8_t image_get_##f(image_header_t *hdr) \ + static inline uint8_t image_get_##f(const image_header_t *hdr) \ { \ return hdr->ih_##f; \ } -image_get_hdr_b (os); -image_get_hdr_b (arch); -image_get_hdr_b (type); -image_get_hdr_b (comp); +image_get_hdr_b (os) /* image_get_os */ +image_get_hdr_b (arch) /* image_get_arch */ +image_get_hdr_b (type) /* image_get_type */ +image_get_hdr_b (comp) /* image_get_comp */ -static inline char *image_get_name (image_header_t *hdr) +static inline char *image_get_name (const image_header_t *hdr) { return (char *)hdr->ih_name; } -static inline uint32_t image_get_data_size (image_header_t *hdr) +static inline uint32_t image_get_data_size (const image_header_t *hdr) { return image_get_size (hdr); } -static inline uint32_t image_get_image_size (image_header_t *hdr) + +/** + * image_get_data - get image payload start address + * @hdr: image header + * + * image_get_data() returns address of the image payload. For single + * component images it is image data start. For multi component + * images it points to the null terminated table of sub-images sizes. + * + * returns: + * image payload data start address + */ +static inline ulong image_get_data (const image_header_t *hdr) +{ + return ((ulong)hdr + image_get_header_size ()); +} + +static inline uint32_t image_get_image_size (const image_header_t *hdr) { return (image_get_size (hdr) + image_get_header_size ()); } -static inline ulong image_get_data (image_header_t *hdr) +static inline ulong image_get_image_end (const image_header_t *hdr) { - return ((ulong)hdr + image_get_header_size ()); + return ((ulong)hdr + image_get_image_size (hdr)); } #define image_set_hdr_l(f) \ static inline void image_set_##f(image_header_t *hdr, uint32_t val) \ { \ - hdr->ih_##f = cpu_to_image (val); \ + hdr->ih_##f = cpu_to_uimage (val); \ } -image_set_hdr_l (magic); -image_set_hdr_l (hcrc); -image_set_hdr_l (time); -image_set_hdr_l (size); -image_set_hdr_l (load); -image_set_hdr_l (ep); -image_set_hdr_l (dcrc); +image_set_hdr_l (magic) /* image_set_magic */ +image_set_hdr_l (hcrc) /* image_set_hcrc */ +image_set_hdr_l (time) /* image_set_time */ +image_set_hdr_l (size) /* image_set_size */ +image_set_hdr_l (load) /* image_set_load */ +image_set_hdr_l (ep) /* image_set_ep */ +image_set_hdr_l (dcrc) /* image_set_dcrc */ #define image_set_hdr_b(f) \ static inline void image_set_##f(image_header_t *hdr, uint8_t val) \ { \ hdr->ih_##f = val; \ } -image_set_hdr_b (os); -image_set_hdr_b (arch); -image_set_hdr_b (type); -image_set_hdr_b (comp); +image_set_hdr_b (os) /* image_set_os */ +image_set_hdr_b (arch) /* image_set_arch */ +image_set_hdr_b (type) /* image_set_type */ +image_set_hdr_b (comp) /* image_set_comp */ static inline void image_set_name (image_header_t *hdr, const char *name) { strncpy (image_get_name (hdr), name, IH_NMLEN); } -int image_check_hcrc (image_header_t *hdr); -int image_check_dcrc (image_header_t *hdr); -int image_check_dcrc_wd (image_header_t *hdr, ulong chunksize); -int getenv_verify (void); +int image_check_hcrc (const image_header_t *hdr); +int image_check_dcrc (const image_header_t *hdr); +#ifndef USE_HOSTCC +int getenv_yesno (char *var); +ulong getenv_bootm_low(void); +phys_size_t getenv_bootm_size(void); +phys_size_t getenv_bootm_mapsize(void); +void memmove_wd (void *to, void *from, size_t len, ulong chunksz); +#endif -static inline int image_check_magic (image_header_t *hdr) +static inline int image_check_magic (const image_header_t *hdr) { return (image_get_magic (hdr) == IH_MAGIC); } -static inline int image_check_type (image_header_t *hdr, uint8_t type) +static inline int image_check_type (const image_header_t *hdr, uint8_t type) { return (image_get_type (hdr) == type); } -static inline int image_check_arch (image_header_t *hdr, uint8_t arch) +static inline int image_check_arch (const image_header_t *hdr, uint8_t arch) { return (image_get_arch (hdr) == arch); } -static inline int image_check_os (image_header_t *hdr, uint8_t os) +static inline int image_check_os (const image_header_t *hdr, uint8_t os) { return (image_get_os (hdr) == os); } +ulong image_multi_count (const image_header_t *hdr); +void image_multi_getimg (const image_header_t *hdr, ulong idx, + ulong *data, ulong *len); + +void image_print_contents (const void *hdr); + #ifndef USE_HOSTCC -static inline int image_check_target_arch (image_header_t *hdr) +static inline int image_check_target_arch (const image_header_t *hdr) { #if defined(__ARM__) if (!image_check_arch (hdr, IH_ARCH_ARM)) @@ -287,14 +496,14 @@ static inline int image_check_target_arch (image_header_t *hdr) if (!image_check_arch (hdr, IH_ARCH_MICROBLAZE)) #elif defined(__mips__) if (!image_check_arch (hdr, IH_ARCH_MIPS)) -#elif defined(__nios__) - if (!image_check_arch (hdr, IH_ARCH_NIOS)) #elif defined(__nios2__) if (!image_check_arch (hdr, IH_ARCH_NIOS2)) #elif defined(__PPC__) if (!image_check_arch (hdr, IH_ARCH_PPC)) #elif defined(__sh__) if (!image_check_arch (hdr, IH_ARCH_SH)) +#elif defined(__sparc__) + if (!image_check_arch (hdr, IH_ARCH_SPARC)) #else # error Unknown CPU type #endif @@ -302,6 +511,173 @@ static inline int image_check_target_arch (image_header_t *hdr) return 1; } +#endif /* USE_HOSTCC */ + +/*******************************************************************/ +/* New uImage format specific code (prefixed with fit_) */ +/*******************************************************************/ +#if defined(CONFIG_FIT) + +#define FIT_IMAGES_PATH "/images" +#define FIT_CONFS_PATH "/configurations" + +/* hash node */ +#define FIT_HASH_NODENAME "hash" +#define FIT_ALGO_PROP "algo" +#define FIT_VALUE_PROP "value" + +/* image node */ +#define FIT_DATA_PROP "data" +#define FIT_TIMESTAMP_PROP "timestamp" +#define FIT_DESC_PROP "description" +#define FIT_ARCH_PROP "arch" +#define FIT_TYPE_PROP "type" +#define FIT_OS_PROP "os" +#define FIT_COMP_PROP "compression" +#define FIT_ENTRY_PROP "entry" +#define FIT_LOAD_PROP "load" + +/* configuration node */ +#define FIT_KERNEL_PROP "kernel" +#define FIT_RAMDISK_PROP "ramdisk" +#define FIT_FDT_PROP "fdt" +#define FIT_DEFAULT_PROP "default" + +#define FIT_MAX_HASH_LEN 20 /* max(crc32_len(4), sha1_len(20)) */ + +/* cmdline argument format parsing */ +inline int fit_parse_conf (const char *spec, ulong addr_curr, + ulong *addr, const char **conf_name); +inline int fit_parse_subimage (const char *spec, ulong addr_curr, + ulong *addr, const char **image_name); + +void fit_print_contents (const void *fit); +void fit_image_print (const void *fit, int noffset, const char *p); +void fit_image_print_hash (const void *fit, int noffset, const char *p); + +/** + * fit_get_end - get FIT image size + * @fit: pointer to the FIT format image header + * + * returns: + * size of the FIT image (blob) in memory + */ +static inline ulong fit_get_size (const void *fit) +{ + return fdt_totalsize (fit); +} + +/** + * fit_get_end - get FIT image end + * @fit: pointer to the FIT format image header + * + * returns: + * end address of the FIT image (blob) in memory + */ +static inline ulong fit_get_end (const void *fit) +{ + return (ulong)fit + fdt_totalsize (fit); +} + +/** + * fit_get_name - get FIT node name + * @fit: pointer to the FIT format image header + * + * returns: + * NULL, on error + * pointer to node name, on success + */ +static inline const char *fit_get_name (const void *fit_hdr, + int noffset, int *len) +{ + return fdt_get_name (fit_hdr, noffset, len); +} + +int fit_get_desc (const void *fit, int noffset, char **desc); +int fit_get_timestamp (const void *fit, int noffset, time_t *timestamp); + +int fit_image_get_node (const void *fit, const char *image_uname); +int fit_image_get_os (const void *fit, int noffset, uint8_t *os); +int fit_image_get_arch (const void *fit, int noffset, uint8_t *arch); +int fit_image_get_type (const void *fit, int noffset, uint8_t *type); +int fit_image_get_comp (const void *fit, int noffset, uint8_t *comp); +int fit_image_get_load (const void *fit, int noffset, ulong *load); +int fit_image_get_entry (const void *fit, int noffset, ulong *entry); +int fit_image_get_data (const void *fit, int noffset, + const void **data, size_t *size); + +int fit_image_hash_get_algo (const void *fit, int noffset, char **algo); +int fit_image_hash_get_value (const void *fit, int noffset, uint8_t **value, + int *value_len); + +int fit_set_timestamp (void *fit, int noffset, time_t timestamp); +int fit_set_hashes (void *fit); +int fit_image_set_hashes (void *fit, int image_noffset); +int fit_image_hash_set_value (void *fit, int noffset, uint8_t *value, + int value_len); + +int fit_image_check_hashes (const void *fit, int noffset); +int fit_all_image_check_hashes (const void *fit); +int fit_image_check_os (const void *fit, int noffset, uint8_t os); +int fit_image_check_arch (const void *fit, int noffset, uint8_t arch); +int fit_image_check_type (const void *fit, int noffset, uint8_t type); +int fit_image_check_comp (const void *fit, int noffset, uint8_t comp); +int fit_check_format (const void *fit); + +int fit_conf_get_node (const void *fit, const char *conf_uname); +int fit_conf_get_kernel_node (const void *fit, int noffset); +int fit_conf_get_ramdisk_node (const void *fit, int noffset); +int fit_conf_get_fdt_node (const void *fit, int noffset); + +void fit_conf_print (const void *fit, int noffset, const char *p); + +#ifndef USE_HOSTCC +static inline int fit_image_check_target_arch (const void *fdt, int node) +{ +#if defined(__ARM__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_ARM)) +#elif defined(__avr32__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_AVR32)) +#elif defined(__bfin__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_BLACKFIN)) +#elif defined(__I386__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_I386)) +#elif defined(__M68K__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_M68K)) +#elif defined(__microblaze__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_MICROBLAZE)) +#elif defined(__mips__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_MIPS)) +#elif defined(__nios2__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_NIOS2)) +#elif defined(__PPC__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_PPC)) +#elif defined(__sh__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_SH)) +#elif defined(__sparc__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_SPARC)) +#else +# error Unknown CPU type #endif + return 0; + + return 1; +} +#endif /* USE_HOSTCC */ + +#ifdef CONFIG_FIT_VERBOSE +#define fit_unsupported(msg) printf ("! %s:%d " \ + "FIT images not supported for '%s'\n", \ + __FILE__, __LINE__, (msg)) + +#define fit_unsupported_reset(msg) printf ("! %s:%d " \ + "FIT images not supported for '%s' " \ + "- must reset board to recover!\n", \ + __FILE__, __LINE__, (msg)) +#else +#define fit_unsupported(msg) +#define fit_unsupported_reset(msg) +#endif /* CONFIG_FIT_VERBOSE */ +#endif /* CONFIG_FIT */ -#endif /* __IMAGE_H__ */ +#endif /* __IMAGE_H__ */