X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=inline;f=common%2Fimage.c;h=5c7d4f42f31e224abe4e1d836ae5b21047193815;hb=f9a78b8d4f1e9b42eb0563029a22fd6c34390088;hp=2b6007e9c6685c3080964e5935ba78aa307d7ffb;hpb=a81cd434b95a9884c9b4db1dbb53e9d460d36cb2;p=u-boot diff --git a/common/image.c b/common/image.c index 2b6007e9c6..5c7d4f42f3 100644 --- a/common/image.c +++ b/common/image.c @@ -60,7 +60,7 @@ static int fit_check_ramdisk (const void *fit, int os_noffset, #endif #ifdef CONFIG_CMD_BDI -extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); #endif DECLARE_GLOBAL_DATA_PTR; @@ -74,7 +74,7 @@ static const image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch, #include #endif /* !USE_HOSTCC*/ -static table_entry_t uimage_arch[] = { +static const table_entry_t uimage_arch[] = { { IH_ARCH_INVALID, NULL, "Invalid ARCH", }, { IH_ARCH_ALPHA, "alpha", "Alpha", }, { IH_ARCH_ARM, "arm", "ARM", }, @@ -96,13 +96,14 @@ static table_entry_t uimage_arch[] = { { -1, "", "", }, }; -static table_entry_t uimage_os[] = { +static const table_entry_t uimage_os[] = { { IH_OS_INVALID, NULL, "Invalid OS", }, { IH_OS_LINUX, "linux", "Linux", }, #if defined(CONFIG_LYNXKDI) || defined(USE_HOSTCC) { IH_OS_LYNXOS, "lynxos", "LynxOS", }, #endif { IH_OS_NETBSD, "netbsd", "NetBSD", }, + { IH_OS_OSE, "ose", "Enea OSE", }, { IH_OS_RTEMS, "rtems", "RTEMS", }, { IH_OS_U_BOOT, "u-boot", "U-Boot", }, #if defined(CONFIG_CMD_ELF) || defined(USE_HOSTCC) @@ -128,7 +129,7 @@ static table_entry_t uimage_os[] = { { -1, "", "", }, }; -static table_entry_t uimage_type[] = { +static const table_entry_t uimage_type[] = { { IH_TYPE_INVALID, NULL, "Invalid Image", }, { IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image", }, { IH_TYPE_FIRMWARE, "firmware", "Firmware", }, @@ -143,7 +144,7 @@ static table_entry_t uimage_type[] = { { -1, "", "", }, }; -static table_entry_t uimage_comp[] = { +static const table_entry_t uimage_comp[] = { { IH_COMP_NONE, "none", "uncompressed", }, { IH_COMP_BZIP2, "bzip2", "bzip2 compressed", }, { IH_COMP_GZIP, "gzip", "gzip compressed", }, @@ -433,17 +434,39 @@ ulong getenv_bootm_low(void) phys_size_t getenv_bootm_size(void) { + phys_size_t tmp; char *s = getenv ("bootm_size"); if (s) { - phys_size_t tmp; tmp = (phys_size_t)simple_strtoull (s, NULL, 16); return tmp; } + s = getenv("bootm_low"); + if (s) + tmp = (phys_size_t)simple_strtoull (s, NULL, 16); + else + tmp = 0; + #if defined(CONFIG_ARM) - return gd->bd->bi_dram[0].size; + return gd->bd->bi_dram[0].size - tmp; +#else + return gd->bd->bi_memsize - tmp; +#endif +} + +phys_size_t getenv_bootm_mapsize(void) +{ + phys_size_t tmp; + char *s = getenv ("bootm_mapsize"); + if (s) { + tmp = (phys_size_t)simple_strtoull (s, NULL, 16); + return tmp; + } + +#if defined(CONFIG_SYS_BOOTMAPSZ) + return CONFIG_SYS_BOOTMAPSZ; #else - return gd->bd->bi_memsize; + return getenv_bootm_size(); #endif } @@ -509,11 +532,11 @@ static void genimg_print_time (time_t timestamp) * long entry name if translation succeeds * msg otherwise */ -char *get_table_entry_name (table_entry_t *table, char *msg, int id) +char *get_table_entry_name(const table_entry_t *table, char *msg, int id) { for (; table->id >= 0; ++table) { if (table->id == id) -#if defined(USE_HOSTCC) || defined(CONFIG_RELOC_FIXUP_WORKS) +#if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC) return table->lname; #else return table->lname + gd->reloc_off; @@ -556,10 +579,10 @@ const char *genimg_get_comp_name (uint8_t comp) * entry id if translation succeeds * -1 otherwise */ -int get_table_entry_id (table_entry_t *table, +int get_table_entry_id(const table_entry_t *table, const char *table_name, const char *name) { - table_entry_t *t; + const table_entry_t *t; #ifdef USE_HOSTCC int first = 1; @@ -578,10 +601,10 @@ int get_table_entry_id (table_entry_t *table, fprintf (stderr, "\n"); #else for (t = table; t->id >= 0; ++t) { -#ifdef CONFIG_RELOC_FIXUP_WORKS - if (t->sname && strcmp(t->sname, name) == 0) -#else +#ifdef CONFIG_NEEDS_MANUAL_RELOC if (t->sname && strcmp(t->sname + gd->reloc_off, name) == 0) +#else + if (t->sname && strcmp(t->sname, name) == 0) #endif return (t->id); } @@ -756,7 +779,7 @@ int genimg_has_config (bootm_headers_t *images) * 1, if ramdisk image is found but corrupted, or invalid * rd_start and rd_end are set to 0 if no ramdisk exists */ -int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images, +int boot_get_ramdisk (int argc, char * const argv[], bootm_headers_t *images, uint8_t arch, ulong *rd_start, ulong *rd_end) { ulong rd_addr, rd_load; @@ -985,7 +1008,7 @@ int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images, return 0; } -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH /** * boot_ramdisk_high - relocate init ramdisk * @lmb: pointer to lmb handle, will be used for memory mgmt @@ -1074,7 +1097,7 @@ int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, error: return -1; } -#endif /* defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) */ +#endif /* CONFIG_SYS_BOOT_RAMDISK_HIGH */ #ifdef CONFIG_OF_LIBFDT static void fdt_error (const char *msg) @@ -1162,15 +1185,44 @@ static int fit_check_fdt (const void *fit, int fdt_noffset, int verify) #define CONFIG_SYS_FDT_PAD 0x3000 #endif +#if defined(CONFIG_OF_LIBFDT) +/** + * boot_fdt_add_mem_rsv_regions - Mark the memreserve sections as unusable + * @lmb: pointer to lmb handle, will be used for memory mgmt + * @fdt_blob: pointer to fdt blob base address + * + * Adds the memreserve regions in the dtb to the lmb block. Adding the + * memreserve regions prevents u-boot from using them to store the initrd + * or the fdt blob. + */ +void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob) +{ + uint64_t addr, size; + int i, total; + + if (fdt_check_header (fdt_blob) != 0) + return; + + total = fdt_num_mem_rsv(fdt_blob); + for (i = 0; i < total; i++) { + if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) != 0) + continue; + printf(" reserving fdt memory region: addr=%llx size=%llx\n", + (unsigned long long)addr, (unsigned long long)size); + lmb_reserve(lmb, addr, size); + } +} + /** * boot_relocate_fdt - relocate flat device tree * @lmb: pointer to lmb handle, will be used for memory mgmt - * @bootmap_base: base address of the bootmap region * @of_flat_tree: pointer to a char* variable, will hold fdt start address * @of_size: pointer to a ulong variable, will hold fdt length * - * boot_relocate_fdt() determines if the of_flat_tree address is within - * the bootmap and if not relocates it into that region + * boot_relocate_fdt() allocates a region of memory within the bootmap and + * relocates the of_flat_tree into that region, even if the fdt is already in + * the bootmap. It also expands the size of the fdt by CONFIG_SYS_FDT_PAD + * bytes. * * of_flat_tree and of_size are set to final (after relocation) values * @@ -1178,12 +1230,14 @@ static int fit_check_fdt (const void *fit, int fdt_noffset, int verify) * 0 - success * 1 - failure */ -int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, - char **of_flat_tree, ulong *of_size) +int boot_relocate_fdt (struct lmb *lmb, char **of_flat_tree, ulong *of_size) { - char *fdt_blob = *of_flat_tree; - ulong relocate = 0; + void *fdt_blob = *of_flat_tree; + void *of_start = 0; + char *fdt_high; ulong of_len = 0; + int err; + int disable_relocation = 0; /* nothing to do */ if (*of_size == 0) @@ -1194,69 +1248,76 @@ int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, goto error; } -#ifndef CONFIG_SYS_NO_FLASH - /* move the blob if it is in flash (set relocate) */ - if (addr2info ((ulong)fdt_blob) != NULL) - relocate = 1; -#endif + /* position on a 4K boundary before the alloc_current */ + /* Pad the FDT by a specified amount */ + of_len = *of_size + CONFIG_SYS_FDT_PAD; - /* - * The blob needs to be inside the boot mapping. - */ - if (fdt_blob < (char *)bootmap_base) - relocate = 1; - - if ((fdt_blob + *of_size + CONFIG_SYS_FDT_PAD) >= - ((char *)CONFIG_SYS_BOOTMAPSZ + bootmap_base)) - relocate = 1; - - /* move flattend device tree if needed */ - if (relocate) { - int err; - ulong of_start = 0; - - /* position on a 4K boundary before the alloc_current */ - /* Pad the FDT by a specified amount */ - of_len = *of_size + CONFIG_SYS_FDT_PAD; - of_start = (unsigned long)lmb_alloc_base(lmb, of_len, 0x1000, - (CONFIG_SYS_BOOTMAPSZ + bootmap_base)); - - if (of_start == 0) { - puts("device tree - allocation error\n"); - goto error; + /* If fdt_high is set use it to select the relocation address */ + fdt_high = getenv("fdt_high"); + if (fdt_high) { + void *desired_addr = (void *)simple_strtoul(fdt_high, NULL, 16); + + if (((ulong) desired_addr) == ~0UL) { + /* All ones means use fdt in place */ + desired_addr = fdt_blob; + disable_relocation = 1; } + if (desired_addr) { + of_start = + (void *)(ulong) lmb_alloc_base(lmb, of_len, 0x1000, + ((ulong) + desired_addr) + + of_len); + if (desired_addr && of_start != desired_addr) { + puts("Failed using fdt_high value for Device Tree"); + goto error; + } + } else { + of_start = + (void *)(ulong) lmb_alloc(lmb, of_len, 0x1000); + } + } else { + of_start = + (void *)(ulong) lmb_alloc_base(lmb, of_len, 0x1000, + getenv_bootm_mapsize() + + getenv_bootm_low()); + } + + if (of_start == 0) { + puts("device tree - allocation error\n"); + goto error; + } - debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", - (ulong)fdt_blob, (ulong)fdt_blob + *of_size - 1, - of_len, of_len); + if (disable_relocation) { + /* We assume there is space after the existing fdt to use for padding */ + fdt_set_totalsize(of_start, of_len); + printf(" Using Device Tree in place at %p, end %p\n", + of_start, of_start + of_len - 1); + } else { + debug ("## device tree at %p ... %p (len=%ld [0x%lX])\n", + fdt_blob, fdt_blob + *of_size - 1, of_len, of_len); - printf (" Loading Device Tree to %08lx, end %08lx ... ", + printf (" Loading Device Tree to %p, end %p ... ", of_start, of_start + of_len - 1); - err = fdt_open_into (fdt_blob, (void *)of_start, of_len); + err = fdt_open_into (fdt_blob, of_start, of_len); if (err != 0) { fdt_error ("fdt move failed"); goto error; } puts ("OK\n"); - - *of_flat_tree = (char *)of_start; - *of_size = of_len; - } else { - *of_flat_tree = fdt_blob; - of_len = (CONFIG_SYS_BOOTMAPSZ + bootmap_base) - (ulong)fdt_blob; - lmb_reserve(lmb, (ulong)fdt_blob, of_len); - fdt_set_totalsize(*of_flat_tree, of_len); - - *of_size = of_len; } + *of_flat_tree = of_start; + *of_size = of_len; + set_working_fdt_addr(*of_flat_tree); return 0; error: return 1; } +#endif /* CONFIG_OF_LIBFDT */ /** * boot_get_fdt - main fdt handling routine @@ -1279,7 +1340,7 @@ error: * 1, if fdt image is found but corrupted * of_flat_tree and of_size are set to 0 if no fdt exists */ -int boot_get_fdt (int flag, int argc, char *argv[], bootm_headers_t *images, +int boot_get_fdt (int flag, int argc, char * const argv[], bootm_headers_t *images, char **of_flat_tree, ulong *of_size) { const image_header_t *fdt_hdr; @@ -1552,7 +1613,7 @@ int boot_get_fdt (int flag, int argc, char *argv[], bootm_headers_t *images, goto error; } - if (be32_to_cpu (fdt_totalsize (fdt_blob)) != fdt_len) { + if (fdt_totalsize(fdt_blob) != fdt_len) { fdt_error ("fdt size != image size"); goto error; } @@ -1566,7 +1627,7 @@ int boot_get_fdt (int flag, int argc, char *argv[], bootm_headers_t *images, } *of_flat_tree = fdt_blob; - *of_size = be32_to_cpu (fdt_totalsize (fdt_blob)); + *of_size = fdt_totalsize(fdt_blob); debug (" of_flat_tree at 0x%08lx size 0x%08lx\n", (ulong)*of_flat_tree, *of_size); @@ -1579,17 +1640,15 @@ error: } #endif /* CONFIG_OF_LIBFDT */ -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) +#ifdef CONFIG_SYS_BOOT_GET_CMDLINE /** * boot_get_cmdline - allocate and initialize kernel cmdline * @lmb: pointer to lmb handle, will be used for memory mgmt * @cmd_start: pointer to a ulong variable, will hold cmdline start * @cmd_end: pointer to a ulong variable, will hold cmdline end - * @bootmap_base: ulong variable, holds offset in physical memory to - * base of bootmap * * boot_get_cmdline() allocates space for kernel command line below - * BOOTMAPSZ + bootmap_base address. If "bootargs" U-boot environemnt + * BOOTMAPSZ + getenv_bootm_low() address. If "bootargs" U-boot environemnt * variable is present its contents is copied to allocated kernel * command line. * @@ -1597,14 +1656,13 @@ error: * 0 - success * -1 - failure */ -int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end, - ulong bootmap_base) +int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end) { char *cmdline; char *s; cmdline = (char *)(ulong)lmb_alloc_base(lmb, CONFIG_SYS_BARGSIZE, 0xf, - CONFIG_SYS_BOOTMAPSZ + bootmap_base); + getenv_bootm_mapsize() + getenv_bootm_low()); if (cmdline == NULL) return -1; @@ -1621,26 +1679,26 @@ int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end, return 0; } +#endif /* CONFIG_SYS_BOOT_GET_CMDLINE */ +#ifdef CONFIG_SYS_BOOT_GET_KBD /** * boot_get_kbd - allocate and initialize kernel copy of board info * @lmb: pointer to lmb handle, will be used for memory mgmt * @kbd: double pointer to board info data - * @bootmap_base: ulong variable, holds offset in physical memory to - * base of bootmap * * boot_get_kbd() allocates space for kernel copy of board info data below - * BOOTMAPSZ + bootmap_base address and kernel board info is initialized with - * the current u-boot board info data. + * BOOTMAPSZ + getenv_bootm_low() address and kernel board info is initialized + * with the current u-boot board info data. * * returns: * 0 - success * -1 - failure */ -int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base) +int boot_get_kbd (struct lmb *lmb, bd_t **kbd) { *kbd = (bd_t *)(ulong)lmb_alloc_base(lmb, sizeof(bd_t), 0xf, - CONFIG_SYS_BOOTMAPSZ + bootmap_base); + getenv_bootm_mapsize() + getenv_bootm_low()); if (*kbd == NULL) return -1; @@ -1654,7 +1712,7 @@ int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base) return 0; } -#endif /* CONFIG_PPC || CONFIG_M68K */ +#endif /* CONFIG_SYS_BOOT_GET_KBD */ #endif /* !USE_HOSTCC */ #if defined(CONFIG_FIT)