From 3505465f64c1cfa12b062fc50ecf4c6ecbe8bdca Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 14 Dec 2011 09:27:06 +0100 Subject: [PATCH 01/17] ppc pcm030: Fix device resource sizes The device resources are much smaller, the resource mechanism revealed this because of overlapping devices. Signed-off-by: Sascha Hauer --- arch/ppc/boards/pcm030/pcm030.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/ppc/boards/pcm030/pcm030.c b/arch/ppc/boards/pcm030/pcm030.c index 61fb11620..4abf6cba8 100644 --- a/arch/ppc/boards/pcm030/pcm030.c +++ b/arch/ppc/boards/pcm030/pcm030.c @@ -59,7 +59,7 @@ static int devices_init (void) sdramsize = mpc5200_get_sdram_size(0) + mpc5200_get_sdram_size(1); barebox_add_memory_bank("ram0", 0x0, sdramsize); - add_generic_device("fec_mpc5xxx", -1, NULL, MPC5XXX_FEC, 0, + add_generic_device("fec_mpc5xxx", -1, NULL, MPC5XXX_FEC, 0x200, IORESOURCE_MEM, &fec_info); ret = stat("/dev/nor0", &s); @@ -76,9 +76,9 @@ device_initcall(devices_init); static int console_init(void) { - add_generic_device("mpc5xxx_serial", -1, NULL, MPC5XXX_PSC3, 4096, + add_generic_device("mpc5xxx_serial", -1, NULL, MPC5XXX_PSC3, 0x200, IORESOURCE_MEM, NULL); - add_generic_device("mpc5xxx_serial", -1, NULL, MPC5XXX_PSC6, 4096, + add_generic_device("mpc5xxx_serial", -1, NULL, MPC5XXX_PSC6, 0x200, IORESOURCE_MEM, NULL); return 0; } From 7b9d903a2097f5134f483411681e12307dc363ae Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 14 Dec 2011 10:07:44 +0100 Subject: [PATCH 02/17] pcm030: update defconfig Signed-off-by: Sascha Hauer --- arch/ppc/configs/pcm030_defconfig | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/arch/ppc/configs/pcm030_defconfig b/arch/ppc/configs/pcm030_defconfig index 601607616..5de1c75a0 100644 --- a/arch/ppc/configs/pcm030_defconfig +++ b/arch/ppc/configs/pcm030_defconfig @@ -1,22 +1,37 @@ +CONFIG_TEXT_BASE=0x3e00000 +CONFIG_MALLOC_SIZE=0x1000000 CONFIG_LONGHELP=y CONFIG_GLOB=y +CONFIG_HUSH_FANCY_PROMPT=y CONFIG_CMDLINE_EDITING=y CONFIG_AUTO_COMPLETE=y -CONFIG_OF_FLAT_TREE=y CONFIG_PARTITION=y -# CONFIG_DEFAULT_ENVIRONMENT is not set +CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y CONFIG_CMD_EDIT=y CONFIG_CMD_SLEEP=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_LOADENV=y +CONFIG_CMD_EXPORT=y +CONFIG_CMD_READLINE=y +CONFIG_CMD_TIME=y +CONFIG_CMD_ECHO_E=y CONFIG_CMD_MEMINFO=y +CONFIG_CMD_IOMEM=y CONFIG_CMD_FLASH=y -CONFIG_CMD_BOOTM_ZLIB=y -CONFIG_CMD_BOOTM_BZLIB=y +CONFIG_CMD_BOOTM_SHOW_TYPE=y +CONFIG_CMD_UIMAGE=y CONFIG_CMD_RESET=y CONFIG_CMD_GO=y +CONFIG_CMD_OFTREE=y +CONFIG_CMD_TIMEOUT=y +CONFIG_CMD_PARTITION=y +CONFIG_CMD_MAGICVAR=y +CONFIG_CMD_MAGICVAR_HELP=y +CONFIG_CMD_UNCOMPRESS=y CONFIG_NET=y CONFIG_NET_DHCP=y CONFIG_NET_PING=y CONFIG_NET_TFTP=y -CONFIG_DRIVER_NET_MPC5200=y CONFIG_DRIVER_CFI=y -CONFIG_FS_CRAMFS=y +CONFIG_CFI_BUFFER_WRITE=y +CONFIG_ZLIB=y From 58a0dde1f7165b590937abf5c3374d87f67ead6b Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 14 Dec 2011 11:07:23 +0100 Subject: [PATCH 03/17] ppc pcm030: Move memory registration to mem_initcall Signed-off-by: Sascha Hauer --- arch/ppc/boards/pcm030/pcm030.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/arch/ppc/boards/pcm030/pcm030.c b/arch/ppc/boards/pcm030/pcm030.c index 4abf6cba8..9c6ccb7bc 100644 --- a/arch/ppc/boards/pcm030/pcm030.c +++ b/arch/ppc/boards/pcm030/pcm030.c @@ -45,7 +45,6 @@ static struct mpc5xxx_fec_platform_data fec_info = { static int devices_init (void) { - unsigned long sdramsize; struct stat s; int ret; @@ -56,9 +55,6 @@ static int devices_init (void) mpc5200_setup_cs(MPC5200_BOOTCS, 0xfe000000, SZ_32M, 0x0008fd00); add_cfi_flash_device(-1, 0xfe000000, 32 * 1024 * 1024, 0); - sdramsize = mpc5200_get_sdram_size(0) + mpc5200_get_sdram_size(1); - barebox_add_memory_bank("ram0", 0x0, sdramsize); - add_generic_device("fec_mpc5xxx", -1, NULL, MPC5XXX_FEC, 0x200, IORESOURCE_MEM, &fec_info); @@ -85,6 +81,18 @@ static int console_init(void) console_initcall(console_init); +static int mem_init(void) +{ + unsigned long sdramsize; + + sdramsize = mpc5200_get_sdram_size(0) + mpc5200_get_sdram_size(1); + + barebox_add_memory_bank("ram0", 0x0, sdramsize); + + return 0; +} +mem_initcall(mem_init); + #include "mt46v32m16-75.h" static void sdram_start (int hi_addr) From a46098b1d18872cc468f849f87d39b1c9038c581 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 14 Dec 2011 11:09:13 +0100 Subject: [PATCH 04/17] ppc: switch to libfdt based oftree implementation Signed-off-by: Sascha Hauer --- arch/ppc/lib/ppclinux.c | 231 +----------------------------------- arch/ppc/mach-mpc5xxx/cpu.c | 40 +++---- commands/bootm.c | 5 + include/boot.h | 2 +- 4 files changed, 30 insertions(+), 248 deletions(-) diff --git a/arch/ppc/lib/ppclinux.c b/arch/ppc/lib/ppclinux.c index 471b3037f..f7d395060 100644 --- a/arch/ppc/lib/ppclinux.c +++ b/arch/ppc/lib/ppclinux.c @@ -16,230 +16,14 @@ #endif extern bd_t *bd; -static int do_bootm_linux(struct image_data *idata) +static int do_bootm_linux(struct image_data *data) { - ulong sp; - ulong initrd_end = 0; - ulong cmd_start, cmd_end; - ulong initrd_high; - int initrd_copy_to_ram = 1; - char *cmdline; - const char *c; - bd_t *kbd; - void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); -#ifdef CONFIG_OF_FLAT_TREE - char *of_flat_tree = NULL; -#endif - image_header_t *os_header = &idata->os->header; - image_header_t *initrd_header = NULL; - void *os_data = NULL; - void *initrd_data = NULL; - void *of_data = NULL; - struct image_handle *oftree_handle; - unsigned long os_len, initrd_len; + void (*kernel)(void *, void *, unsigned long, + unsigned long, unsigned long); + struct image_header *os_header = &data->os->header; - if (idata->initrd) - initrd_header = &idata->initrd->header; + kernel = (void *)image_get_ep(os_header); - printf("entering %s: os_header: %p initrd_header: %p oftree: %s\n", - __FUNCTION__, os_header, initrd_header, idata->oftree); - - if (image_get_type(os_header) == IH_TYPE_MULTI) { - unsigned long *data = (unsigned long *)(idata->os->data); - unsigned long len1 = 0, len2 = 0; - - if (!*data) { - printf("multifile image with 0 entries???\n"); - return -1; - } - os_len = ntohl(*data); /* first one is the kernel */ - data++; - - if (*data) { - len1 = ntohl(*data); /* could be initrd or oftree */ - data++; - } - - if (*data) { - len2 = ntohl(*data); /* could be oftree */ - data++; - } - - while (*data) /* skip all remaining files */ - data++; - - data++; /* skip terminating zero */ - - os_data = (void *)ntohl(data); - - if (len2) { - initrd_data = (void *) - ((unsigned long)data + ((os_len + 3) & ~3)); - initrd_len = len1; - of_data = (void *) - ((unsigned long)initrd_data + ((initrd_len + 3) & ~3)); - } else if (len1) { - /* We could check here if this is a multifile image - * with only a kernel and an oftree. Original barebox - * did not do this, so leave it out for now. - */ - initrd_data = (void *)((unsigned long)data + ((os_len + 3) & ~3)); - initrd_len = len1; - } - } else { - os_data = idata->os->data; - printf("set os_data to %p\n", os_data); - } - - if (idata->initrd) - initrd_data = idata->initrd->data; - -#ifdef CONFIG_OF_FLAT_TREE - if (idata->oftree) { - /* The oftree can be given either as an barebox image or as a - * binary blob. First try to read it as an image. - */ - oftree_handle = map_image(idata->oftree, 1); - if (oftree_handle) { - of_data = oftree_handle->data; - } else { - of_data = read_file(idata->oftree, 0); - if (!of_data) { - printf("could not read %s: %s\n", idata->oftree, errno_str()); - return -1; - } - } - /* FIXME: check if this is really an oftree */ - } -#endif - printf("loading kernel.\n"); - - if ((c = getenv ("initrd_high")) != NULL) { - /* a value of "no" or a similar string will act like 0, - * turning the "load high" feature off. This is intentional. - */ - initrd_high = simple_strtoul(c, NULL, 16); - if (initrd_high == ~0) - initrd_copy_to_ram = 0; - } else { /* not set, no restrictions to load high */ - initrd_high = ~0; - } - -#ifdef CONFIG_LOGBUFFER - kbd=gd->bd; - /* Prevent initrd from overwriting logbuffer */ - if (initrd_high < (kbd->bi_memsize-LOGBUFF_LEN-LOGBUFF_OVERHEAD)) - initrd_high = kbd->bi_memsize-LOGBUFF_LEN-LOGBUFF_OVERHEAD; - debug ("## Logbuffer at 0x%08lX ", kbd->bi_memsize-LOGBUFF_LEN); -#endif - - /* - * Booting a (Linux) kernel image - * - * Allocate space for command line and board info - the - * address should be as high as possible within the reach of - * the kernel (see CFG_BOOTMAPSZ settings), but in unused - * memory, which means far enough below the current stack - * pointer. - */ - - asm( "mr %0,1": "=r"(sp) : ); - - debug ("## Current stack ends at 0x%08lX ", sp); - - sp -= 2048; /* just to be sure */ - if (sp > CFG_BOOTMAPSZ) - sp = CFG_BOOTMAPSZ; - sp &= ~0xF; - - debug ("=> set upper limit to 0x%08lX\n", sp); - - cmdline = (char *)((sp - CONFIG_CBSIZE) & ~0xF); - kbd = (bd_t *)(((ulong)cmdline - sizeof(bd_t)) & ~0xF); - - printf("cmdline: %p kbd: %p\n", cmdline, kbd); - - if ((c = getenv("bootargs")) == NULL) - c = ""; - - strcpy (cmdline, c); - - cmd_start = (ulong)cmdline; - cmd_end = cmd_start + strlen(cmdline); - - init_board_data(kbd); - -#ifdef DEBUG - printf ("## cmdline at 0x%08lX ... 0x%08lX\n", cmd_start, cmd_end); - -// do_bdinfo (NULL, 0, 0, NULL); -#endif - - if ((c = getenv ("clocks_in_mhz")) != NULL) { - /* convert all clock information to MHz */ - kbd->bi_intfreq /= 1000000L; - kbd->bi_busfreq /= 1000000L; -#if defined(CONFIG_MPC8220) - kbd->bi_inpfreq /= 1000000L; - kbd->bi_pcifreq /= 1000000L; - kbd->bi_pevfreq /= 1000000L; - kbd->bi_flbfreq /= 1000000L; - kbd->bi_vcofreq /= 1000000L; -#endif -#if defined(CONFIG_CPM2) - kbd->bi_cpmfreq /= 1000000L; - kbd->bi_brgfreq /= 1000000L; - kbd->bi_sccfreq /= 1000000L; - kbd->bi_vco /= 1000000L; -#endif -#if defined(CONFIG_MPC5xxx) - kbd->bi_ipbfreq /= 1000000L; - kbd->bi_pcifreq /= 1000000L; -#endif /* CONFIG_MPC5xxx */ - } - - kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep(os_header); /* FIXME */ - -#if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500) - unlock_ram_in_cache(); -#endif - -#ifdef CONFIG_OF_FLAT_TREE - /* move of_flat_tree if needed */ - if (of_data) { - ulong of_start, of_len; - of_len = ((struct boot_param_header *)of_data)->totalsize; - /* provide extra 8k pad */ - if (initrd_data) - of_start = (unsigned long)initrd_data - of_len - 8192; - else - of_start = (ulong)kbd - of_len - 8192; - of_start &= ~(4096 - 1); /* align on page */ - debug ("## device tree at 0x%p ... 0x%p (len=%ld=0x%lX)\n", - of_data, of_data + of_len - 1, of_len, of_len); - - of_flat_tree = (char *)of_start; - printf (" Loading Device Tree to %08lx, end %08lx ... ", - of_start, of_start + of_len - 1); - memmove ((void *)of_start, (void *)of_data, of_len); - } -#endif - - /* - * Linux Kernel Parameters (passing board info data): - * r3: ptr to board info data - * r4: initrd_start or 0 if no initrd - * r5: initrd_end - unused if r4 is 0 - * r6: Start of command line string - * r7: End of command line string - */ -#ifdef CONFIG_OF_FLAT_TREE - if (!of_flat_tree) /* no device tree; boot old style */ -#endif - (*kernel) (kbd, (ulong)initrd_data, initrd_end, cmd_start, cmd_end); - /* does not return */ - -#ifdef CONFIG_OF_FLAT_TREE /* * Linux Kernel Parameters (passing device tree): * r3: ptr to OF flat tree, followed by the board info data @@ -248,11 +32,8 @@ static int do_bootm_linux(struct image_data *idata) * r6: NULL * r7: NULL */ - ft_setup(of_flat_tree, kbd, (long)initrd_data, initrd_end); - ft_cpu_setup(of_flat_tree, kbd); + kernel(data->oftree, kernel, 0, 0, 0); - (*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0); -#endif reset_cpu(0); /* not reached */ diff --git a/arch/ppc/mach-mpc5xxx/cpu.c b/arch/ppc/mach-mpc5xxx/cpu.c index d695b9b54..62ddb1fbe 100644 --- a/arch/ppc/mach-mpc5xxx/cpu.c +++ b/arch/ppc/mach-mpc5xxx/cpu.c @@ -34,12 +34,9 @@ #include #include #include +#include #include -#if defined(CONFIG_OF_FLAT_TREE) -#include -#endif - int checkcpu (void) { ulong clock = get_cpu_clock(); @@ -83,27 +80,26 @@ void __noreturn reset_cpu (unsigned long addr) /* ------------------------------------------------------------------------- */ -#ifdef CONFIG_OF_FLAT_TREE -void -ft_cpu_setup(void *blob, bd_t *bd) +#ifdef CONFIG_OFTREE +static int of_mpc5200_fixup(struct fdt_header *fdt) { - u32 *p; - int len; + char *cpu_path = "/cpus/PowerPC,5200@0"; + int div = in_8((void*)CFG_MBAR + 0x204) & 0x0020 ? 8 : 4; - /* Core XLB bus frequency */ - p = ft_get_prop(blob, "/cpus/" OF_CPU "/bus-frequency", &len); - if (p != NULL) - *p = cpu_to_be32(get_bus_clock()); - - /* SOC peripherals use the IPB bus frequency */ - p = ft_get_prop(blob, "/" OF_SOC "/bus-frequency", &len); - if (p != NULL) - *p = cpu_to_be32(get_ipb_clock()); - - p = ft_get_prop(blob, "/" OF_SOC "/ethernet@3000/mac-address", &len); - if (p != NULL) - memcpy(p, bd->bi_enetaddr, 6); + do_fixup_by_path_u32(fdt, cpu_path, "timebase-frequency", get_timebase_clock(), 1); + do_fixup_by_path_u32(fdt, cpu_path, "bus-frequency", get_bus_clock(), 1); + do_fixup_by_path_u32(fdt, cpu_path, "clock-frequency", get_cpu_clock(), 1); + do_fixup_by_path_u32(fdt, "/soc5200@f0000000", "bus-frequency", get_ipb_clock(), 1); + do_fixup_by_path_u32(fdt, "/soc5200@f0000000", "system-frequency", + get_bus_clock() * div, 1); + return 0; } + +static int of_register_mpc5200_fixup(void) +{ + return of_register_fixup(of_mpc5200_fixup); +} +late_initcall(of_register_mpc5200_fixup); #endif int cpu_init_board_data(bd_t *bd) diff --git a/commands/bootm.c b/commands/bootm.c index f97a84223..265ad4637 100644 --- a/commands/bootm.c +++ b/commands/bootm.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -144,6 +145,10 @@ static int do_bootm(struct command *cmdtp, int argc, char *argv[]) } } +#ifdef CONFIG_OFTREE + data.oftree = of_get_fixed_tree(); +#endif + if (optind == argc) { ret = COMMAND_ERROR_USAGE; goto err_out; diff --git a/include/boot.h b/include/boot.h index b67e03480..297b944c7 100644 --- a/include/boot.h +++ b/include/boot.h @@ -7,7 +7,7 @@ struct image_data { struct image_handle *os; struct image_handle *initrd; - const char *oftree; + void *oftree; int verify; unsigned long initrd_address; unsigned long initrd_size; From a746f4685a1dec66fc59bf8b9e20524b10a5d8b7 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 14 Dec 2011 10:08:32 +0100 Subject: [PATCH 05/17] remove old ft_build support This is unused now as its only user (ppc) is switched to libfdt based oftree support" Signed-off-by: Sascha Hauer --- arch/ppc/boards/pcm030/pcm030.c | 9 - common/Kconfig | 4 - common/Makefile | 1 - common/ft_build.c | 620 -------------------------------- include/ft_build.h | 69 ---- 5 files changed, 703 deletions(-) delete mode 100644 common/ft_build.c delete mode 100644 include/ft_build.h diff --git a/arch/ppc/boards/pcm030/pcm030.c b/arch/ppc/boards/pcm030/pcm030.c index 9c6ccb7bc..80f1cbe7f 100644 --- a/arch/ppc/boards/pcm030/pcm030.c +++ b/arch/ppc/boards/pcm030/pcm030.c @@ -191,12 +191,3 @@ void initdram (int board_type) } } } - -#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) -void -ft_board_setup(void *blob, bd_t *bd) -{ - ft_cpu_setup(blob, bd); -} -#endif - diff --git a/common/Kconfig b/common/Kconfig index 27464d15e..1c9e39844 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -398,10 +398,6 @@ config CONSOLE_ACTIVATE_ALL Enabling this options activates all consoles on startup, so you will get output and a prompt on all consoles simultaneously. -config OF_FLAT_TREE - bool - prompt "Open Firmware flat device tree support" - config PARTITION bool prompt "Enable Partitions" diff --git a/common/Makefile b/common/Makefile index 9bce47943..237c6b043 100644 --- a/common/Makefile +++ b/common/Makefile @@ -1,7 +1,6 @@ obj-$(CONFIG_SHELL_HUSH) += hush.o obj-$(CONFIG_SHELL_SIMPLE) += parser.o obj-$(CONFIG_GREGORIAN_CALENDER) += date.o -obj-$(CONFIG_OF_FLAT_TREE) += ft_build.o obj-$(CONFIG_KALLSYMS) += kallsyms.o obj-$(CONFIG_ENV_HANDLING) += environment.o obj-$(CONFIG_AUTO_COMPLETE) += complete.o diff --git a/common/ft_build.c b/common/ft_build.c deleted file mode 100644 index 9042f1337..000000000 --- a/common/ft_build.c +++ /dev/null @@ -1,620 +0,0 @@ -/* - * OF flat tree builder - * Written by: Pantelis Antoniou - * Updated by: Matthew McClintock - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#undef DEBUG - -/* align addr on a size boundary - adjust address up if needed -- Cort */ -#define _ALIGN(addr,size) (((addr)+(size)-1)&(~((size)-1))) -#ifndef CONFIG_OF_BOOT_CPU -#define CONFIG_OF_BOOT_CPU 0 -#endif -#define SIZE_OF_RSVMAP_ENTRY (2*sizeof(u64)) - -static void ft_put_word(struct ft_cxt *cxt, u32 v) -{ - memmove(cxt->p + sizeof(u32), cxt->p, cxt->p_end - cxt->p); - - *(u32 *) cxt->p = cpu_to_be32(v); - cxt->p += sizeof(u32); - cxt->p_end += sizeof(u32); -} - -static inline void ft_put_bin(struct ft_cxt *cxt, const void *data, int sz) -{ - int aligned_size = ((u8 *)_ALIGN((unsigned long)cxt->p + sz, - sizeof(u32))) - cxt->p; - - memmove(cxt->p + aligned_size, cxt->p, cxt->p_end - cxt->p); - - /* make sure the last bytes are zeroed */ - memset(cxt->p + aligned_size - (aligned_size % sizeof(u32)), 0, - (aligned_size % sizeof(u32))); - - memcpy(cxt->p, data, sz); - - cxt->p += aligned_size; - cxt->p_end += aligned_size; -} - -void ft_begin_node(struct ft_cxt *cxt, const char *name) -{ - ft_put_word(cxt, OF_DT_BEGIN_NODE); - ft_put_bin(cxt, name, strlen(name) + 1); -} - -void ft_end_node(struct ft_cxt *cxt) -{ - ft_put_word(cxt, OF_DT_END_NODE); -} - -void ft_nop(struct ft_cxt *cxt) -{ - ft_put_word(cxt, OF_DT_NOP); -} - -static int lookup_string(struct ft_cxt *cxt, const char *name) -{ - u8 *p; - - p = cxt->p; - while (p < cxt->p_end) { - if (strcmp((char *)p, name) == 0) - return p - cxt->p; - p += strlen((char *)p) + 1; - } - - return -1; -} - -void ft_prop(struct ft_cxt *cxt, const char *name, const void *data, int sz) -{ - int off = 0; - - off = lookup_string(cxt, name); - if (off == -1) { - memcpy(cxt->p_end, name, strlen(name) + 1); - off = cxt->p_end - cxt->p; - cxt->p_end += strlen(name) + 1; - } - - /* now put offset from beginning of *STRUCTURE* */ - /* will be fixed up at the end */ - ft_put_word(cxt, OF_DT_PROP); - ft_put_word(cxt, sz); - ft_put_word(cxt, off); - ft_put_bin(cxt, data, sz); -} - -void ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str) -{ - ft_prop(cxt, name, str, strlen(str) + 1); -} - -void ft_prop_int(struct ft_cxt *cxt, const char *name, int val) -{ - u32 v = cpu_to_be32((u32) val); - - ft_prop(cxt, name, &v, sizeof(u32)); -} - -/* pick up and start working on a tree in place */ -void ft_init_cxt(struct ft_cxt *cxt, void *blob) -{ - struct boot_param_header *bph = blob; - - memset(cxt, 0, sizeof(*cxt)); - - cxt->bph = bph; - bph->boot_cpuid_phys = CONFIG_OF_BOOT_CPU; - - /* find beginning and end of reserve map table (zeros in last entry) */ - cxt->p_rsvmap = (u8 *)bph + bph->off_mem_rsvmap; - while ( ((uint64_t *)cxt->p_rsvmap)[0] != 0 && - ((uint64_t *)cxt->p_rsvmap)[1] != 0 ) { - cxt->p_rsvmap += SIZE_OF_RSVMAP_ENTRY; - } - - cxt->p_start = (u8 *)bph + bph->off_dt_struct; - cxt->p_end = (u8 *)bph + bph->totalsize; - cxt->p = (u8 *)bph + bph->off_dt_strings; -} - -/* add a reserver physical area to the rsvmap */ -void ft_add_rsvmap(struct ft_cxt *cxt, u64 physstart, u64 physend) -{ - memmove(cxt->p_rsvmap + SIZE_OF_RSVMAP_ENTRY, cxt->p_rsvmap, - cxt->p_end - cxt->p_rsvmap); - - ((u64 *)cxt->p_rsvmap)[0] = cpu_to_be64(physstart); - ((u64 *)cxt->p_rsvmap)[1] = cpu_to_be64(physend); - ((u64 *)cxt->p_rsvmap)[2] = 0; - ((u64 *)cxt->p_rsvmap)[3] = 0; - - cxt->p_rsvmap += SIZE_OF_RSVMAP_ENTRY; - cxt->p_start += SIZE_OF_RSVMAP_ENTRY; - cxt->p += SIZE_OF_RSVMAP_ENTRY; - cxt->p_end += SIZE_OF_RSVMAP_ENTRY; -} - -void ft_end_tree(struct ft_cxt *cxt) -{ - ft_put_word(cxt, OF_DT_END); -} - -/* update the boot param header with correct values */ -void ft_finalize_tree(struct ft_cxt *cxt) { - struct boot_param_header *bph = cxt->bph; - - bph->totalsize = cxt->p_end - (u8 *)bph; - bph->off_dt_struct = cxt->p_start - (u8 *)bph; - bph->off_dt_strings = cxt->p - (u8 *)bph; - bph->dt_strings_size = cxt->p_end - cxt->p; -} - -static inline int isprint(int c) -{ - return c >= 0x20 && c <= 0x7e; -} - -static int is_printable_string(const void *data, int len) -{ - const char *s = data; - const char *ss; - - /* zero length is not */ - if (len == 0) - return 0; - - /* must terminate with zero */ - if (s[len - 1] != '\0') - return 0; - - ss = s; - while (*s && isprint(*s)) - s++; - - /* not zero, or not done yet */ - if (*s != '\0' || (s + 1 - ss) < len) - return 0; - - return 1; -} - -static void print_data(const void *data, int len) -{ - int i; - const u8 *s; - - /* no data, don't print */ - if (len == 0) - return; - - if (is_printable_string(data, len)) { - puts(" = \""); - puts(data); - puts("\""); - return; - } - - switch (len) { - case 1: /* byte */ - printf(" = <%02x>", (*(u8 *) data) & 0xff); - break; - case 2: /* half-word */ - printf(" = <%04x>", be16_to_cpu(*(u16 *) data) & 0xffff); - break; - case 4: /* word */ - printf(" = <%x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU); - break; - case 8: /* double-word */ - printf(" = <%qx>", be64_to_cpu(*(uint64_t *) data)); - break; - default: /* anything else... hexdump */ - printf(" = ["); - for (i = 0, s = data; i < len; i++) - printf("%02x%s", s[i], i < len - 1 ? " " : ""); - printf("]"); - - break; - } -} - -void ft_dump_blob(const void *bphp) -{ - const struct boot_param_header *bph = bphp; - const uint64_t *p_rsvmap = (const uint64_t *) - ((const char *)bph + be32_to_cpu(bph->off_mem_rsvmap)); - const u32 *p_struct = (const u32 *) - ((const char *)bph + be32_to_cpu(bph->off_dt_struct)); - const u32 *p_strings = (const u32 *) - ((const char *)bph + be32_to_cpu(bph->off_dt_strings)); - u32 tag; - const u32 *p; - const char *s, *t; - int depth, sz, shift; - int i; - uint64_t addr, size; - - if (be32_to_cpu(bph->magic) != OF_DT_HEADER) { - /* not valid tree */ - return; - } - - depth = 0; - shift = 4; - - for (i = 0;; i++) { - addr = be64_to_cpu(p_rsvmap[i * 2]); - size = be64_to_cpu(p_rsvmap[i * 2 + 1]); - if (addr == 0 && size == 0) - break; - - printf("/memreserve/ %qx %qx;\n", addr, size); - } - - p = p_struct; - while ((tag = be32_to_cpu(*p++)) != OF_DT_END) { - - /* printf("tag: 0x%08x (%d)\n", tag, p - p_struct); */ - - if (tag == OF_DT_BEGIN_NODE) { - s = (const char *)p; - p = (u32 *) _ALIGN((unsigned long)p + strlen(s) + 1, 4); - - printf("%*s%s {\n", depth * shift, "", s); - - depth++; - continue; - } - - if (tag == OF_DT_END_NODE) { - depth--; - - printf("%*s};\n", depth * shift, ""); - continue; - } - - if (tag == OF_DT_NOP) { - printf("%*s[NOP]\n", depth * shift, ""); - continue; - } - - if (tag != OF_DT_PROP) { - fprintf(stderr, "%*s ** Unknown tag 0x%08x at 0x%p\n", - depth * shift, "", tag, --p); - break; - } - sz = be32_to_cpu(*p++); - s = (const char *)p_strings + be32_to_cpu(*p++); - t = (const char *)p; - p = (const u32 *)_ALIGN((unsigned long)p + sz, 4); - printf("%*s%s", depth * shift, "", s); - print_data(t, sz); - printf(";\n"); - } -} - -void ft_backtrack_node(struct ft_cxt *cxt) -{ - int i = 4; - - while (be32_to_cpu(*(u32 *) (cxt->p - i)) != OF_DT_END_NODE) - i += 4; - - memmove (cxt->p - i, cxt->p, cxt->p_end - cxt->p); - - cxt->p_end -= i; - cxt->p -= i; -} - -void *ft_get_prop(void *bphp, const char *propname, int *szp) -{ - struct boot_param_header *bph = bphp; - uint32_t *p_struct = - (uint32_t *) ((char *)bph + be32_to_cpu(bph->off_dt_struct)); - uint32_t *p_strings = - (uint32_t *) ((char *)bph + be32_to_cpu(bph->off_dt_strings)); - uint32_t version = be32_to_cpu(bph->version); - uint32_t tag; - uint32_t *p; - char *s, *t; - char *ss; - int sz; - static char path[256], prop[256]; - - path[0] = '\0'; - - p = p_struct; - while ((tag = be32_to_cpu(*p++)) != OF_DT_END) { - - if (tag == OF_DT_BEGIN_NODE) { - s = (char *)p; - p = (uint32_t *) _ALIGN((unsigned long)p + strlen(s) + - 1, 4); - strcat(path, s); - strcat(path, "/"); - continue; - } - - if (tag == OF_DT_END_NODE) { - path[strlen(path) - 1] = '\0'; - ss = strrchr(path, '/'); - if (ss != NULL) - ss[1] = '\0'; - continue; - } - - if (tag == OF_DT_NOP) - continue; - - if (tag != OF_DT_PROP) - break; - - sz = be32_to_cpu(*p++); - s = (char *)p_strings + be32_to_cpu(*p++); - if (version < 0x10 && sz >= 8) - p = (uint32_t *) _ALIGN((unsigned long)p, 8); - t = (char *)p; - p = (uint32_t *) _ALIGN((unsigned long)p + sz, 4); - - strcpy(prop, path); - strcat(prop, s); - - if (strcmp(prop, propname) == 0) { - *szp = sz; - return t; - } - } - - return NULL; -} - -/********************************************************************/ - -/* Function that returns a character from the environment */ -extern uchar(*env_get_char) (int); - -#define BDM(x) { .name = #x, .offset = offsetof(bd_t, bi_ ##x ) } - -#ifdef CONFIG_OF_HAS_BD_T -static const struct { - const char *name; - int offset; -} bd_map[] = { - BDM(memstart), - BDM(memsize), - BDM(flashstart), - BDM(flashsize), - BDM(flashoffset), - BDM(sramstart), - BDM(sramsize), -#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_8260) \ - || defined(CONFIG_E500) - BDM(immr_base), -#endif -#if defined(CONFIG_MPC5xxx) - BDM(mbar_base), -#endif -#if defined(CONFIG_MPC83XX) - BDM(immrbar), -#endif -#if defined(CONFIG_MPC8220) - BDM(mbar_base), - BDM(inpfreq), - BDM(pcifreq), - BDM(pevfreq), - BDM(flbfreq), - BDM(vcofreq), -#endif - BDM(bootflags), - BDM(ip_addr), - BDM(intfreq), - BDM(busfreq), -#ifdef CONFIG_CPM2 - BDM(cpmfreq), - BDM(brgfreq), - BDM(sccfreq), - BDM(vco), -#endif -#if defined(CONFIG_MPC5xxx) - BDM(ipbfreq), - BDM(pcifreq), -#endif - BDM(baudrate), -}; -#endif - -void ft_setup(void *blob, bd_t * bd, ulong initrd_start, ulong initrd_end) -{ - u32 *p; - int len; - struct ft_cxt cxt; - ulong clock; -#if defined(CONFIG_OF_HAS_BAREBOX_ENV) - int k, nxt; -#endif -#if defined(CONFIG_OF_HAS_BD_T) - u8 *end; -#endif -#if defined(CONFIG_OF_HAS_BAREBOX_ENV) || defined(CONFIG_OF_HAS_BD_T) - int i; - static char tmpenv[256]; -#endif - - /* disable OF tree; booting old kernel */ - if (getenv("disable_of") != NULL) { - memcpy(blob, bd, sizeof(*bd)); - return; - } - -#ifdef DEBUG - printf ("recieved oftree\n"); - ft_dump_blob(blob); -#endif - - ft_init_cxt(&cxt, blob); - - if (initrd_start && initrd_end) - ft_add_rsvmap(&cxt, initrd_start, initrd_end - initrd_start + 1); - - /* back into root */ - ft_backtrack_node(&cxt); - -#ifdef CONFIG_OF_HAS_BAREBOX_ENV - ft_begin_node(&cxt, "barebox-env"); - - for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) { - char *s, *lval, *rval; - - for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) ; - s = tmpenv; - for (k = i; k < nxt && s < &tmpenv[sizeof(tmpenv) - 1]; ++k) - *s++ = env_get_char(k); - *s++ = '\0'; - lval = tmpenv; - s = strchr(tmpenv, '='); - if (s != NULL) { - *s++ = '\0'; - rval = s; - } else - continue; - ft_prop_str(&cxt, lval, rval); - } - - ft_end_node(&cxt); -#endif - - ft_begin_node(&cxt, "chosen"); - ft_prop_str(&cxt, "name", "chosen"); - - ft_prop_str(&cxt, "bootargs", getenv("bootargs")); - ft_prop_int(&cxt, "linux,platform", 0x600); /* what is this? */ - if (initrd_start && initrd_end) { - ft_prop_int(&cxt, "linux,initrd-start", initrd_start); - ft_prop_int(&cxt, "linux,initrd-end", initrd_end); - } -#ifdef OF_STDOUT_PATH - ft_prop_str(&cxt, "linux,stdout-path", OF_STDOUT_PATH); -#endif - - ft_end_node(&cxt); - - ft_end_node(&cxt); /* end root */ - - ft_end_tree(&cxt); - ft_finalize_tree(&cxt); - -#ifdef CONFIG_OF_HAS_BD_T - /* paste the bd_t at the end of the flat tree */ - end = (char *)blob + - be32_to_cpu(((struct boot_param_header *)blob)->totalsize); - memcpy(end, bd, sizeof(*bd)); -#endif - -#ifdef CONFIG_PPC - -#ifdef CONFIG_OF_HAS_BD_T - for (i = 0; i < sizeof(bd_map)/sizeof(bd_map[0]); i++) { - uint32_t v; - - sprintf(tmpenv, "/bd_t/%s", bd_map[i].name); - v = *(uint32_t *)((char *)bd + bd_map[i].offset); - - p = ft_get_prop(blob, tmpenv, &len); - if (p != NULL) - *p = cpu_to_be32(v); - } - - p = ft_get_prop(blob, "/bd_t/enetaddr", &len); - if (p != NULL) - memcpy(p, bd->bi_enetaddr, 6); - - p = ft_get_prop(blob, "/bd_t/ethspeed", &len); - if (p != NULL) - *p = cpu_to_be32((uint32_t) bd->bi_ethspeed); -#endif - - clock = bd->bi_intfreq; - p = ft_get_prop(blob, "/cpus/" OF_CPU "/clock-frequency", &len); - if (p != NULL) - *p = cpu_to_be32(clock); - -#ifdef OF_TBCLK - clock = OF_TBCLK; - p = ft_get_prop(blob, "/cpus/" OF_CPU "/timebase-frequency", &len); - if (p != NULL) - *p = cpu_to_be32(clock); -#endif -#endif /* __powerpc__ */ - -#ifdef CONFIG_OF_BOARD_SETUP - ft_board_setup(blob, bd); -#endif - - /* in case the size changed in the platform code */ - ft_finalize_tree(&cxt); - -#ifdef DEBUG - printf("final OF-tree\n"); - ft_dump_blob(blob); -#endif -} - -#if 0 -static int oftree_handler_cmdline_parse(struct image_data *data, int opt, - char *optarg) -{ - switch(opt) { - case 'o': - printf("using oftree %s\n", optarg); - data->oftree = optarg; - return 0; - default: - return 1; - } -} - -static struct image_handler of_handler = { - .cmdline_options = "o:", - .cmdline_parse = oftree_handler_cmdline_parse, - .help_string = " -o use oftree", -}; - -static int oftree_register_image_handler(void) -{ - return register_image_handler(&of_handler); -} - -late_initcall(oftree_register_image_handler); -#endif diff --git a/include/ft_build.h b/include/ft_build.h deleted file mode 100644 index 1fb6b4d11..000000000 --- a/include/ft_build.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * OF Flat tree builder - * - */ - -#ifndef FT_BUILD_H -#define FT_BUILD_H - -#include -#include - -/* Definitions used by the flattened device tree */ -#define OF_DT_HEADER 0xd00dfeed /* marker */ -#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */ -#define OF_DT_END_NODE 0x2 /* End node */ -#define OF_DT_PROP 0x3 /* Property: name off, size, - * content */ -#define OF_DT_NOP 0x4 /* nop */ -#define OF_DT_END 0x9 - -#define OF_DT_VERSION 0x10 - -struct boot_param_header { - u32 magic; /* magic word OF_DT_HEADER */ - u32 totalsize; /* total size of DT block */ - u32 off_dt_struct; /* offset to structure */ - u32 off_dt_strings; /* offset to strings */ - u32 off_mem_rsvmap; /* offset to memory reserve map */ - u32 version; /* format version */ - u32 last_comp_version; /* last compatible version */ - /* version 2 fields below */ - u32 boot_cpuid_phys; /* Physical CPU id we're booting on */ - /* version 3 fields below */ - u32 dt_strings_size; /* size of the DT strings block */ -}; - -struct ft_cxt { - struct boot_param_header *bph; - u8 *p_rsvmap; - u8 *p_start; /* pointer to beginning of dt_struct */ - u8 *p_end; /* pointer to end of dt_strings */ - u8 *p; /* pointer to end of dt_struct and beginning of dt_strings */ -}; - -void ft_begin_node(struct ft_cxt *cxt, const char *name); -void ft_init_cxt(struct ft_cxt *cxt, void *blob); -void ft_end_node(struct ft_cxt *cxt); - -void ft_end_tree(struct ft_cxt *cxt); -void ft_finalize_tree(struct ft_cxt *cxt); - -void ft_nop(struct ft_cxt *cxt); -void ft_prop(struct ft_cxt *cxt, const char *name, const void *data, int sz); -void ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str); -void ft_prop_int(struct ft_cxt *cxt, const char *name, int val); -void ft_begin(struct ft_cxt *cxt, void *blob, int max_size); -void ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size); - -void ft_setup(void *blob, bd_t * bd, ulong initrd_start, ulong initrd_end); - -void ft_dump_blob(const void *bphp); -void ft_merge_blob(struct ft_cxt *cxt, void *blob); -void *ft_get_prop(void *bphp, const char *propname, int *szp); - -void ft_board_setup(void *blob, bd_t *bd); -void ft_cpu_setup(void *blob, bd_t *bd); -void ft_pci_setup(void *blob, bd_t *bd); - -#endif From 56442bb101597ecaf133647b2ee4707cbcdb0c97 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 14 Dec 2011 20:19:57 +0100 Subject: [PATCH 06/17] oftree: add of_fix_tree() Currently we have of_get_fixed_tree() which assumes that there is a global variable holding a oftree. This seems not very flexible, so for now introduce a of_fix_tree() which takes an fdt_header as argument and walks the list of registered of fixup functions. Signed-off-by: Sascha Hauer --- common/oftree.c | 22 +++++++++++++++------- include/of.h | 1 + 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/common/oftree.c b/common/oftree.c index 2a2f46420..a657d3166 100644 --- a/common/oftree.c +++ b/common/oftree.c @@ -293,20 +293,28 @@ int of_register_fixup(int (*fixup)(struct fdt_header *)) return 0; } -struct fdt_header *of_get_fixed_tree(void) +int of_fix_tree(struct fdt_header *fdt) { struct of_fixup *of_fixup; int ret; - if (!barebox_fdt) - return NULL; - list_for_each_entry(of_fixup, &of_fixup_list, list) { - ret = of_fixup->fixup(barebox_fdt); + ret = of_fixup->fixup(fdt); if (ret) - return NULL; + return ret; } - return barebox_fdt; + return 0; } +struct fdt_header *of_get_fixed_tree(void) +{ + int ret; + + if (!barebox_fdt) + return NULL; + ret = of_fix_tree(barebox_fdt); + if (ret) + return NULL; + return barebox_fdt; +} diff --git a/include/of.h b/include/of.h index c2661efae..609b3b587 100644 --- a/include/of.h +++ b/include/of.h @@ -8,6 +8,7 @@ extern struct fdt_header *barebox_fdt; int fdt_print(struct fdt_header *working_fdt, const char *pathp); struct fdt_header *of_get_fixed_tree(void); +int of_fix_tree(struct fdt_header *fdt); int of_register_fixup(int (*fixup)(struct fdt_header *)); int fdt_find_and_setprop(struct fdt_header *fdt, const char *node, const char *prop, From 9c11a31ce2d30ff2c8bb004cd3da794b5be56625 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 14 Dec 2011 20:18:51 +0100 Subject: [PATCH 07/17] filetype: Add oftree detection Signed-off-by: Sascha Hauer --- common/filetype.c | 3 +++ include/filetype.h | 1 + 2 files changed, 4 insertions(+) diff --git a/common/filetype.c b/common/filetype.c index 5635d40af..40faff3ad 100644 --- a/common/filetype.c +++ b/common/filetype.c @@ -36,6 +36,7 @@ static const char *filetype_str[] = { [filetype_jffs2] = "JFFS2 image", [filetype_gzip] = "gzip compressed", [filetype_bzip2] = "bzip2 compressed", + [filetype_oftree] = "open firmware flat device tree", }; const char *file_type_to_string(enum filetype f) @@ -69,6 +70,8 @@ enum filetype file_detect_type(void *_buf) if (buf8[0] == 'B' && buf8[1] == 'Z' && buf8[2] == 'h' && buf8[3] > '0' && buf8[3] <= '9') return filetype_bzip2; + if (buf[0] == be32_to_cpu(0xd00dfeed)) + return filetype_oftree; return filetype_unknown; } diff --git a/include/filetype.h b/include/filetype.h index 64d32ef8b..88f31dfe3 100644 --- a/include/filetype.h +++ b/include/filetype.h @@ -14,6 +14,7 @@ enum filetype { filetype_jffs2, filetype_gzip, filetype_bzip2, + filetype_oftree, }; const char *file_type_to_string(enum filetype f); From 90d036d62cc8e2fb274d02c8d6b331d61bd5ba55 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 30 Nov 2011 15:12:47 +0100 Subject: [PATCH 08/17] uncompress: implement uncompress_fd_to_buf Signed-off-by: Sascha Hauer --- lib/uncompress.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/uncompress.c b/lib/uncompress.c index beb96d167..cdfebe917 100644 --- a/lib/uncompress.c +++ b/lib/uncompress.c @@ -158,3 +158,11 @@ int uncompress_fd_to_fd(int infd, int outfd, NULL, error_fn); } + +int uncompress_fd_to_buf(int infd, void *output, + void(*error_fn)(char *x)) +{ + uncompress_infd = infd; + + return uncompress(NULL, 0, fill_fd, NULL, output, NULL, error_fn); +} From 4c41e245cfaf9f85af31c26394cf6549392f89f5 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 12 Apr 2011 16:38:20 +0200 Subject: [PATCH 09/17] libbb: add read_full/write_full functions These functions read/write all data or return with an error. Signed-off-by: Sascha Hauer --- include/libbb.h | 3 +++ lib/libbb.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/include/libbb.h b/include/libbb.h index 2d17c3fc9..110e8ec39 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -32,4 +32,7 @@ int process_escape_sequence(const char *source, char *dest, int destlen); char *simple_itoa(unsigned int i); +int write_full(int fd, void *buf, size_t size); +int read_full(int fd, void *buf, size_t size); + #endif /* __LIBBB_H */ diff --git a/lib/libbb.c b/lib/libbb.c index 3d0220263..9a0a60bdb 100644 --- a/lib/libbb.c +++ b/lib/libbb.c @@ -127,3 +127,53 @@ char *simple_itoa(unsigned int i) return p + 1; } EXPORT_SYMBOL(simple_itoa); + +/* + * write_full - write to filedescriptor + * + * Like write, but guarantees to write the full buffer out, else + * it returns with an error. + */ +int write_full(int fd, void *buf, size_t size) +{ + size_t insize = size; + int now; + + while (size) { + now = write(fd, buf, size); + if (now <= 0) + return now; + size -= now; + buf += now; + } + + return insize; +} +EXPORT_SYMBOL(write_full); + +/* + * read_full - read from filedescriptor + * + * Like read, but this function only returns less bytes than + * requested when the end of file is reached. + */ +int read_full(int fd, void *buf, size_t size) +{ + size_t insize = size; + int now; + int total = 0; + + while (size) { + now = read(fd, buf, size); + if (now == 0) + return total; + if (now < 0) + return now; + total += now; + size -= now; + buf += now; + } + + return insize; +} +EXPORT_SYMBOL(read_full); From 296cd8d6380f775d0f7b59bd78d3421327ebbe9e Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 12 Dec 2011 10:43:33 +0100 Subject: [PATCH 10/17] ARM: call start_linux directly with initrd start/size and oftree whoever calls this function is not necessarily aware of a struct image_data, so remove the dependency from the function. Signed-off-by: Sascha Hauer --- arch/arm/include/asm/armlinux.h | 3 ++- arch/arm/lib/armlinux.c | 20 ++++++++++---------- arch/arm/lib/bootm.c | 3 ++- arch/arm/lib/bootu.c | 8 +++++++- arch/arm/lib/bootz.c | 7 ++++++- 5 files changed, 27 insertions(+), 14 deletions(-) diff --git a/arch/arm/include/asm/armlinux.h b/arch/arm/include/asm/armlinux.h index ba3a424e2..9ca1e4b6d 100644 --- a/arch/arm/include/asm/armlinux.h +++ b/arch/arm/include/asm/armlinux.h @@ -29,6 +29,7 @@ static inline void armlinux_set_serial(u64 serial) struct image_data; -void start_linux(void *adr, int swap, struct image_data *data); +void start_linux(void *adr, int swap, unsigned long initrd_address, + unsigned long initrd_size, void *oftree); #endif /* __ARCH_ARMLINUX_H */ diff --git a/arch/arm/lib/armlinux.c b/arch/arm/lib/armlinux.c index bd9b72a8a..1d210d1a4 100644 --- a/arch/arm/lib/armlinux.c +++ b/arch/arm/lib/armlinux.c @@ -224,7 +224,8 @@ static void setup_end_tag (void) params->hdr.size = 0; } -static void setup_tags(struct image_data *data, int swap) +static void setup_tags(unsigned long initrd_address, + unsigned long initrd_size, int swap) { const char *commandline = getenv("bootargs"); @@ -232,8 +233,8 @@ static void setup_tags(struct image_data *data, int swap) setup_memory_tags(); setup_commandline_tag(commandline, swap); - if (data && (data->initrd_size > 0)) - setup_initrd_tag(data->initrd_address, data->initrd_size); + if (initrd_size) + setup_initrd_tag(initrd_address, initrd_size); setup_revision_tag(); setup_serial_tag(); @@ -249,17 +250,16 @@ void armlinux_set_bootparams(void *params) armlinux_bootparams = params; } -void start_linux(void *adr, int swap, struct image_data *data) +void start_linux(void *adr, int swap, unsigned long initrd_address, + unsigned long initrd_size, void *oftree) { void (*kernel)(int zero, int arch, void *params) = adr; void *params = NULL; -#ifdef CONFIG_OFTREE - params = of_get_fixed_tree(); - if (params) + + if (oftree) { printf("booting Linux kernel with devicetree\n"); -#endif - if (!params) { - setup_tags(data, swap); + } else { + setup_tags(initrd_address, initrd_size, swap); params = armlinux_bootparams; } diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 031a2698e..1de22bf81 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -31,7 +31,8 @@ static int do_bootm_linux(struct image_data *data) /* we assume that the kernel is in place */ printf("\nStarting kernel %s...\n\n", data->initrd ? "with initrd " : ""); - start_linux(theKernel, 0, data); + start_linux((void *)theKernel, 0, data->initrd_address, data->initrd_size, + data->oftree); return -1; } diff --git a/arch/arm/lib/bootu.c b/arch/arm/lib/bootu.c index e97ded0e4..89d793af9 100644 --- a/arch/arm/lib/bootu.c +++ b/arch/arm/lib/bootu.c @@ -3,12 +3,14 @@ #include #include #include +#include #include static int do_bootu(struct command *cmdtp, int argc, char *argv[]) { int fd; void *kernel = NULL; + void *oftree = NULL; if (argc != 2) { barebox_cmd_usage(cmdtp); @@ -22,7 +24,11 @@ static int do_bootu(struct command *cmdtp, int argc, char *argv[]) if (!kernel) kernel = (void *)simple_strtoul(argv[1], NULL, 0); - start_linux(kernel, 0, NULL); +#ifdef CONFIG_OFTREE + oftree = of_get_fixed_tree(); +#endif + + start_linux(kernel, 0, 0, 0, oftree); return 1; } diff --git a/arch/arm/lib/bootz.c b/arch/arm/lib/bootz.c index 956ea8286..40facf677 100644 --- a/arch/arm/lib/bootz.c +++ b/arch/arm/lib/bootz.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,7 @@ static int do_bootz(struct command *cmdtp, int argc, char *argv[]) int fd, ret, swap = 0; struct zimage_header __header, *header; void *zimage; + void *oftree = NULL; u32 end; int usemap = 0; struct memory_bank *bank = list_first_entry(&memory_banks, struct memory_bank, list); @@ -105,8 +107,11 @@ static int do_bootz(struct command *cmdtp, int argc, char *argv[]) } printf("loaded zImage from %s with size %d\n", argv[1], end); +#ifdef CONFIG_OFTREE + oftree = of_get_fixed_tree(); +#endif - start_linux(zimage, swap, NULL); + start_linux(zimage, swap, 0, 0, oftree); return 0; From 390249968c4eeaceddd26a1cdeca5728f5b87b18 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 6 Dec 2011 08:40:44 +0100 Subject: [PATCH 11/17] reimplement uImage code Provide a new API for accessing uImages which makes it easy for commands to open images, verify them, load to (free) sdram regions and show information about uImages. - We now do not load the image to malloced space anymore. - The data in the header is now stored in cpu native endianess after uimage_open which makes it easy to access the header data. - uImage can be loaded to dynamically allocated sdram regions. Signed-off-by: Sascha Hauer --- common/Makefile | 1 + common/uimage.c | 505 ++++++++++++++++++++++++++++++++++++++++++++++++ include/image.h | 30 +++ 3 files changed, 536 insertions(+) create mode 100644 common/uimage.c diff --git a/common/Makefile b/common/Makefile index 237c6b043..e02650ba4 100644 --- a/common/Makefile +++ b/common/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_CONSOLE_SIMPLE) += console_simple.o obj-$(CONFIG_DIGEST) += digest.o obj-$(CONFIG_ENVIRONMENT_VARIABLES) += env.o obj-$(CONFIG_CMD_BOOTM) += image.o +obj-$(CONFIG_CMD_BOOTM) += uimage.o obj-y += startup.o obj-y += misc.o obj-y += memsize.o diff --git a/common/uimage.c b/common/uimage.c new file mode 100644 index 000000000..28791b541 --- /dev/null +++ b/common/uimage.c @@ -0,0 +1,505 @@ +/* + * uimage.c - uimage handling code + * + * Copyright (c) 2011 Sascha Hauer , Pengutronix + * + * partly based on U-Boot uImage code + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_UIMAGE_MULTI +static inline int uimage_is_multi_image(struct uimage_handle *handle) +{ + return (handle->header.ih_type == IH_TYPE_MULTI) ? 1 : 0; +} +#else +static inline int uimage_is_multi_image(struct uimage_handle *handle) +{ + return 0; +} +#endif + +void uimage_print_contents(struct uimage_handle *handle) +{ + struct image_header *hdr = &handle->header; +#if defined(CONFIG_TIMESTAMP) + struct rtc_time tm; +#endif + printf(" Image Name: %.*s\n", IH_NMLEN, hdr->ih_name); +#if defined(CONFIG_TIMESTAMP) + printf(" Created: "); + to_tm(hdr->ih_time, &tm); + printf("%4d-%02d-%02d %2d:%02d:%02d UTC\n", + tm.tm_year, tm.tm_mon, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); +#endif +#if defined(CONFIG_CMD_BOOTM_SHOW_TYPE) + printf(" OS: %s\n", image_get_os_name(hdr->ih_os)); + printf(" Architecture: %s\n", image_get_arch_name(hdr->ih_arch)); + printf(" Type: %s\n", image_get_type_name(hdr->ih_type)); + printf(" Compression: %s\n", image_get_comp_name(hdr->ih_comp)); +#endif + printf(" Data Size: %d Bytes = %s\n", hdr->ih_size, + size_human_readable(hdr->ih_size)); + printf(" Load Address: %08x\n", hdr->ih_load); + printf(" Entry Point: %08x\n", hdr->ih_ep); + + if (uimage_is_multi_image(handle)) { + int i; + + printf(" Contents:\n"); + + for (i = 0; i < handle->nb_data_entries; i++) { + struct uimage_handle_data *data = &handle->ihd[i]; + + printf(" Image %d: %ld (%s)\n", i, + data->len, size_human_readable(data->len)); + } + } +} +EXPORT_SYMBOL(uimage_print_contents); + +size_t uimage_get_size(struct uimage_handle *handle, unsigned int image_no) +{ + if (image_no >= handle->nb_data_entries) + return -EINVAL; + + return handle->ihd[image_no].len; +} +EXPORT_SYMBOL(uimage_get_size); + +/* + * open a uimage. This will check the header contents and + * return a handle to the uImage + */ +struct uimage_handle *uimage_open(const char *filename) +{ + int fd; + uint32_t checksum; + struct uimage_handle *handle; + struct image_header *header; + int i; + int ret; + + fd = open(filename, O_RDONLY); + if (fd < 0) { + printf("could not open: %s\n", errno_str()); + return NULL; + } + + handle = xzalloc(sizeof(struct uimage_handle)); + header = &handle->header; + + if (read(fd, header, sizeof(*header)) < 0) { + printf("could not read: %s\n", errno_str()); + goto err_out; + } + + if (uimage_to_cpu(header->ih_magic) != IH_MAGIC) { + printf("Bad Magic Number\n"); + goto err_out; + } + + checksum = uimage_to_cpu(header->ih_hcrc); + header->ih_hcrc = 0; + + if (crc32(0, header, sizeof(*header)) != checksum) { + printf("Bad Header Checksum\n"); + goto err_out; + } + + /* convert header to cpu native endianess */ + header->ih_magic = uimage_to_cpu(header->ih_magic); + header->ih_hcrc = uimage_to_cpu(header->ih_hcrc); + header->ih_time = uimage_to_cpu(header->ih_time); + header->ih_size = uimage_to_cpu(header->ih_size); + header->ih_load = uimage_to_cpu(header->ih_load); + header->ih_ep = uimage_to_cpu(header->ih_ep); + header->ih_dcrc = uimage_to_cpu(header->ih_dcrc); + + if (header->ih_name[0]) { + handle->name = xzalloc(IH_NMLEN + 1); + strncpy(handle->name, header->ih_name, IH_NMLEN); + } else { + handle->name = xstrdup(filename); + } + + if (uimage_is_multi_image(handle)) { + size_t offset; + + for (i = 0; i < MAX_MULTI_IMAGE_COUNT; i++) { + u32 size; + + ret = read(fd, &size, sizeof(size)); + if (ret < 0) + goto err_out; + + if (!size) + break; + + handle->ihd[i].len = uimage_to_cpu(size); + } + + handle->nb_data_entries = i; + + /* offset of the first image in a multifile image */ + offset = 0; + + for (i = 0; i < handle->nb_data_entries; i++) { + handle->ihd[i].offset = offset; + offset += (handle->ihd[i].len + 3) & ~3; + } + + handle->data_offset = sizeof(struct image_header) + + sizeof(u32) * (handle->nb_data_entries + 1); + } else { + handle->ihd[0].offset = 0; + handle->ihd[0].len = header->ih_size; + handle->nb_data_entries = 1; + handle->data_offset = sizeof(struct image_header); + } + + /* + * fd is now at the first data word + */ + handle->fd = fd; + + return handle; +err_out: + close(fd); + free(handle); + return NULL; +} +EXPORT_SYMBOL(uimage_open); + +/* + * close a uImage previously opened with uimage_open + */ +void uimage_close(struct uimage_handle *handle) +{ + close(handle->fd); + free(handle->name); + free(handle); +} +EXPORT_SYMBOL(uimage_close); + +static int uimage_fd; + +static int uimage_fill(void *buf, unsigned int len) +{ + return read_full(uimage_fd, buf, len); +} + +static int uncompress_copy(unsigned char *inbuf_unused, int len, + int(*fill)(void*, unsigned int), + int(*flush)(void*, unsigned int), + unsigned char *outbuf_unused, + int *pos, + void(*error_fn)(char *x)) +{ + int ret; + void *buf = xmalloc(PAGE_SIZE); + + while (len) { + int now = min(len, PAGE_SIZE); + ret = fill(buf, now); + if (ret < 0) + goto err; + ret = flush(buf, now); + if (ret < 0) + goto err; + len -= now; + } + + ret = 0; +err: + free(buf); + return ret; +} + +/* + * Verify the data crc of an uImage + */ +int uimage_verify(struct uimage_handle *handle) +{ + u32 crc = 0; + int len, ret; + void *buf; + + ret = lseek(handle->fd, sizeof(struct image_header), SEEK_SET); + if (ret < 0) + return ret; + + buf = xmalloc(PAGE_SIZE); + + len = handle->header.ih_size; + while (len) { + int now = min(len, PAGE_SIZE); + ret = read(handle->fd, buf, now); + if (ret < 0) + goto err; + crc = crc32(crc, buf, now); + len -= ret; + } + + if (crc != handle->header.ih_dcrc) { + printf("Bad Data CRC: 0x%08x != 0x%08x\n", + crc, handle->header.ih_dcrc); + ret = -EINVAL; + goto err; + } + + ret = 0; +err: + free(buf); + + return ret; +} +EXPORT_SYMBOL(uimage_verify); + +/* + * Load a uimage, flushing output to flush function + */ +int uimage_load(struct uimage_handle *handle, unsigned int image_no, + int(*flush)(void*, unsigned int)) +{ + image_header_t *hdr = &handle->header; + struct uimage_handle_data *iha; + int ret; + int (*uncompress_fn)(unsigned char *inbuf, int len, + int(*fill)(void*, unsigned int), + int(*flush)(void*, unsigned int), + unsigned char *output, + int *pos, + void(*error)(char *x)); + + if (image_no >= handle->nb_data_entries) + return -EINVAL; + + iha = &handle->ihd[image_no]; + + ret = lseek(handle->fd, iha->offset + handle->data_offset, + SEEK_SET); + if (ret < 0) + return ret; + + if (hdr->ih_comp == IH_COMP_NONE) + uncompress_fn = uncompress_copy; + else + uncompress_fn = uncompress; + + uimage_fd = handle->fd; + + ret = uncompress_fn(NULL, iha->len, uimage_fill, flush, + NULL, NULL, + uncompress_err_stdout); + return ret; +} +EXPORT_SYMBOL(uimage_load); + +static void *uimage_buf; +static size_t uimage_size; +static struct resource *uimage_resource; + +static int uimage_sdram_flush(void *buf, unsigned int len) +{ + if (uimage_size + len > uimage_resource->size) { + resource_size_t start = uimage_resource->start; + resource_size_t size = uimage_resource->size + len; + release_sdram_region(uimage_resource); + + uimage_resource = request_sdram_region("uimage", + start, size); + if (!uimage_resource) { + printf("unable to request SDRAM 0x%08x-0x%08x\n", + start, start + size - 1); + return -ENOMEM; + } + } + + memcpy(uimage_buf + uimage_size, buf, len); + + uimage_size += len; + + return len; +} + +#define BUFSIZ (PAGE_SIZE * 2) + +struct resource *file_to_sdram(const char *filename, unsigned long adr) +{ + struct resource *res; + size_t size = BUFSIZ; + size_t ofs = 0; + int fd; + + fd = open(filename, O_RDONLY); + if (fd < 0) + return NULL; + + while (1) { + size_t now; + + res = request_sdram_region("image", adr, size); + if (!res) { + printf("unable to request SDRAM 0x%08lx-0x%08lx\n", + adr, adr + size - 1); + goto out; + } + + now = read_full(fd, (void *)(res->start + ofs), BUFSIZ); + if (now < 0) { + release_sdram_region(res); + res = NULL; + goto out; + } + if (now < BUFSIZ) + goto out; + + release_sdram_region(res); + + ofs += BUFSIZ; + size += BUFSIZ; + } +out: + close(fd); + + return res; +} + +/* + * Load an uImage to a dynamically allocated sdram resource. + * the resource must be freed afterwards with release_sdram_region + */ +struct resource *uimage_load_to_sdram(struct uimage_handle *handle, + int image_no, unsigned long load_address) +{ + int ret; + size_t size; + resource_size_t start = (resource_size_t)load_address; + + uimage_buf = (void *)load_address; + uimage_size = 0; + + size = uimage_get_size(handle, image_no); + if (size < 0) + return NULL; + + uimage_resource = request_sdram_region("uimage", + start, size); + if (!uimage_resource) { + printf("unable to request SDRAM 0x%08x-0x%08x\n", + start, start + size - 1); + return NULL; + } + + ret = uimage_load(handle, image_no, uimage_sdram_flush); + if (ret) { + release_sdram_region(uimage_resource); + return NULL; + } + + return uimage_resource; +} +EXPORT_SYMBOL(uimage_load_to_sdram); + +void *uimage_load_to_buf(struct uimage_handle *handle, int image_no, + size_t *outsize) +{ + u32 size; + int ret; + struct uimage_handle_data *ihd; + char ftbuf[128]; + enum filetype ft; + void *buf; + + if (image_no >= handle->nb_data_entries) + return NULL; + + ihd = &handle->ihd[image_no]; + + ret = lseek(handle->fd, ihd->offset + handle->data_offset, + SEEK_SET); + if (ret < 0) + return NULL; + + if (handle->header.ih_comp == IH_COMP_NONE) { + buf = malloc(ihd->len); + if (!buf) + return NULL; + + ret = read_full(handle->fd, buf, ihd->len); + if (ret < ihd->len) { + free(buf); + return NULL; + } + goto out; + } + + ret = read(handle->fd, ftbuf, 128); + if (ret < 0) + return NULL; + + ft = file_detect_type(ftbuf); + if ((int)ft < 0) + return NULL; + + if (ft != filetype_gzip) + return NULL; + + ret = lseek(handle->fd, ihd->offset + handle->data_offset + + ihd->len - 4, + SEEK_SET); + if (ret < 0) + return NULL; + + ret = read(handle->fd, &size, 4); + if (ret < 0) + return NULL; + + size = le32_to_cpu(size); + + ret = lseek(handle->fd, ihd->offset + handle->data_offset, + SEEK_SET); + if (ret < 0) + return NULL; + + buf = malloc(size); + ret = uncompress_fd_to_buf(handle->fd, buf, uncompress_err_stdout); + if (ret) { + free(buf); + return NULL; + } + +out: + if (outsize) + *outsize = size; + + return buf; +} diff --git a/include/image.h b/include/image.h index f3a9949e5..5e9b6e26e 100644 --- a/include/image.h +++ b/include/image.h @@ -349,4 +349,34 @@ struct image_handle_data* gen_image_handle_data(void* data, ulong len); */ int relocate_image(struct image_handle *handle, void *load_address); +struct uimage_handle_data { + size_t offset; /* offset in the image */ + ulong len; +}; + +struct uimage_handle *uimage_open(const char *filename); +void uimage_close(struct uimage_handle *handle); +int uimage_verify(struct uimage_handle *handle); +int uimage_load(struct uimage_handle *handle, unsigned int image_no, + int(*flush)(void*, unsigned int)); +void uimage_print_contents(struct uimage_handle *handle); +size_t uimage_get_size(struct uimage_handle *handle, unsigned int image_no); +struct resource *uimage_load_to_sdram(struct uimage_handle *handle, + int image_no, unsigned long load_address); +void *uimage_load_to_buf(struct uimage_handle *handle, int image_no, + size_t *size); +struct resource *file_to_sdram(const char *filename, unsigned long adr); +#define MAX_MULTI_IMAGE_COUNT 16 + +struct uimage_handle { + struct image_header header; + char *name; + struct uimage_handle_data ihd[MAX_MULTI_IMAGE_COUNT]; + int nb_data_entries; + size_t data_offset; + int fd; +}; + +#define UIMAGE_INVALID_ADDRESS (~0) + #endif /* __IMAGE_H__ */ From d4e5c6b8a03d31c00084d38e40d9811267f00289 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 6 Dec 2011 08:53:26 +0100 Subject: [PATCH 12/17] bootm: use new uimage code This switches the bootm code to the new uimage code. Also bootm can now handle other types of images than uImages. Currently the only architecture making use of this is arm which allows to boot zImages, raw images and barebox images. I intended to make a more bisectable series from this but I failed becuase there are many dependencies and no matter how I tried the patches grew bigger and and bigger. So I decided to put this all in a single patch. Signed-off-by: Sascha Hauer --- arch/arm/lib/bootm.c | 222 +++++++++++++- arch/blackfin/lib/blackfin_linux.c | 12 +- arch/nios2/lib/bootm.c | 11 +- arch/ppc/lib/ppclinux.c | 16 +- commands/Kconfig | 22 ++ commands/bootm.c | 461 +++++++++++++++++++++-------- include/boot.h | 62 +++- 7 files changed, 638 insertions(+), 168 deletions(-) diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 1de22bf81..d8bb701c4 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include @@ -18,33 +20,223 @@ #include #include -static int do_bootm_linux(struct image_data *data) +static int __do_bootm_linux(struct image_data *data, int swap) { - void (*theKernel)(int zero, int arch, void *params); - image_header_t *os_header = &data->os->header; + unsigned long kernel; + unsigned long initrd_start = 0, initrd_size = 0; + struct memory_bank *bank; + unsigned long load_address; - theKernel = (void *)image_get_ep(os_header); + if (data->os_res) { + load_address = data->os_res->start; + } else if (data->os_address != UIMAGE_INVALID_ADDRESS) { + load_address = data->os_address; + } else { + bank = list_first_entry(&memory_banks, + struct memory_bank, list); + load_address = bank->start + SZ_32K; + if (bootm_verbose(data)) + printf("no os load address, defaulting to 0x%08lx\n", + load_address); + } - debug("## Transferring control to Linux (at address 0x%p) ...\n", - theKernel); + if (!data->os_res && data->os) { + data->os_res = uimage_load_to_sdram(data->os, + data->os_num, load_address); + if (!data->os_res) + return -ENOMEM; + } - /* we assume that the kernel is in place */ - printf("\nStarting kernel %s...\n\n", data->initrd ? "with initrd " : ""); + if (!data->os_res) { + data->os_res = file_to_sdram(data->os_file, load_address); + if (!data->os_res) + return -ENOMEM; + } - start_linux((void *)theKernel, 0, data->initrd_address, data->initrd_size, - data->oftree); + kernel = data->os_res->start + data->os_entry; - return -1; + if (data->initrd_file && data->initrd_address == UIMAGE_INVALID_ADDRESS) { + initrd_start = data->os_res->start + SZ_8M; + + if (bootm_verbose(data)) { + printf("no initrd load address, defaulting to 0x%08lx\n", + initrd_start); + } + } + + if (data->initrd) { + data->initrd_res = uimage_load_to_sdram(data->initrd, + data->initrd_num, initrd_start); + if (!data->initrd_res) + return -ENOMEM; + } else if (data->initrd_file) { + data->initrd_res = file_to_sdram(data->initrd_file, initrd_start); + if (!data->initrd_res) + return -ENOMEM; + } + + if (data->initrd_res) { + initrd_start = data->initrd_res->start; + initrd_size = data->initrd_res->size; + } + + if (bootm_verbose(data)) { + printf("\nStarting kernel at 0x%08lx", kernel); + if (initrd_size) + printf(", initrd at 0x%08lx", initrd_start); + if (data->oftree) + printf(", oftree at 0x%p", data->oftree); + printf("...\n"); + } + + start_linux((void *)kernel, swap, initrd_start, initrd_size, data->oftree); + + reset_cpu(0); + + return -ERESTARTSYS; } -static struct image_handler handler = { +static int do_bootm_linux(struct image_data *data) +{ + return __do_bootm_linux(data, 0); +} + +static struct image_handler uimage_handler = { + .name = "ARM Linux uImage", .bootm = do_bootm_linux, - .image_type = IH_OS_LINUX, + .filetype = filetype_uimage, + .ih_os = IH_OS_LINUX, +}; + +static struct image_handler rawimage_handler = { + .name = "ARM raw image", + .bootm = do_bootm_linux, + .filetype = filetype_unknown, +}; + +struct zimage_header { + u32 unused[9]; + u32 magic; + u32 start; + u32 end; +}; + +#define ZIMAGE_MAGIC 0x016F2818 + +static int do_bootz_linux(struct image_data *data) +{ + int fd, ret, swap = 0; + struct zimage_header __header, *header; + void *zimage; + u32 end; + unsigned long load_address = data->os_address; + + if (load_address == UIMAGE_INVALID_ADDRESS) { + struct memory_bank *bank = list_first_entry(&memory_banks, + struct memory_bank, list); + data->os_address = bank->start + SZ_8M; + if (bootm_verbose(data)) + printf("no os load address, defaulting to 0x%08lx\n", + load_address); + } + + fd = open(data->os_file, O_RDONLY); + if (fd < 0) { + perror("open"); + return 1; + } + + header = &__header; + ret = read(fd, header, sizeof(*header)); + if (ret < sizeof(*header)) { + printf("could not read %s\n", data->os_file); + goto err_out; + } + + switch (header->magic) { + case swab32(ZIMAGE_MAGIC): + swap = 1; + /* fall through */ + case ZIMAGE_MAGIC: + break; + default: + printf("invalid magic 0x%08x\n", header->magic); + ret = -EINVAL; + goto err_out; + } + + end = header->end; + + if (swap) + end = swab32(end); + + data->os_res = request_sdram_region("zimage", load_address, end); + if (!data->os_res) { + ret = -ENOMEM; + goto err_out; + } + + zimage = (void *)data->os_res->start; + + memcpy(zimage, header, sizeof(*header)); + + ret = read_full(fd, zimage + sizeof(*header), end - sizeof(*header)); + if (ret < 0) + goto err_out; + if (ret < end - sizeof(*header)) { + printf("premature end of image\n"); + ret = -EIO; + goto err_out; + } + + if (swap) { + void *ptr; + for (ptr = zimage; ptr < zimage + end; ptr += 4) + *(u32 *)ptr = swab32(*(u32 *)ptr); + } + + return __do_bootm_linux(data, swap); + +err_out: + close(fd); + + return ret; +} + +static struct image_handler zimage_handler = { + .name = "ARM zImage", + .bootm = do_bootz_linux, + .filetype = filetype_arm_zimage, +}; + +static int do_bootm_barebox(struct image_data *data) +{ + void (*barebox)(void); + + barebox = read_file(data->os_file, NULL); + if (!barebox) + return -EINVAL; + + shutdown_barebox(); + + barebox(); + + reset_cpu(0); +} + +static struct image_handler barebox_handler = { + .name = "ARM barebox", + .bootm = do_bootm_barebox, + .filetype = filetype_arm_barebox, }; static int armlinux_register_image_handler(void) { - return register_image_handler(&handler); -} + register_image_handler(&barebox_handler); + register_image_handler(&uimage_handler); + register_image_handler(&rawimage_handler); + register_image_handler(&zimage_handler); + return 0; +} late_initcall(armlinux_register_image_handler); diff --git a/arch/blackfin/lib/blackfin_linux.c b/arch/blackfin/lib/blackfin_linux.c index 9da9ec4e5..458d1b180 100644 --- a/arch/blackfin/lib/blackfin_linux.c +++ b/arch/blackfin/lib/blackfin_linux.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -44,10 +45,11 @@ static int do_bootm_linux(struct image_data *idata) int (*appl)(char *cmdline); const char *cmdline = getenv("bootargs"); char *cmdlinedest = (char *) CMD_LINE_ADDR; - struct image_handle *os_handle = idata->os; - image_header_t *os_header = &os_handle->header; - appl = (int (*)(char *))image_get_ep(os_header); + if (!idata->os_res) + return -EINVAL; + + appl = (void *)(idata->os_address + idata->os_entry); printf("Starting Kernel at 0x%p\n", appl); icache_disable(); @@ -63,8 +65,10 @@ static int do_bootm_linux(struct image_data *idata) } static struct image_handler handler = { + .name = "Blackfin Linux", .bootm = do_bootm_linux, - .image_type = IH_OS_LINUX, + .filetype = filetype_uimage, + .ih_os = IH_OS_LINUX, }; static int bfinlinux_register_image_handler(void) diff --git a/arch/nios2/lib/bootm.c b/arch/nios2/lib/bootm.c index b5b344f49..1cd43c81a 100644 --- a/arch/nios2/lib/bootm.c +++ b/arch/nios2/lib/bootm.c @@ -31,17 +31,20 @@ #include #include #include +#include #include #define NIOS_MAGIC 0x534f494e /* enable command line and initrd passing */ static int do_bootm_linux(struct image_data *idata) { - image_header_t *os_header = &idata->os->header; void (*kernel)(int, int, int, const char *); const char *commandline = getenv ("bootargs"); - kernel = (void (*)(int, int, int, const char *))ntohl(os_header->ih_ep); + if (!idata->os_res) + return -EINVAL; + + kernel = (void *)(idata->os_address + idata->os_entry); /* kernel parameters passing * r4 : NIOS magic @@ -63,8 +66,10 @@ static int do_bootm_linux(struct image_data *idata) } static struct image_handler handler = { + .name = "NIOS2 Linux", .bootm = do_bootm_linux, - .image_type = IH_OS_LINUX, + .filetype = filetype_uimage, + .ih_os = IH_OS_LINUX, }; int nios2_register_image_handler(void) diff --git a/arch/ppc/lib/ppclinux.c b/arch/ppc/lib/ppclinux.c index f7d395060..3c1b3fa00 100644 --- a/arch/ppc/lib/ppclinux.c +++ b/arch/ppc/lib/ppclinux.c @@ -11,18 +11,15 @@ #include #include -#ifdef CONFIG_OF_FLAT_TREE -#include -#endif -extern bd_t *bd; - static int do_bootm_linux(struct image_data *data) { void (*kernel)(void *, void *, unsigned long, unsigned long, unsigned long); - struct image_header *os_header = &data->os->header; - kernel = (void *)image_get_ep(os_header); + if (!data->os_res) + return -EINVAL; + + kernel = (void *)(data->os_address + data->os_entry); /* * Linux Kernel Parameters (passing device tree): @@ -41,8 +38,10 @@ static int do_bootm_linux(struct image_data *data) } static struct image_handler handler = { + .name = "PowerPC Linux", .bootm = do_bootm_linux, - .image_type = IH_OS_LINUX, + .filetype = filetype_uimage, + .ih_os = IH_OS_LINUX, }; static int ppclinux_register_image_handler(void) @@ -51,4 +50,3 @@ static int ppclinux_register_image_handler(void) } late_initcall(ppclinux_register_image_handler); - diff --git a/commands/Kconfig b/commands/Kconfig index ebc9c7f2d..3cf2d085f 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -310,6 +310,28 @@ config CMD_BOOTM_SHOW_TYPE depends on CMD_BOOTM prompt "show image information" +config CMD_BOOTM_VERBOSE + bool + prompt "bootm verbose support" + depends on CMD_BOOTM + help + support verbose bootm (-v switch) + +config CMD_BOOTM_INITRD + bool + prompt "bootm initrd support" + depends on CMD_BOOTM + help + support initrds in bootm + +config CMD_BOOTM_OFTREE_UIMAGE + bool + prompt "support passing oftree uImages" + depends on CMD_BOOTM + help + Support using oftree uImages. Without this only raw oftree + blobs can be used. + config CMD_IMINFO bool prompt "iminfo" diff --git a/commands/bootm.c b/commands/bootm.c index 265ad4637..d9805866b 100644 --- a/commands/bootm.c +++ b/commands/bootm.c @@ -39,53 +39,29 @@ #include #include #include +#include #include #include +#include #include #include +#include +#include #include -struct image_handle_data* image_handle_data_get_by_num(struct image_handle* handle, int num) -{ - if (!handle || num < 0 || num >= handle->nb_data_entries) - return NULL; +static LIST_HEAD(handler_list); - return &handle->data_entries[num]; +#ifdef CONFIG_CMD_BOOTM_INITRD +static inline int bootm_initrd(struct image_data *data) +{ + return data->initrd ? 1 : 0; } - -int relocate_image(struct image_handle *handle, void *load_address) +#else +static inline int bootm_initrd(struct image_data *data) { - image_header_t *hdr = &handle->header; - unsigned long len = image_get_size(hdr); - struct image_handle_data *iha; - void *data; - int ret; - - iha = image_handle_data_get_by_num(handle, 0); - data = iha->data; - - switch (image_get_comp(hdr)) { - case IH_COMP_NONE: - if (load_address == data) { - printf (" XIP ... "); - } else { - memmove(load_address, data, len); - } - break; - default: - printf (" Uncompressing ... "); - ret = uncompress(data, len, NULL, NULL, load_address, NULL, - uncompress_err_stdout); - if (ret) - return ret; - break; - } - return 0; } -EXPORT_SYMBOL(relocate_image); - -static LIST_HEAD(handler_list); +#endif int register_image_handler(struct image_handler *handler) { @@ -93,148 +69,380 @@ int register_image_handler(struct image_handler *handler) return 0; } -/* - * generate a image_handle from a multi_image - * this image_handle can be freed by unmap_image - */ -static struct image_handle *get_fake_image_handle(struct image_data *data, int num) +#define UIMAGE_SOME_ADDRESS (UIMAGE_INVALID_ADDRESS - 1) + +static int bootm_open_os_uimage(struct image_data *data) { - struct image_handle *handle; - struct image_handle_data* iha; - image_header_t *header; + int ret; - iha = image_handle_data_get_by_num(data->os, num); + data->os = uimage_open(data->os_file); + if (!data->os) + return -EINVAL; - handle = xzalloc(sizeof(struct image_handle)); - header = &handle->header; - handle->data_entries = gen_image_handle_data(iha->data, iha->len); - handle->nb_data_entries = 1; - header->ih_size = cpu_to_uimage(iha->len); - handle->data = handle->data_entries[0].data; + if (data->verify) { + ret = uimage_verify(data->os); + if (ret) { + printf("Checking data crc failed with %s\n", + strerror(-ret)); + return ret; + } + } - return handle; + uimage_print_contents(data->os); + + if (data->os->header.ih_arch != IH_ARCH) { + printf("Unsupported Architecture 0x%x\n", + data->os->header.ih_arch); + return -EINVAL; + } + + if (data->os_address == UIMAGE_SOME_ADDRESS) + data->os_address = data->os->header.ih_load; + + if (data->os_address != UIMAGE_INVALID_ADDRESS) { + data->os_res = uimage_load_to_sdram(data->os, 0, + data->os_address); + if (!data->os_res) + return -ENOMEM; + } + + return 0; +} + +static int bootm_open_initrd_uimage(struct image_data *data) +{ + int ret; + + if (!data->initrd_file) + return 0; + + if (strcmp(data->os_file, data->initrd_file)) { + data->initrd = uimage_open(data->initrd_file); + if (!data->initrd) + return -EINVAL; + + if (data->verify) { + ret = uimage_verify(data->initrd); + if (ret) { + printf("Checking data crc failed with %s\n", + strerror(-ret)); + } + } + uimage_print_contents(data->initrd); + } else { + data->initrd = data->os; + } + + if (data->initrd_address == UIMAGE_SOME_ADDRESS) + data->initrd_address = data->initrd->header.ih_load; + + if (data->initrd_address != UIMAGE_INVALID_ADDRESS) { + data->initrd_res = uimage_load_to_sdram(data->initrd, + data->initrd_num, + data->initrd_address); + if (!data->initrd_res) + return -ENOMEM; + } + + return 0; +} + +#ifdef CONFIG_OFTREE +static int bootm_open_oftree(struct image_data *data, char *oftree, int num) +{ + enum filetype ft; + struct fdt_header *fdt; + int ret; + size_t size; + + ft = file_name_detect_type(oftree); + if ((int)ft < 0) + return ft; + + if (ft == filetype_uimage) { +#ifdef CONFIG_CMD_BOOTM_OFTREE_UIMAGE + struct uimage_handle *of_handle; + int release = 0; + + if (!strcmp(data->os_file, oftree)) { + of_handle = data->os; + } else if (!strcmp(data->initrd_file, oftree)) { + of_handle = data->initrd; + } else { + of_handle = uimage_open(oftree); + if (!of_handle) + return -ENODEV; + uimage_print_contents(of_handle); + release = 1; + } + + fdt = uimage_load_to_buf(of_handle, num, &size); + + if (release) + uimage_close(of_handle); +#else + return -EINVAL; +#endif + } else { + fdt = read_file(oftree, &size); + if (!fdt) { + perror("open"); + return -ENODEV; + } + } + + ft = file_detect_type(fdt); + if (ft != filetype_oftree) { + printf("%s is not a oftree but %s\n", oftree, + file_type_to_string(ft)); + } + + if (bootm_verbose(data)) + printf("Loading oftree from '%s'\n", oftree); + + fdt = xrealloc(fdt, size + 0x8000); + fdt_open_into(fdt, fdt, size + 0x8000); + + if (!fdt) { + printf("unable to read %s\n", oftree); + return -ENODEV; + } + + ret = of_fix_tree(fdt); + if (ret) + return ret; + + if (bootm_verbose(data) > 1) + fdt_print(fdt, "/"); + + data->oftree = fdt; + + return ret; +} +#endif + +static struct image_handler *bootm_find_handler(enum filetype filetype, + struct image_data *data) +{ + struct image_handler *handler; + + list_for_each_entry(handler, &handler_list, list) { + if (filetype != filetype_uimage && + handler->filetype == filetype) + return handler; + if (filetype == filetype_uimage && + handler->ih_os == data->os->header.ih_os) + return handler; + } + + return NULL; +} + +static void bootm_image_name_and_no(char *name, int *no) +{ + char *at; + + *no = 0; + + at = strchr(name, '@'); + if (!at) + return; + + *at++ = 0; + + *no = simple_strtoul(at, NULL, 10); } static int do_bootm(struct command *cmdtp, int argc, char *argv[]) { - int opt; - image_header_t *os_header; - struct image_handle *os_handle = NULL; + int opt; struct image_handler *handler; struct image_data data; - const char *initrdname = NULL; int ret = 1; + enum filetype os_type, initrd_type = filetype_unknown; + char *oftree = NULL; + int fallback = 0; memset(&data, 0, sizeof(struct image_data)); - data.verify = 1; - data.initrd_address = ~0; - while ((opt = getopt(argc, argv, "nr:L:")) > 0) { + data.initrd_address = UIMAGE_SOME_ADDRESS; + data.os_address = UIMAGE_SOME_ADDRESS; + data.verify = 0; + data.verbose = 0; + + while ((opt = getopt(argc, argv, "cL:r:a:e:vo:f")) > 0) { switch(opt) { - case 'n': - data.verify = 0; + case 'c': + data.verify = 1; break; +#ifdef CONFIG_CMD_BOOTM_INITRD case 'L': data.initrd_address = simple_strtoul(optarg, NULL, 0); break; case 'r': - initrdname = optarg; + data.initrd_file = optarg; + break; +#endif + case 'a': + data.os_address = simple_strtoul(optarg, NULL, 0); + break; + case 'e': + data.os_entry = simple_strtoul(optarg, NULL, 0); + break; + case 'v': + data.verbose++; + break; + case 'o': + oftree = optarg; + break; + case 'f': + fallback = 1; break; default: break; } } -#ifdef CONFIG_OFTREE - data.oftree = of_get_fixed_tree(); -#endif + if (optind == argc) + return COMMAND_ERROR_USAGE; - if (optind == argc) { - ret = COMMAND_ERROR_USAGE; + data.os_file = argv[optind]; + + bootm_image_name_and_no(data.os_file, &data.os_num); + + os_type = file_name_detect_type(data.os_file); + if ((int)os_type < 0) { + printf("could not open %s: %s\n", data.os_file, + strerror(-os_type)); goto err_out; } - os_handle = map_image(argv[optind], data.verify); - if (!os_handle) - goto err_out; - data.os = os_handle; - - os_header = &os_handle->header; - - if (image_get_arch(os_header) != IH_ARCH) { - printf("Unsupported Architecture 0x%x\n", - image_get_arch(os_header)); + if (!fallback && os_type == filetype_unknown) { + printf("Unknown OS filetype (try -f)\n"); goto err_out; } - if (initrdname) { - /* check for multi image @ */ - if (initrdname[0] == '@') { - int num = simple_strtol(optarg + 1, NULL, 0); - - data.initrd = get_fake_image_handle(&data, num); - } else { - data.initrd = map_image(optarg, data.verify); - } - if (!data.initrd) + if (os_type == filetype_uimage) { + ret = bootm_open_os_uimage(&data); + if (ret) { + printf("loading initrd failed with %s\n", + strerror(-ret)); goto err_out; + } } - /* - * We have reached the point of no return: we are going to - * overwrite all exception vector code, so we cannot easily - * recover from any failures any more... - */ + if (bootm_initrd(&data)) { + bootm_image_name_and_no(data.initrd_file, &data.initrd_num); - puts ("OK\n"); + initrd_type = file_name_detect_type(data.initrd_file); + if ((int)initrd_type < 0) { + printf("could not open %s: %s\n", data.initrd_file, + strerror(-initrd_type)); + goto err_out; + } + if (initrd_type == filetype_uimage) { + ret = bootm_open_initrd_uimage(&data); + if (ret) { + printf("loading initrd failed with %s\n", + strerror(-ret)); + goto err_out; + } + } + } - /* - * FIXME: we do not check at all whether - * - we will write the image to sdram - * - we overwrite ourselves - * - kernel and initrd overlap - */ - ret = relocate_image(data.os, (void *)image_get_load(os_header)); - if (ret) - goto err_out; + if (bootm_verbose(&data)) { + printf("\nLoading OS %s '%s'", file_type_to_string(os_type), + data.os_file); + if (os_type == filetype_uimage && + data.os->header.ih_type == IH_TYPE_MULTI) + printf(", multifile image %d", data.os_num); + printf("\n"); + if (data.os_res) + printf("OS image is at 0x%08x-0x%08x\n", + data.os_res->start, + data.os_res->start + + data.os_res->size - 1); + else + printf("OS image not yet relocated\n"); - if (data.initrd) { - if (data.initrd && data.initrd_address == ~0) - data.initrd_address = uimage_to_cpu(data.initrd->header.ih_load); + if (data.initrd_file) { + printf("Loading initrd %s '%s'", + file_type_to_string(initrd_type), + data.initrd_file); + if (initrd_type == filetype_uimage && + data.initrd->header.ih_type == IH_TYPE_MULTI) + printf(", multifile image %d", data.initrd_num); + printf("\n"); + if (data.initrd_res) + printf("initrd is at 0x%08x-0x%08x\n", + data.initrd_res->start, + data.initrd_res->start + + data.initrd_res->size - 1); + else + printf("initrd image not yet relocated\n"); + } + } - data.initrd_size = image_get_data_size(&data.initrd->header); +#ifdef CONFIG_OFTREE + if (oftree) { + int oftree_num; - ret = relocate_image(data.initrd, (void *)data.initrd_address); + bootm_image_name_and_no(oftree, &oftree_num); + + ret = bootm_open_oftree(&data, oftree, oftree_num); if (ret) goto err_out; } +#endif + if (data.os_address == UIMAGE_SOME_ADDRESS) + data.os_address = UIMAGE_INVALID_ADDRESS; + if (data.initrd_address == UIMAGE_SOME_ADDRESS) + data.initrd_address = UIMAGE_INVALID_ADDRESS; - /* loop through the registered handlers */ - list_for_each_entry(handler, &handler_list, list) { - if (image_get_os(os_header) == handler->image_type) { - handler->bootm(&data); - printf("handler returned!\n"); - goto err_out; - } + handler = bootm_find_handler(os_type, &data); + if (!handler) { + printf("no image handler found for image type %s\n", + file_type_to_string(os_type)); + if (os_type == filetype_uimage) + printf("and os type: %d\n", data.os->header.ih_os); + goto err_out; } - printf("no image handler found for image type %d\n", - image_get_os(os_header)); + if (bootm_verbose(&data)) + printf("Passing control to %s handler\n", handler->name); + + ret = handler->bootm(&data); + + printf("handler failed with %s\n", strerror(-ret)); err_out: - if (os_handle) - unmap_image(os_handle); - if (data.initrd) - unmap_image(data.initrd); - return ret; + if (data.os_res) + release_sdram_region(data.os_res); + if (data.initrd_res) + release_sdram_region(data.initrd_res); + if (data.initrd && data.initrd != data.os) + uimage_close(data.initrd); + if (data.os) + uimage_close(data.os); + return 1; } BAREBOX_CMD_HELP_START(bootm) BAREBOX_CMD_HELP_USAGE("bootm [OPTIONS] image\n") BAREBOX_CMD_HELP_SHORT("Boot an application image.\n") -BAREBOX_CMD_HELP_OPT ("-n", "Do not verify the image (speeds up boot process)\n") +BAREBOX_CMD_HELP_OPT ("-c", "crc check uImage data\n") +#ifdef CONFIG_CMD_BOOTM_INITRD BAREBOX_CMD_HELP_OPT ("-r ","specify an initrd image\n") -BAREBOX_CMD_HELP_OPT ("-L ","specify initrd load address") +BAREBOX_CMD_HELP_OPT ("-L ","specify initrd load address\n") +#endif +BAREBOX_CMD_HELP_OPT ("-a ","specify os load address\n") +BAREBOX_CMD_HELP_OPT ("-e ","entry point to the image relative to start (0)\n") +#ifdef CONFIG_OFTREE +BAREBOX_CMD_HELP_OPT ("-o ","specify oftree\n") +#endif +#ifdef CONFIG_CMD_BOOTM_VERBOSE +BAREBOX_CMD_HELP_OPT ("-v","verbose\n") +#endif BAREBOX_CMD_HELP_END BAREBOX_CMD_START(bootm) @@ -245,13 +453,6 @@ BAREBOX_CMD_END BAREBOX_MAGICVAR(bootargs, "Linux Kernel parameters"); -#ifdef CONFIG_BZLIB -void bz_internal_error(int errcode) -{ - printf ("BZIP2 internal error %d\n", errcode); -} -#endif /* CONFIG_BZLIB */ - /** * @file * @brief Boot support for Linux diff --git a/include/boot.h b/include/boot.h index 297b944c7..a17bf25a4 100644 --- a/include/boot.h +++ b/include/boot.h @@ -2,25 +2,73 @@ #define __BOOT_H #include +#include +#include #include struct image_data { - struct image_handle *os; - struct image_handle *initrd; - void *oftree; - int verify; + /* simplest case. barebox has already loaded the os here */ + struct resource *os_res; + + /* if os is an uImage this will be provided */ + struct uimage_handle *os; + int os_num; + + /* otherwise only the filename will be provided */ + char *os_file; + + /* + * The address the user wants to load the os image to. + * May be UIMAGE_INVALID_ADDRESS to indicate that the + * user has not specified any address. In this case the + * handler may choose a suitable address + */ + unsigned long os_address; + + /* entry point to the os. relative to the start of the image */ + unsigned long os_entry; + + /* if initrd is already loaded this resource will be !NULL */ + struct resource *initrd_res; + + /* if initrd is an uImage this will be provided */ + struct uimage_handle *initrd; + int initrd_num; + + /* otherwise only the filename will be provided */ + char *initrd_file; + unsigned long initrd_address; - unsigned long initrd_size; + + struct fdt_header *oftree; + + int verify; + int verbose; }; struct image_handler { + const char *name; + struct list_head list; - int image_type; + int ih_os; + + enum filetype filetype; int (*bootm)(struct image_data *data); }; int register_image_handler(struct image_handler *handle); -#endif /* __BOOT_H */ +#ifdef CONFIG_CMD_BOOTM_VERBOSE +static inline int bootm_verbose(struct image_data *data) +{ + return data->verbose; +} +#else +static inline int bootm_verbose(struct image_data *data) +{ + return 0; +} +#endif +#endif /* __BOOT_H */ From 1d1618a11b33f3c88b5e9f52b3b4c38199eedec0 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sun, 11 Dec 2011 13:48:52 +0100 Subject: [PATCH 13/17] add uimage command The uimage command superseeds the iminfo command. Unlike the iminfo command the uimage command can also be used to verify the data crc on demand and to extract uImages to files. Signed-off-by: Sascha Hauer --- commands/Kconfig | 6 +++ commands/Makefile | 1 + commands/uimage.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 commands/uimage.c diff --git a/commands/Kconfig b/commands/Kconfig index 3cf2d085f..fc3797128 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -338,6 +338,12 @@ config CMD_IMINFO help Show information about uImages +config CMD_UIMAGE + tristate + prompt "uimage" + help + Show information about uImage and also extract and verify uImages. + config CMD_BOOTZ tristate default y diff --git a/commands/Makefile b/commands/Makefile index aa013de10..01cd1a2e7 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-$(CONFIG_CMD_IMINFO) += iminfo.o +obj-$(CONFIG_CMD_UIMAGE) += uimage.o obj-$(CONFIG_CMD_LINUX16) += linux16.o obj-$(CONFIG_CMD_LOADB) += loadb.o xyzModem.o obj-$(CONFIG_CMD_LOADY) += loadb.o xyzModem.o diff --git a/commands/uimage.c b/commands/uimage.c new file mode 100644 index 000000000..82efd7834 --- /dev/null +++ b/commands/uimage.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int uimage_fd; + +static int uimage_flush(void *buf, unsigned int len) +{ + int ret; + + ret = write_full(uimage_fd, buf, len); + + return ret; +} + +static int do_uimage(struct command *cmdtp, int argc, char *argv[]) +{ + struct uimage_handle *handle; + int ret; + int verify = 0; + int fd; + int opt; + char *extract = NULL; + int info = 0; + int image_no = 0; + + while ((opt = getopt(argc, argv, "ve:in:")) > 0) { + switch (opt) { + case 'v': + verify = 1; + break; + case 'i': + info = 1; + break; + case 'e': + extract = optarg; + break; + case 'n': + image_no = simple_strtoul(optarg, NULL, 0); + break; + } + } + + if (optind == argc) + return COMMAND_ERROR_USAGE; + + handle = uimage_open(argv[optind]); + if (!handle) + return 1; + + if (info) { + printf("Image at %s:\n", argv[optind]); + uimage_print_contents(handle); + } + + if (verify) { + printf("verifying data crc... "); + ret = uimage_verify(handle); + if (ret) { + goto err; + printf("Bad Data CRC\n"); + } else { + printf("ok\n"); + } + } + + if (extract) { + fd = open(extract, O_WRONLY | O_CREAT | O_TRUNC); + if (fd < 0) { + perror("open"); + ret = fd; + goto err; + } + uimage_fd = fd; + ret = uimage_load(handle, image_no, uimage_flush); + if (ret) { + printf("loading uImage failed with %d\n", ret); + close(fd); + goto err; + } + + close(fd); + } +err: + uimage_close(handle); + + return ret ? 1 : 0; +} + +BAREBOX_CMD_HELP_START(uimage) +BAREBOX_CMD_HELP_USAGE("uimage [OPTIONS] \n") +BAREBOX_CMD_HELP_OPT ("-i", "show information about image\n") +BAREBOX_CMD_HELP_OPT ("-v", "verify image\n") +BAREBOX_CMD_HELP_OPT ("-e ", "extract image to \n") +BAREBOX_CMD_HELP_OPT ("-n ", "use image number in multifile images\n") +BAREBOX_CMD_HELP_END + +BAREBOX_CMD_START(uimage) + .cmd = do_uimage, + .usage = "extract/verify uImage", + BAREBOX_CMD_HELP(cmd_uimage_help) +BAREBOX_CMD_END From e90f67881e2fcebf4b030b5a96f92d1e5efe5559 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 6 Dec 2011 09:00:45 +0100 Subject: [PATCH 14/17] remove now obsolete iminfo command Signed-off-by: Sascha Hauer --- commands/Kconfig | 6 ---- commands/Makefile | 1 - commands/iminfo.c | 71 ----------------------------------------------- 3 files changed, 78 deletions(-) delete mode 100644 commands/iminfo.c diff --git a/commands/Kconfig b/commands/Kconfig index fc3797128..6d5959106 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -332,12 +332,6 @@ config CMD_BOOTM_OFTREE_UIMAGE Support using oftree uImages. Without this only raw oftree blobs can be used. -config CMD_IMINFO - bool - prompt "iminfo" - help - Show information about uImages - config CMD_UIMAGE tristate prompt "uimage" diff --git a/commands/Makefile b/commands/Makefile index 01cd1a2e7..24753be80 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -1,5 +1,4 @@ obj-$(CONFIG_CMD_BOOTM) += bootm.o -obj-$(CONFIG_CMD_IMINFO) += iminfo.o obj-$(CONFIG_CMD_UIMAGE) += uimage.o obj-$(CONFIG_CMD_LINUX16) += linux16.o obj-$(CONFIG_CMD_LOADB) += loadb.o xyzModem.o diff --git a/commands/iminfo.c b/commands/iminfo.c deleted file mode 100644 index 2fde9bc09..000000000 --- a/commands/iminfo.c +++ /dev/null @@ -1,71 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -static int image_info(image_header_t *hdr) -{ - u32 len, checksum; - - if (image_get_magic(hdr) != IH_MAGIC) { - puts (" Bad Magic Number\n"); - return 1; - } - - len = image_get_header_size(); - - checksum = image_get_hcrc(hdr); - hdr->ih_hcrc = 0; - - if (crc32 (0, hdr, len) != checksum) { - puts (" Bad Header Checksum\n"); - return 1; - } - - image_print_contents(hdr, NULL); - - return 0; -} - -static int do_iminfo(struct command *cmdtp, int argc, char *argv[]) -{ - int rcode = 1; - int fd; - int ret; - image_header_t hdr; - - if (argc != 2) - return COMMAND_ERROR_USAGE; - - fd = open(argv[1], O_RDONLY); - if (fd < 0) { - perror("open"); - return 1; - } - - ret = read(fd, &hdr, sizeof(image_header_t)); - if (ret != sizeof(image_header_t)) - goto err_out; - - printf("Image at %s:\n", argv[1]); - image_info(&hdr); - -err_out: - close(fd); - - return rcode; -} - -BAREBOX_CMD_HELP_START(iminfo) -BAREBOX_CMD_HELP_USAGE("iminfo\n") -BAREBOX_CMD_HELP_SHORT("Print header information for an application image.\n") -BAREBOX_CMD_HELP_END - -BAREBOX_CMD_START(iminfo) - .cmd = do_iminfo, - .usage = "print header information for an application image", - BAREBOX_CMD_HELP(cmd_iminfo_help) -BAREBOX_CMD_END From cbf041c6301b2d7cca9089cbd88476bf97f0116a Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 6 Dec 2011 09:13:07 +0100 Subject: [PATCH 15/17] remove now unused uImage code Signed-off-by: Sascha Hauer --- common/image.c | 118 ------------------------------------------------ include/image.h | 28 ------------ 2 files changed, 146 deletions(-) diff --git a/common/image.c b/common/image.c index d68889bc0..7a7c0dfeb 100644 --- a/common/image.c +++ b/common/image.c @@ -313,121 +313,3 @@ void image_print_contents(const image_header_t *hdr, void *data) } } } - -#ifdef __BAREBOX__ -struct image_handle *map_image(const char *filename, int verify) -{ - int fd; - uint32_t checksum, len; - struct image_handle *handle; - image_header_t *header; - int type; - - fd = open(filename, O_RDONLY); - if (fd < 0) { - printf("could not open: %s\n", errno_str()); - return NULL; - } - - handle = xzalloc(sizeof(struct image_handle)); - header = &handle->header; - - if (read(fd, header, image_get_header_size()) < 0) { - printf("could not read: %s\n", errno_str()); - goto err_out; - } - - if (image_get_magic(header) != IH_MAGIC) { - puts ("Bad Magic Number\n"); - goto err_out; - } - - checksum = image_get_hcrc(header); - header->ih_hcrc = 0; - - if (crc32 (0, (uchar *)header, image_get_header_size()) != checksum) { - puts ("Bad Header Checksum\n"); - goto err_out; - } - len = image_get_size(header); - - handle->data = memmap(fd, PROT_READ); - if (handle->data == (void *)-1) { - handle->data = xmalloc(len); - handle->flags = IH_MALLOC; - if (read(fd, handle->data, len) < 0) { - printf("could not read: %s\n", errno_str()); - goto err_out; - } - } else { - handle->data = (void *)((unsigned long)handle->data + - image_get_header_size()); - } - - type = image_get_type(header); - if (type == IH_TYPE_MULTI) { - struct image_handle_data *data_entries; - int i; - ulong img_data; - ulong count = image_multi_count(handle->data); - - data_entries = xzalloc(sizeof(struct image_handle_data) * count); - - for (i = 0; i < count; i++) { - image_multi_getimg(handle->data, i, &img_data, - &data_entries[i].len); - - data_entries[i].data = (void*)img_data; - } - handle->data_entries = data_entries; - handle->nb_data_entries = count; - } else { - handle->data_entries = gen_image_handle_data(handle->data, len); - handle->nb_data_entries = 1; - } - - if (verify) { - puts (" Verifying Checksum ... "); - if (crc32 (0, handle->data, len) != image_get_dcrc(header)) { - printf ("Bad Data CRC\n"); - goto err_out; - } - puts ("OK\n"); - } - - image_print_contents(header, handle->data); - - close(fd); - - return handle; -err_out: - close(fd); - if (handle->flags & IH_MALLOC) - free(handle->data); - free(handle->data_entries); - free(handle); - return NULL; -} -EXPORT_SYMBOL(map_image); - -void unmap_image(struct image_handle *handle) -{ - if (handle->flags & IH_MALLOC) - free(handle->data); - free(handle->data_entries); - free(handle); -} -EXPORT_SYMBOL(unmap_image); - -struct image_handle_data * gen_image_handle_data(void* data, ulong len) -{ - struct image_handle_data *iha; - - iha = xzalloc(sizeof(struct image_handle_data)); - iha->data = data; - iha->len = len; - - return iha; -} -EXPORT_SYMBOL(gen_image_handle_data); -#endif diff --git a/include/image.h b/include/image.h index 5e9b6e26e..97de88133 100644 --- a/include/image.h +++ b/include/image.h @@ -188,20 +188,6 @@ typedef struct image_header { uint8_t ih_name[IH_NMLEN]; /* Image Name */ } image_header_t; -struct image_handle_data { - void *data; - ulong len; -}; - -struct image_handle { - image_header_t header; - void *data; - struct image_handle_data *data_entries; - int nb_data_entries; -#define IH_MALLOC 1 - int flags; -}; - #if defined(CONFIG_CMD_BOOTM_SHOW_TYPE) || !defined(__BAREBOX__) const char *image_get_os_name(uint8_t os); const char *image_get_arch_name(uint8_t arch); @@ -335,20 +321,6 @@ void image_print_size(uint32_t size); void image_print_contents(const image_header_t *hdr, void *data); -/* - * Load an image into memory. Returns a pointer to the loaded - * image. - */ -struct image_handle *map_image(const char *filename, int verify); -void unmap_image(struct image_handle *handle); -struct image_handle_data* gen_image_handle_data(void* data, ulong len); - -/* - * Relocate an image to load_address by uncompressing - * or just copying. - */ -int relocate_image(struct image_handle *handle, void *load_address); - struct uimage_handle_data { size_t offset; /* offset in the image */ ulong len; From d9d9c41f776a4b4744592ab0fb64398bb8ff6636 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 6 Dec 2011 09:21:20 +0100 Subject: [PATCH 16/17] move code now only used in mkimage to mkimage Signed-off-by: Sascha Hauer --- common/image.c | 169 -------------------------------- include/image.h | 103 -------------------- scripts/mkimage.c | 240 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 240 insertions(+), 272 deletions(-) diff --git a/common/image.c b/common/image.c index 7a7c0dfeb..e7d2242e7 100644 --- a/common/image.c +++ b/common/image.c @@ -144,172 +144,3 @@ const char *image_get_comp_name(uint8_t comp) return get_table_entry_name(comp_name, "Unknown Compression", comp); } #endif - -/** - * image_multi_count - get component (sub-image) count - * @hdr: pointer to the header of the multi component image - * - * image_multi_count() returns number of components in a multi - * component image. - * - * Note: no checking of the image type is done, caller must pass - * a valid multi component image. - * - * returns: - * number of components - */ -ulong image_multi_count(void *data) -{ - ulong i, count = 0; - uint32_t *size; - - /* get start of the image payload, which in case of multi - * component images that points to a table of component sizes */ - size = (uint32_t *)data; - - /* count non empty slots */ - for (i = 0; size[i]; ++i) - count++; - - return count; -} - -/** - * image_multi_getimg - get component data address and size - * @hdr: pointer to the header of the multi component image - * @idx: index of the requested component - * @data: pointer to a ulong variable, will hold component data address - * @len: pointer to a ulong variable, will hold component size - * - * image_multi_getimg() returns size and data address for the requested - * component in a multi component image. - * - * Note: no checking of the image type is done, caller must pass - * a valid multi component image. - * - * returns: - * data address and size of the component, if idx is valid - * 0 in data and len, if idx is out of range - */ -void image_multi_getimg(void *data, ulong idx, - ulong *img_data, ulong *len) -{ - int i; - uint32_t *size; - ulong offset, count, tmp_img_data; - - /* get number of component */ - count = image_multi_count(data); - - /* get start of the image payload, which in case of multi - * component images that points to a table of component sizes */ - size = (uint32_t *)data; - - /* get address of the proper component data start, which means - * skipping sizes table (add 1 for last, null entry) */ - tmp_img_data = (ulong)data + (count + 1) * sizeof (uint32_t); - - if (idx < count) { - *len = uimage_to_cpu(size[idx]); - offset = 0; - - /* go over all indices preceding requested component idx */ - for (i = 0; i < idx; i++) { - /* add up i-th component size, rounding up to 4 bytes */ - offset += (uimage_to_cpu(size[i]) + 3) & ~3 ; - } - - /* calculate idx-th component data address */ - *img_data = tmp_img_data + offset; - } else { - *len = 0; - *img_data = 0; - } -} - -static void image_print_type(const image_header_t *hdr) -{ - const char *os, *arch, *type, *comp; - - os = image_get_os_name(image_get_os(hdr)); - arch = image_get_arch_name(image_get_arch(hdr)); - type = image_get_type_name(image_get_type(hdr)); - comp = image_get_comp_name(image_get_comp(hdr)); - - printf ("%s %s %s (%s)\n", arch, os, type, comp); -} - -#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || !defined(__BAREBOX__) -static void image_print_time(time_t timestamp) -{ -#if defined(__BAREBOX__) - struct rtc_time tm; - - to_tm(timestamp, &tm); - printf("%4d-%02d-%02d %2d:%02d:%02d UTC\n", - tm.tm_year, tm.tm_mon, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec); -#else - printf("%s", ctime(×tamp)); -#endif -} -#endif /* CONFIG_TIMESTAMP || CONFIG_CMD_DATE || !__BAREBOX__ */ - -void image_print_size(uint32_t size) -{ -#ifdef __BAREBOX__ - printf("%d Bytes = %s\n", size, size_human_readable(size)); -#else - printf("%d Bytes = %.2f kB = %.2f MB\n", - size, (double)size / 1.024e3, - (double)size / 1.048576e6); -#endif -} - -void image_print_contents(const image_header_t *hdr, void *data) -{ - const char *p; - int type; - -#ifdef __BAREBOX__ - p = " "; -#else - p = ""; -#endif - - printf("%sImage Name: %.*s\n", p, IH_NMLEN, image_get_name(hdr)); -#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || !defined(__BAREBOX__) - printf("%sCreated: ", p); - image_print_time((time_t)image_get_time(hdr)); -#endif - printf ("%sImage Type: ", p); - image_print_type(hdr); - printf ("%sData Size: ", p); - image_print_size(image_get_data_size(hdr)); - printf ("%sLoad Address: %08x\n", p, image_get_load(hdr)); - printf ("%sEntry Point: %08x\n", p, image_get_ep(hdr)); - - type = image_get_type(hdr); - if (data && (type == IH_TYPE_MULTI || type == IH_TYPE_SCRIPT)) { - int i; - ulong img_data, len; - ulong count = image_multi_count(data); - - printf ("%sContents:\n", p); - for (i = 0; i < count; i++) { - image_multi_getimg(data, i, &img_data, &len); - - printf("%s Image %d: ", p, i); - image_print_size(len); - - if (image_get_type(hdr) != IH_TYPE_SCRIPT && i > 0) { - /* - * the user may need to know offsets - * if planning to do something with - * multiple files - */ - printf("%s Offset = 0x%08lx\n", p, img_data); - } - } - } -} diff --git a/include/image.h b/include/image.h index 97de88133..35ff01b1c 100644 --- a/include/image.h +++ b/include/image.h @@ -218,109 +218,6 @@ static inline const char *image_get_comp_name(uint8_t comp) #define uimage_to_cpu(x) be32_to_cpu(x) #define cpu_to_uimage(x) cpu_to_be32(x) -static inline uint32_t image_get_header_size(void) -{ - return sizeof(image_header_t); -} - -#define image_get_hdr_u32(x) \ -static inline uint32_t image_get_##x(const image_header_t *hdr) \ -{ \ - return uimage_to_cpu(hdr->ih_##x); \ -} - -image_get_hdr_u32(magic); /* image_get_magic */ -image_get_hdr_u32(hcrc); /* image_get_hcrc */ -image_get_hdr_u32(time); /* image_get_time */ -image_get_hdr_u32(size); /* image_get_size */ -image_get_hdr_u32(load); /* image_get_load */ -image_get_hdr_u32(ep); /* image_get_ep */ -image_get_hdr_u32(dcrc); /* image_get_dcrc */ - -#define image_get_hdr_u8(x) \ -static inline uint8_t image_get_##x(const image_header_t *hdr) \ -{ \ - return hdr->ih_##x; \ -} -image_get_hdr_u8(os); /* image_get_os */ -image_get_hdr_u8(arch); /* image_get_arch */ -image_get_hdr_u8(type); /* image_get_type */ -image_get_hdr_u8(comp); /* image_get_comp */ - -static inline char *image_get_name(const image_header_t *hdr) -{ - return (char*)hdr->ih_name; -} - -static inline uint32_t image_get_data_size(const image_header_t *hdr) -{ - return image_get_size(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_image_end(const image_header_t *hdr) -{ - return ((ulong)hdr + image_get_image_size(hdr)); -} - -#define image_set_hdr_u32(x) \ -static inline void image_set_##x(image_header_t *hdr, uint32_t val) \ -{ \ - hdr->ih_##x = cpu_to_uimage(val); \ -} - -image_set_hdr_u32(magic); /* image_set_magic */ -image_set_hdr_u32(hcrc); /* image_set_hcrc */ -image_set_hdr_u32(time); /* image_set_time */ -image_set_hdr_u32(size); /* image_set_size */ -image_set_hdr_u32(load); /* image_set_load */ -image_set_hdr_u32(ep); /* image_set_ep */ -image_set_hdr_u32(dcrc); /* image_set_dcrc */ - -#define image_set_hdr_u8(x) \ -static inline void image_set_##x(image_header_t *hdr, uint8_t val) \ -{ \ - hdr->ih_##x = val; \ -} - -image_set_hdr_u8(os); /* image_set_os */ -image_set_hdr_u8(arch); /* image_set_arch */ -image_set_hdr_u8(type); /* image_set_type */ -image_set_hdr_u8(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); -} - -ulong image_multi_count(void *data); -void image_multi_getimg(void *data, ulong idx, - ulong *img_data, ulong *len); - -void image_print_size(uint32_t size); - -void image_print_contents(const image_header_t *hdr, void *data); - struct uimage_handle_data { size_t offset; /* offset in the image */ ulong len; diff --git a/scripts/mkimage.c b/scripts/mkimage.c index b219cb8f2..64290cfe8 100644 --- a/scripts/mkimage.c +++ b/scripts/mkimage.c @@ -62,6 +62,246 @@ int opt_comp = IH_COMP_GZIP; image_header_t header; image_header_t *hdr = &header; +static inline uint32_t image_get_header_size(void) +{ + return sizeof(image_header_t); +} + +#define image_get_hdr_u32(x) \ +static inline uint32_t image_get_##x(const image_header_t *hdr) \ +{ \ + return uimage_to_cpu(hdr->ih_##x); \ +} + +image_get_hdr_u32(magic); /* image_get_magic */ +image_get_hdr_u32(hcrc); /* image_get_hcrc */ +image_get_hdr_u32(time); /* image_get_time */ +image_get_hdr_u32(size); /* image_get_size */ +image_get_hdr_u32(load); /* image_get_load */ +image_get_hdr_u32(ep); /* image_get_ep */ +image_get_hdr_u32(dcrc); /* image_get_dcrc */ + +#define image_get_hdr_u8(x) \ +static inline uint8_t image_get_##x(const image_header_t *hdr) \ +{ \ + return hdr->ih_##x; \ +} +image_get_hdr_u8(os); /* image_get_os */ +image_get_hdr_u8(arch); /* image_get_arch */ +image_get_hdr_u8(type); /* image_get_type */ +image_get_hdr_u8(comp); /* image_get_comp */ + +static inline char *image_get_name(const image_header_t *hdr) +{ + return (char*)hdr->ih_name; +} + +static inline uint32_t image_get_data_size(const image_header_t *hdr) +{ + return image_get_size(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_image_end(const image_header_t *hdr) +{ + return ((ulong)hdr + image_get_image_size(hdr)); +} + +#define image_set_hdr_u32(x) \ +static inline void image_set_##x(image_header_t *hdr, uint32_t val) \ +{ \ + hdr->ih_##x = cpu_to_uimage(val); \ +} + +image_set_hdr_u32(magic); /* image_set_magic */ +image_set_hdr_u32(hcrc); /* image_set_hcrc */ +image_set_hdr_u32(time); /* image_set_time */ +image_set_hdr_u32(size); /* image_set_size */ +image_set_hdr_u32(load); /* image_set_load */ +image_set_hdr_u32(ep); /* image_set_ep */ +image_set_hdr_u32(dcrc); /* image_set_dcrc */ + +#define image_set_hdr_u8(x) \ +static inline void image_set_##x(image_header_t *hdr, uint8_t val) \ +{ \ + hdr->ih_##x = val; \ +} + +image_set_hdr_u8(os); /* image_set_os */ +image_set_hdr_u8(arch); /* image_set_arch */ +image_set_hdr_u8(type); /* image_set_type */ +image_set_hdr_u8(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); +} + +/** + * image_multi_count - get component (sub-image) count + * @hdr: pointer to the header of the multi component image + * + * image_multi_count() returns number of components in a multi + * component image. + * + * Note: no checking of the image type is done, caller must pass + * a valid multi component image. + * + * returns: + * number of components + */ +static ulong image_multi_count(void *data) +{ + ulong i, count = 0; + uint32_t *size; + + /* get start of the image payload, which in case of multi + * component images that points to a table of component sizes */ + size = (uint32_t *)data; + + /* count non empty slots */ + for (i = 0; size[i]; ++i) + count++; + + return count; +} + +/** + * image_multi_getimg - get component data address and size + * @hdr: pointer to the header of the multi component image + * @idx: index of the requested component + * @data: pointer to a ulong variable, will hold component data address + * @len: pointer to a ulong variable, will hold component size + * + * image_multi_getimg() returns size and data address for the requested + * component in a multi component image. + * + * Note: no checking of the image type is done, caller must pass + * a valid multi component image. + * + * returns: + * data address and size of the component, if idx is valid + * 0 in data and len, if idx is out of range + */ +static void image_multi_getimg(void *data, ulong idx, + ulong *img_data, ulong *len) +{ + int i; + uint32_t *size; + ulong offset, count, tmp_img_data; + + /* get number of component */ + count = image_multi_count(data); + + /* get start of the image payload, which in case of multi + * component images that points to a table of component sizes */ + size = (uint32_t *)data; + + /* get address of the proper component data start, which means + * skipping sizes table (add 1 for last, null entry) */ + tmp_img_data = (ulong)data + (count + 1) * sizeof (uint32_t); + + if (idx < count) { + *len = uimage_to_cpu(size[idx]); + offset = 0; + + /* go over all indices preceding requested component idx */ + for (i = 0; i < idx; i++) { + /* add up i-th component size, rounding up to 4 bytes */ + offset += (uimage_to_cpu(size[i]) + 3) & ~3 ; + } + + /* calculate idx-th component data address */ + *img_data = tmp_img_data + offset; + } else { + *len = 0; + *img_data = 0; + } +} + +static void image_print_type(const image_header_t *hdr) +{ + const char *os, *arch, *type, *comp; + + os = image_get_os_name(image_get_os(hdr)); + arch = image_get_arch_name(image_get_arch(hdr)); + type = image_get_type_name(image_get_type(hdr)); + comp = image_get_comp_name(image_get_comp(hdr)); + + printf ("%s %s %s (%s)\n", arch, os, type, comp); +} + +static void image_print_time(time_t timestamp) +{ + printf("%s", ctime(×tamp)); +} + +static void image_print_size(uint32_t size) +{ + printf("%d Bytes = %.2f kB = %.2f MB\n", + size, (double)size / 1.024e3, + (double)size / 1.048576e6); +} + +static void image_print_contents(const image_header_t *hdr, void *data) +{ + int type; + + printf("Image Name: %.*s\n", IH_NMLEN, image_get_name(hdr)); + printf("Created: "); + image_print_time((time_t)image_get_time(hdr)); + printf ("Image Type: "); + image_print_type(hdr); + printf ("Data Size: "); + image_print_size(image_get_data_size(hdr)); + printf ("Load Address: %08x\n", image_get_load(hdr)); + printf ("Entry Point: %08x\n", image_get_ep(hdr)); + + type = image_get_type(hdr); + if (data && (type == IH_TYPE_MULTI || type == IH_TYPE_SCRIPT)) { + int i; + ulong img_data, len; + ulong count = image_multi_count(data); + + printf ("Contents:\n"); + for (i = 0; i < count; i++) { + image_multi_getimg(data, i, &img_data, &len); + + printf(" Image %d: ", i); + image_print_size(len); + + if (image_get_type(hdr) != IH_TYPE_SCRIPT && i > 0) { + /* + * the user may need to know offsets + * if planning to do something with + * multiple files + */ + printf(" Offset = 0x%08lx\n", img_data); + } + } + } +} + int main (int argc, char **argv) { From 52fac4b1ff5da3deff3e9f0cae681ff23337c1f1 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 14 Dec 2011 21:30:58 +0100 Subject: [PATCH 17/17] defaultenv: simplify boot Now that we have a bootm command which boots everything we can simplify the defaultenvironment. We can call bootm on every image type and can remove the kernelimage_type variables. Signed-off-by: Sascha Hauer --- arch/arm/boards/at91rm9200ek/env/config | 5 --- arch/arm/boards/at91sam9261ek/env/config | 5 --- arch/arm/boards/at91sam9263ek/env/config | 5 --- arch/arm/boards/at91sam9m10g45ek/env/config | 5 --- .../arm/boards/chumby_falconwing/env/bin/boot | 9 +--- arch/arm/boards/chumby_falconwing/env/config | 2 - arch/arm/boards/dss11/env/config | 5 --- arch/arm/boards/eukrea_cpuimx25/env/config | 1 - arch/arm/boards/eukrea_cpuimx35/env/config | 1 - arch/arm/boards/eukrea_cpuimx51/env/config | 1 - .../boards/freescale-mx35-3-stack/env/config | 5 --- arch/arm/boards/freescale-mx51-pdk/env/config | 5 --- .../arm/boards/freescale-mx53-loco/env/config | 5 --- arch/arm/boards/freescale-mx53-smd/env/config | 5 --- arch/arm/boards/guf-cupid/env/config | 5 --- arch/arm/boards/guf-neso/env/config | 5 --- arch/arm/boards/karo-tx25/env/config | 5 --- arch/arm/boards/karo-tx28/env/config | 5 --- arch/arm/boards/mini2440/env/config | 5 --- arch/arm/boards/nhk8815/env/config | 5 --- arch/arm/boards/panda/env/config | 5 --- arch/arm/boards/pcm037/env/config | 5 --- arch/arm/boards/pcm038/env/config | 5 --- arch/arm/boards/pcm043/env/config | 5 --- arch/arm/boards/pcm049/env/config | 5 --- arch/arm/boards/phycard-i.MX27/env/config | 5 --- arch/arm/boards/pm9261/env/config | 5 --- arch/arm/boards/pm9g45/env/config | 5 --- arch/arm/boards/scb9328/env/config | 5 --- arch/arm/boards/usb-a926x/env/config | 5 --- arch/arm/boards/versatile/env/config | 5 --- arch/nios2/boards/generic/env/config | 1 - defaultenv/bin/boot | 43 ++----------------- defaultenv/config | 5 --- 34 files changed, 5 insertions(+), 188 deletions(-) diff --git a/arch/arm/boards/at91rm9200ek/env/config b/arch/arm/boards/at91rm9200ek/env/config index 1b56b25b5..12655c2b4 100644 --- a/arch/arm/boards/at91rm9200ek/env/config +++ b/arch/arm/boards/at91rm9200ek/env/config @@ -19,14 +19,9 @@ rootfs_loc=net rootfs_type=ubifs rootfsimage=root.$rootfs_type -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -#kernelimage_type=zimage #kernelimage=zImage -kernelimage_type=uimage kernelimage=uImage -#kernelimage_type=raw #kernelimage=Image -#kernelimage_type=raw_lzo #kernelimage=Image.lzo nor_parts="256k(barebox)ro,64k(bareboxenv),1536k(kernel),-(root)" diff --git a/arch/arm/boards/at91sam9261ek/env/config b/arch/arm/boards/at91sam9261ek/env/config index 733326d48..d6eeea42f 100644 --- a/arch/arm/boards/at91sam9261ek/env/config +++ b/arch/arm/boards/at91sam9261ek/env/config @@ -19,14 +19,9 @@ rootfs_loc=net rootfs_type=ubifs rootfsimage=root.$rootfs_type -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -#kernelimage_type=zimage #kernelimage=zImage -kernelimage_type=uimage kernelimage=uImage -#kernelimage_type=raw #kernelimage=Image -#kernelimage_type=raw_lzo #kernelimage=Image.lzo nand_device=atmel_nand diff --git a/arch/arm/boards/at91sam9263ek/env/config b/arch/arm/boards/at91sam9263ek/env/config index 4e2923227..bd771ac37 100644 --- a/arch/arm/boards/at91sam9263ek/env/config +++ b/arch/arm/boards/at91sam9263ek/env/config @@ -19,14 +19,9 @@ rootfs_loc=net rootfs_type=ubifs rootfsimage=root.$rootfs_type -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -#kernelimage_type=zimage #kernelimage=zImage -kernelimage_type=uimage kernelimage=uImage -#kernelimage_type=raw #kernelimage=Image -#kernelimage_type=raw_lzo #kernelimage=Image.lzo nand_device=atmel_nand diff --git a/arch/arm/boards/at91sam9m10g45ek/env/config b/arch/arm/boards/at91sam9m10g45ek/env/config index b8ca18dce..3dea7247f 100644 --- a/arch/arm/boards/at91sam9m10g45ek/env/config +++ b/arch/arm/boards/at91sam9m10g45ek/env/config @@ -19,14 +19,9 @@ rootfs_loc=net rootfs_type=ubifs rootfsimage=root.$rootfs_type -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -#kernelimage_type=zimage #kernelimage=zImage -kernelimage_type=uimage kernelimage=uImage -#kernelimage_type=raw #kernelimage=Image -#kernelimage_type=raw_lzo #kernelimage=Image.lzo nand_device=atmel_nand diff --git a/arch/arm/boards/chumby_falconwing/env/bin/boot b/arch/arm/boards/chumby_falconwing/env/bin/boot index 981a387a1..999170cb4 100644 --- a/arch/arm/boards/chumby_falconwing/env/bin/boot +++ b/arch/arm/boards/chumby_falconwing/env/bin/boot @@ -26,13 +26,6 @@ elif [ x$rootfs_loc = xinitrd ]; then bootargs="$bootargs root=/dev/ram0 rdinit=/sbin/init" fi -if [ x$kernelimage_type = xuimage ]; then - bootm /dev/$kernel_part -elif [ x$kernelimage_type = xzimage ]; then - bootz /dev/$kernel_part -else - echo "Booting failed. Correct setup of 'kernelimage_type'?" - exit -fi +bootm /dev/$kernel_part echo "Booting failed. Correct setup of 'kernel_part'?" diff --git a/arch/arm/boards/chumby_falconwing/env/config b/arch/arm/boards/chumby_falconwing/env/config index 1e61dce97..141916125 100644 --- a/arch/arm/boards/chumby_falconwing/env/config +++ b/arch/arm/boards/chumby_falconwing/env/config @@ -25,8 +25,6 @@ rootfs_part=mmcblk0p4 # Where is the rootfs in case of 'rootfs_loc=net' nfsroot=FIXME -# The image type of the kernel. Can be uimage, zimage -kernelimage_type=uimage # Where to get the kernel image in case of 'kernel_loc=disk' kernel_part=disk0.2 diff --git a/arch/arm/boards/dss11/env/config b/arch/arm/boards/dss11/env/config index 5c9be7d6d..adf3af5d7 100644 --- a/arch/arm/boards/dss11/env/config +++ b/arch/arm/boards/dss11/env/config @@ -19,14 +19,9 @@ rootfs_loc=net rootfs_type=ubifs rootfsimage=root.$rootfs_type -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -#kernelimage_type=zimage #kernelimage=zImage -kernelimage_type=uimage kernelimage=uImage -#kernelimage_type=raw #kernelimage=Image -#kernelimage_type=raw_lzo #kernelimage=Image.lzo nand_device=atmel_nand diff --git a/arch/arm/boards/eukrea_cpuimx25/env/config b/arch/arm/boards/eukrea_cpuimx25/env/config index 5cedbf821..bc1cfd506 100644 --- a/arch/arm/boards/eukrea_cpuimx25/env/config +++ b/arch/arm/boards/eukrea_cpuimx25/env/config @@ -25,7 +25,6 @@ rootfs_type=ubifs rootfsimage=$machine/rootfs.$rootfs_type # kernel -kernelimage_type=uimage kernelimage=$machine/uImage-${machine}.bin # barebox and it's env diff --git a/arch/arm/boards/eukrea_cpuimx35/env/config b/arch/arm/boards/eukrea_cpuimx35/env/config index 776d19a24..8f64ba05c 100644 --- a/arch/arm/boards/eukrea_cpuimx35/env/config +++ b/arch/arm/boards/eukrea_cpuimx35/env/config @@ -25,7 +25,6 @@ rootfs_type=ubifs rootfsimage=$machine/rootfs.$rootfs_type # kernel -kernelimage_type=uimage kernelimage=$machine/uImage-${machine}.bin # barebox and it's env diff --git a/arch/arm/boards/eukrea_cpuimx51/env/config b/arch/arm/boards/eukrea_cpuimx51/env/config index 91a267163..1b57b2903 100644 --- a/arch/arm/boards/eukrea_cpuimx51/env/config +++ b/arch/arm/boards/eukrea_cpuimx51/env/config @@ -28,7 +28,6 @@ rootfs_type=ubifs rootfsimage=$machine/rootfs.$rootfs_type # kernel -kernelimage_type=uimage kernelimage=$machine/uImage-${machine}.bin # barebox and it's env diff --git a/arch/arm/boards/freescale-mx35-3-stack/env/config b/arch/arm/boards/freescale-mx35-3-stack/env/config index ee9bd07e2..17b1e31f0 100644 --- a/arch/arm/boards/freescale-mx35-3-stack/env/config +++ b/arch/arm/boards/freescale-mx35-3-stack/env/config @@ -23,14 +23,9 @@ rootfs_loc=net rootfs_type=ubifs rootfsimage=root-$machine.$rootfs_type -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -kernelimage_type=zimage kernelimage=zImage-$machine -#kernelimage_type=uimage #kernelimage=uImage-$machine -#kernelimage_type=raw #kernelimage=Image-$machine -#kernelimage_type=raw_lzo #kernelimage=Image-$machine.lzo if [ -n $user ]; then diff --git a/arch/arm/boards/freescale-mx51-pdk/env/config b/arch/arm/boards/freescale-mx51-pdk/env/config index 8e6b34eec..10690c9c5 100644 --- a/arch/arm/boards/freescale-mx51-pdk/env/config +++ b/arch/arm/boards/freescale-mx51-pdk/env/config @@ -23,14 +23,9 @@ rootfs_loc=net rootfs_type=ubifs rootfsimage=root-$machine.$rootfs_type -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -kernelimage_type=zimage kernelimage=zImage-$machine -#kernelimage_type=uimage #kernelimage=uImage-$machine -#kernelimage_type=raw #kernelimage=Image-$machine -#kernelimage_type=raw_lzo #kernelimage=Image-$machine.lzo if [ -n $user ]; then diff --git a/arch/arm/boards/freescale-mx53-loco/env/config b/arch/arm/boards/freescale-mx53-loco/env/config index 3659a629a..fd238a6ac 100644 --- a/arch/arm/boards/freescale-mx53-loco/env/config +++ b/arch/arm/boards/freescale-mx53-loco/env/config @@ -23,14 +23,9 @@ rootfs_loc=net rootfs_type=ubifs rootfsimage=root-$machine.$rootfs_type -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -kernelimage_type=zimage kernelimage=zImage-$machine -#kernelimage_type=uimage #kernelimage=uImage-$machine -#kernelimage_type=raw #kernelimage=Image-$machine -#kernelimage_type=raw_lzo #kernelimage=Image-$machine.lzo if [ -n $user ]; then diff --git a/arch/arm/boards/freescale-mx53-smd/env/config b/arch/arm/boards/freescale-mx53-smd/env/config index 3659a629a..fd238a6ac 100644 --- a/arch/arm/boards/freescale-mx53-smd/env/config +++ b/arch/arm/boards/freescale-mx53-smd/env/config @@ -23,14 +23,9 @@ rootfs_loc=net rootfs_type=ubifs rootfsimage=root-$machine.$rootfs_type -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -kernelimage_type=zimage kernelimage=zImage-$machine -#kernelimage_type=uimage #kernelimage=uImage-$machine -#kernelimage_type=raw #kernelimage=Image-$machine -#kernelimage_type=raw_lzo #kernelimage=Image-$machine.lzo if [ -n $user ]; then diff --git a/arch/arm/boards/guf-cupid/env/config b/arch/arm/boards/guf-cupid/env/config index cd11eb185..930a97d1e 100644 --- a/arch/arm/boards/guf-cupid/env/config +++ b/arch/arm/boards/guf-cupid/env/config @@ -23,14 +23,9 @@ rootfs_loc=net rootfs_type=ubifs rootfsimage=root-$machine.$rootfs_type -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -kernelimage_type=zimage kernelimage=zImage-$machine -#kernelimage_type=uimage #kernelimage=uImage-$machine -#kernelimage_type=raw #kernelimage=Image-$machine -#kernelimage_type=raw_lzo #kernelimage=Image-$machine.lzo if [ -n $user ]; then diff --git a/arch/arm/boards/guf-neso/env/config b/arch/arm/boards/guf-neso/env/config index 162488f8b..9b675b592 100644 --- a/arch/arm/boards/guf-neso/env/config +++ b/arch/arm/boards/guf-neso/env/config @@ -23,14 +23,9 @@ rootfs_loc=net rootfs_type=ubifs rootfsimage=root-$machine.$rootfs_type -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -kernelimage_type=zimage kernelimage=zImage-$machine -#kernelimage_type=uimage #kernelimage=uImage-$machine -#kernelimage_type=raw #kernelimage=Image-$machine -#kernelimage_type=raw_lzo #kernelimage=Image-$machine.lzo if [ -n $user ]; then diff --git a/arch/arm/boards/karo-tx25/env/config b/arch/arm/boards/karo-tx25/env/config index 9113a87bc..69f2c26c3 100644 --- a/arch/arm/boards/karo-tx25/env/config +++ b/arch/arm/boards/karo-tx25/env/config @@ -23,14 +23,9 @@ rootfs_loc=net rootfs_type=ubifs rootfsimage=root-$machine.$rootfs_type -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -kernelimage_type=zimage kernelimage=zImage-$machine -#kernelimage_type=uimage #kernelimage=uImage-$machine -#kernelimage_type=raw #kernelimage=Image-$machine -#kernelimage_type=raw_lzo #kernelimage=Image-$machine.lzo if [ -n $user ]; then diff --git a/arch/arm/boards/karo-tx28/env/config b/arch/arm/boards/karo-tx28/env/config index fdf57ea66..ed361ebd2 100644 --- a/arch/arm/boards/karo-tx28/env/config +++ b/arch/arm/boards/karo-tx28/env/config @@ -24,14 +24,9 @@ rootfs_loc=net rootfs_type=ubifs rootfsimage=root-$machine.$rootfs_type -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -kernelimage_type=zimage kernelimage=zImage-$machine -#kernelimage_type=uimage #kernelimage=uImage-$machine -#kernelimage_type=raw #kernelimage=Image-$machine -#kernelimage_type=raw_lzo #kernelimage=Image-$machine.lzo if [ -n $user ]; then diff --git a/arch/arm/boards/mini2440/env/config b/arch/arm/boards/mini2440/env/config index ff6f1ea5e..ac8c32a38 100644 --- a/arch/arm/boards/mini2440/env/config +++ b/arch/arm/boards/mini2440/env/config @@ -23,14 +23,9 @@ rootfs_loc=net rootfs_type=ubifs rootfsimage=root-${machine}.${rootfs_type} -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -kernelimage_type=zimage kernelimage=zImage-${machine} -#kernelimage_type=uimage #kernelimage=uImage-$machine -#kernelimage_type=raw #kernelimage=Image-$machine -#kernelimage_type=raw_lzo #kernelimage=Image-$machine.lzo if [ -n $user ]; then diff --git a/arch/arm/boards/nhk8815/env/config b/arch/arm/boards/nhk8815/env/config index 7428c4371..c05ed2704 100644 --- a/arch/arm/boards/nhk8815/env/config +++ b/arch/arm/boards/nhk8815/env/config @@ -19,14 +19,9 @@ rootfs_loc=net rootfs_type=ubifs rootfsimage=root.$rootfs_type -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -#kernelimage_type=zimage #kernelimage=zImage -kernelimage_type=uimage kernelimage=uImage -#kernelimage_type=raw #kernelimage=Image -#kernelimage_type=raw_lzo #kernelimage=Image.lzo # Partition Size Start diff --git a/arch/arm/boards/panda/env/config b/arch/arm/boards/panda/env/config index 363208e9b..29672be9e 100644 --- a/arch/arm/boards/panda/env/config +++ b/arch/arm/boards/panda/env/config @@ -18,14 +18,9 @@ kernel_loc=tftp # can be either 'net', 'nor', 'nand' or 'initrd' rootfs_loc=net -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -kernelimage_type=zimage kernelimage=zImage-$machine -#kernelimage_type=uimage #kernelimage=uImage-$machine -#kernelimage_type=raw #kernelimage=Image-$machine -#kernelimage_type=raw_lzo #kernelimage=Image-${machine}.lzo if [ -n $user ]; then diff --git a/arch/arm/boards/pcm037/env/config b/arch/arm/boards/pcm037/env/config index 3748cc4c3..d67d31945 100644 --- a/arch/arm/boards/pcm037/env/config +++ b/arch/arm/boards/pcm037/env/config @@ -23,14 +23,9 @@ rootfs_loc=net rootfs_type=ubifs rootfsimage=root-$machine.$rootfs_type -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -kernelimage_type=zimage kernelimage=zImage-$machine -#kernelimage_type=uimage #kernelimage=uImage-$machine -#kernelimage_type=raw #kernelimage=Image-$machine -#kernelimage_type=raw_lzo #kernelimage=Image-$machine.lzo if [ -n $user ]; then diff --git a/arch/arm/boards/pcm038/env/config b/arch/arm/boards/pcm038/env/config index 9e28f5d1f..eb0f9c1a7 100644 --- a/arch/arm/boards/pcm038/env/config +++ b/arch/arm/boards/pcm038/env/config @@ -23,14 +23,9 @@ rootfs_loc=net rootfs_type=ubifs rootfsimage=root-$machine.$rootfs_type -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -kernelimage_type=zimage kernelimage=zImage-$machine -#kernelimage_type=uimage #kernelimage=uImage-$machine -#kernelimage_type=raw #kernelimage=Image-$machine -#kernelimage_type=raw_lzo #kernelimage=Image-$machine.lzo if [ -n $user ]; then diff --git a/arch/arm/boards/pcm043/env/config b/arch/arm/boards/pcm043/env/config index e7f94f8de..2a355e670 100644 --- a/arch/arm/boards/pcm043/env/config +++ b/arch/arm/boards/pcm043/env/config @@ -23,14 +23,9 @@ rootfs_loc=net rootfs_type=ubifs rootfsimage=root-$machine.$rootfs_type -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -kernelimage_type=zimage kernelimage=zImage-$machine -#kernelimage_type=uimage #kernelimage=uImage-$machine -#kernelimage_type=raw #kernelimage=Image-$machine -#kernelimage_type=raw_lzo #kernelimage=Image-$machine.lzo if [ -n $user ]; then diff --git a/arch/arm/boards/pcm049/env/config b/arch/arm/boards/pcm049/env/config index 54b2e3dd7..f3487141e 100644 --- a/arch/arm/boards/pcm049/env/config +++ b/arch/arm/boards/pcm049/env/config @@ -23,14 +23,9 @@ rootfs_loc=net rootfs_type=ubifs rootfsimage=root-${machine}.$rootfs_type -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -kernelimage_type=zimage kernelimage=zImage-$machine -#kernelimage_type=uimage #kernelimage=uImage-$machine -#kernelimage_type=raw #kernelimage=Image-$machine -#kernelimage_type=raw_lzo #kernelimage=Image-${machine}.lzo if [ -n $user ]; then diff --git a/arch/arm/boards/phycard-i.MX27/env/config b/arch/arm/boards/phycard-i.MX27/env/config index 0e20b48ff..5db33d0c6 100644 --- a/arch/arm/boards/phycard-i.MX27/env/config +++ b/arch/arm/boards/phycard-i.MX27/env/config @@ -23,14 +23,9 @@ rootfs_loc=net rootfs_type=ubifs rootfsimage=root-$machine.$rootfs_type -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -kernelimage_type=zimage kernelimage=zImage-$machine -#kernelimage_type=uimage #kernelimage=uImage-$machine -#kernelimage_type=raw #kernelimage=Image-$machine -#kernelimage_type=raw_lzo #kernelimage=Image-$machine.lzo if [ -n $user ]; then diff --git a/arch/arm/boards/pm9261/env/config b/arch/arm/boards/pm9261/env/config index 7933379b6..bdc2d38d4 100644 --- a/arch/arm/boards/pm9261/env/config +++ b/arch/arm/boards/pm9261/env/config @@ -19,14 +19,9 @@ rootfs_loc=net rootfs_type=ubifs rootfsimage=root.$rootfs_type -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -#kernelimage_type=zimage #kernelimage=zImage -kernelimage_type=uimage kernelimage=uImage -#kernelimage_type=raw #kernelimage=Image -#kernelimage_type=raw_lzo #kernelimage=Image.lzo nor_parts="256k(barebox)ro,64k(bareboxenv),1536k(kernel),-(root)" diff --git a/arch/arm/boards/pm9g45/env/config b/arch/arm/boards/pm9g45/env/config index b8ca18dce..3dea7247f 100644 --- a/arch/arm/boards/pm9g45/env/config +++ b/arch/arm/boards/pm9g45/env/config @@ -19,14 +19,9 @@ rootfs_loc=net rootfs_type=ubifs rootfsimage=root.$rootfs_type -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -#kernelimage_type=zimage #kernelimage=zImage -kernelimage_type=uimage kernelimage=uImage -#kernelimage_type=raw #kernelimage=Image -#kernelimage_type=raw_lzo #kernelimage=Image.lzo nand_device=atmel_nand diff --git a/arch/arm/boards/scb9328/env/config b/arch/arm/boards/scb9328/env/config index d0f3f25ee..e1c5807ba 100644 --- a/arch/arm/boards/scb9328/env/config +++ b/arch/arm/boards/scb9328/env/config @@ -23,14 +23,9 @@ rootfs_loc=net rootfs_type=ubifs rootfsimage=root-$machine.$rootfs_type -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -kernelimage_type=zimage kernelimage=zImage-$machine -#kernelimage_type=uimage #kernelimage=uImage-$machine -#kernelimage_type=raw #kernelimage=Image-$machine -#kernelimage_type=raw_lzo #kernelimage=Image-$machine.lzo if [ -n $user ]; then diff --git a/arch/arm/boards/usb-a926x/env/config b/arch/arm/boards/usb-a926x/env/config index d77f6785f..96a452484 100644 --- a/arch/arm/boards/usb-a926x/env/config +++ b/arch/arm/boards/usb-a926x/env/config @@ -19,14 +19,9 @@ rootfs_loc=net rootfs_type=ubifs rootfsimage=root.$rootfs_type -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -#kernelimage_type=zimage #kernelimage=zImage -kernelimage_type=uimage kernelimage=uImage -#kernelimage_type=raw #kernelimage=Image -#kernelimage_type=raw_lzo #kernelimage=Image.lzo nand_device=atmel_nand diff --git a/arch/arm/boards/versatile/env/config b/arch/arm/boards/versatile/env/config index 9c5ce6133..667dce374 100644 --- a/arch/arm/boards/versatile/env/config +++ b/arch/arm/boards/versatile/env/config @@ -19,14 +19,9 @@ rootfs_loc=initrd rootfs_type=ubifs rootfsimage=root.$rootfs_type -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -#kernelimage_type=zimage #kernelimage=zImage -kernelimage_type=uimage kernelimage=uImage -#kernelimage_type=raw #kernelimage=Image -#kernelimage_type=raw_lzo #kernelimage=Image.lzo nfsroot="$eth0.serverip:/opt/work/busybox/arm9/rootfs_arm" diff --git a/arch/nios2/boards/generic/env/config b/arch/nios2/boards/generic/env/config index 5d2309839..16adc49f1 100644 --- a/arch/nios2/boards/generic/env/config +++ b/arch/nios2/boards/generic/env/config @@ -5,7 +5,6 @@ kernel=flash root=flash kernel_loc=nor -kernelimage_type=uimage # use 'dhcp' todo dhcp in barebox and in kernel ip=none diff --git a/defaultenv/bin/boot b/defaultenv/bin/boot index 90ebf9a3d..11207573c 100644 --- a/defaultenv/bin/boot +++ b/defaultenv/bin/boot @@ -72,35 +72,12 @@ if [ -n $mtdparts ]; then bootargs="${bootargs} mtdparts=${mtdparts}" fi -if [ ! -e /dev/ram0.kernelraw ]; then - # arm raw kernel images are usually located at sdram start + 0x8000 - addpart /dev/ram0 8M@0x8000(kernelraw) -fi - -if [ ! -e /dev/ram0.kernel ]; then - # Here we can safely put the kernel without risking of overwriting it - # while extracting - addpart /dev/ram0 8M@8M(kernel) -fi - if [ x$kernel_loc = xnfs -o x$kernel_loc = xtftp ]; then if [ x$ip = xdhcp ]; then dhcp fi - if [ $kernelimage_type = uimage ]; then - netload="/dev/ram0.kernel" - elif [ $kernelimage_type = zimage ]; then - netload="/dev/ram0.kernel" - elif [ $kernelimage_type = raw ]; then - netload="/dev/ram0.kernelraw" - elif [ $kernelimage_type = raw_lzo ]; then - netload="/dev/ram0.kernel" - else - echo "error: set kernelimage_type to one of 'uimage', 'zimage', 'raw' or 'raw_lzo'" - exit 1 - fi - $kernel_loc $kernelimage $netload || exit 1 - kdev="$netload" + kdev=/image + $kernel_loc $kernelimage $kdev || exit 1 elif [ x$kernel_loc = xnor ]; then kdev="/dev/nor0.kernel" elif [ x$kernel_loc = xnand ]; then @@ -112,18 +89,6 @@ else exit 1 fi -echo "booting kernel of type $kernelimage_type from $kdev" +echo "booting kernel from $kdev" -if [ x$kernelimage_type = xuimage ]; then - bootm $bootm_opt $kdev -elif [ x$kernelimage_type = xzimage ]; then - bootz $kdev -elif [ x$kernelimage_type = xraw ]; then - if [ $kernel_loc != net ]; then - cp $kdev /dev/ram0.kernelraw - fi - bootu /dev/ram0.kernelraw -elif [ x$kernelimage_type = xraw_lzo ]; then - uncompress $kdev /dev/ram0.kernelraw - bootu /dev/ram0.kernelraw -fi +bootm $bootm_opt $kdev diff --git a/defaultenv/config b/defaultenv/config index 0aaead5cc..98662735e 100644 --- a/defaultenv/config +++ b/defaultenv/config @@ -31,14 +31,9 @@ rootfsimage=rootfs-${machine}.$rootfs_type # where is the kernel image in case of 'kernel_loc=disk' kernel_part=disk0.2 -# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo -kernelimage_type=zimage kernelimage=zImage-$machine -#kernelimage_type=uimage #kernelimage=uImage-$machine -#kernelimage_type=raw #kernelimage=Image-$machine -#kernelimage_type=raw_lzo #kernelimage=Image-$machine.lzo bareboximage=barebox-${machine}.bin