diff --git a/arch/arm/boards/at91rm9200ek/env/config b/arch/arm/boards/at91rm9200ek/env/config index 1b56b25..12655c2 100644 --- a/arch/arm/boards/at91rm9200ek/env/config +++ b/arch/arm/boards/at91rm9200ek/env/config @@ -19,14 +19,9 @@ 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 733326d..d6eeea4 100644 --- a/arch/arm/boards/at91sam9261ek/env/config +++ b/arch/arm/boards/at91sam9261ek/env/config @@ -19,14 +19,9 @@ 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 4e29232..bd771ac 100644 --- a/arch/arm/boards/at91sam9263ek/env/config +++ b/arch/arm/boards/at91sam9263ek/env/config @@ -19,14 +19,9 @@ 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 b8ca18d..3dea724 100644 --- a/arch/arm/boards/at91sam9m10g45ek/env/config +++ b/arch/arm/boards/at91sam9m10g45ek/env/config @@ -19,14 +19,9 @@ 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 981a387..999170c 100644 --- a/arch/arm/boards/chumby_falconwing/env/bin/boot +++ b/arch/arm/boards/chumby_falconwing/env/bin/boot @@ -26,13 +26,6 @@ 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 1e61dce..1419161 100644 --- a/arch/arm/boards/chumby_falconwing/env/config +++ b/arch/arm/boards/chumby_falconwing/env/config @@ -25,8 +25,6 @@ # 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 5c9be7d..adf3af5 100644 --- a/arch/arm/boards/dss11/env/config +++ b/arch/arm/boards/dss11/env/config @@ -19,14 +19,9 @@ 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 5cedbf8..bc1cfd5 100644 --- a/arch/arm/boards/eukrea_cpuimx25/env/config +++ b/arch/arm/boards/eukrea_cpuimx25/env/config @@ -25,7 +25,6 @@ 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 776d19a..8f64ba0 100644 --- a/arch/arm/boards/eukrea_cpuimx35/env/config +++ b/arch/arm/boards/eukrea_cpuimx35/env/config @@ -25,7 +25,6 @@ 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 91a2671..1b57b29 100644 --- a/arch/arm/boards/eukrea_cpuimx51/env/config +++ b/arch/arm/boards/eukrea_cpuimx51/env/config @@ -28,7 +28,6 @@ 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 ee9bd07..17b1e31 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_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 8e6b34e..10690c9 100644 --- a/arch/arm/boards/freescale-mx51-pdk/env/config +++ b/arch/arm/boards/freescale-mx51-pdk/env/config @@ -23,14 +23,9 @@ 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 3659a62..fd238a6 100644 --- a/arch/arm/boards/freescale-mx53-loco/env/config +++ b/arch/arm/boards/freescale-mx53-loco/env/config @@ -23,14 +23,9 @@ 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 3659a62..fd238a6 100644 --- a/arch/arm/boards/freescale-mx53-smd/env/config +++ b/arch/arm/boards/freescale-mx53-smd/env/config @@ -23,14 +23,9 @@ 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 cd11eb1..930a97d 100644 --- a/arch/arm/boards/guf-cupid/env/config +++ b/arch/arm/boards/guf-cupid/env/config @@ -23,14 +23,9 @@ 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 162488f..9b675b5 100644 --- a/arch/arm/boards/guf-neso/env/config +++ b/arch/arm/boards/guf-neso/env/config @@ -23,14 +23,9 @@ 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 9113a87..69f2c26 100644 --- a/arch/arm/boards/karo-tx25/env/config +++ b/arch/arm/boards/karo-tx25/env/config @@ -23,14 +23,9 @@ 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 fdf57ea..ed361eb 100644 --- a/arch/arm/boards/karo-tx28/env/config +++ b/arch/arm/boards/karo-tx28/env/config @@ -24,14 +24,9 @@ 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 ff6f1ea..ac8c32a 100644 --- a/arch/arm/boards/mini2440/env/config +++ b/arch/arm/boards/mini2440/env/config @@ -23,14 +23,9 @@ 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 7428c43..c05ed27 100644 --- a/arch/arm/boards/nhk8815/env/config +++ b/arch/arm/boards/nhk8815/env/config @@ -19,14 +19,9 @@ 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 363208e..29672be 100644 --- a/arch/arm/boards/panda/env/config +++ b/arch/arm/boards/panda/env/config @@ -18,14 +18,9 @@ # 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 3748cc4..d67d319 100644 --- a/arch/arm/boards/pcm037/env/config +++ b/arch/arm/boards/pcm037/env/config @@ -23,14 +23,9 @@ 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 9e28f5d..eb0f9c1 100644 --- a/arch/arm/boards/pcm038/env/config +++ b/arch/arm/boards/pcm038/env/config @@ -23,14 +23,9 @@ 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 e7f94f8..2a355e6 100644 --- a/arch/arm/boards/pcm043/env/config +++ b/arch/arm/boards/pcm043/env/config @@ -23,14 +23,9 @@ 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 54b2e3d..f348714 100644 --- a/arch/arm/boards/pcm049/env/config +++ b/arch/arm/boards/pcm049/env/config @@ -23,14 +23,9 @@ 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 0e20b48..5db33d0 100644 --- a/arch/arm/boards/phycard-i.MX27/env/config +++ b/arch/arm/boards/phycard-i.MX27/env/config @@ -23,14 +23,9 @@ 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 7933379..bdc2d38 100644 --- a/arch/arm/boards/pm9261/env/config +++ b/arch/arm/boards/pm9261/env/config @@ -19,14 +19,9 @@ 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 b8ca18d..3dea724 100644 --- a/arch/arm/boards/pm9g45/env/config +++ b/arch/arm/boards/pm9g45/env/config @@ -19,14 +19,9 @@ 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 d0f3f25..e1c5807 100644 --- a/arch/arm/boards/scb9328/env/config +++ b/arch/arm/boards/scb9328/env/config @@ -23,14 +23,9 @@ 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 d77f678..96a4524 100644 --- a/arch/arm/boards/usb-a926x/env/config +++ b/arch/arm/boards/usb-a926x/env/config @@ -19,14 +19,9 @@ 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 9c5ce61..667dce3 100644 --- a/arch/arm/boards/versatile/env/config +++ b/arch/arm/boards/versatile/env/config @@ -19,14 +19,9 @@ 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/arm/include/asm/armlinux.h b/arch/arm/include/asm/armlinux.h index ba3a424..9ca1e4b 100644 --- a/arch/arm/include/asm/armlinux.h +++ b/arch/arm/include/asm/armlinux.h @@ -29,6 +29,7 @@ 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 bd9b72a..1d210d1 100644 --- a/arch/arm/lib/armlinux.c +++ b/arch/arm/lib/armlinux.c @@ -224,7 +224,8 @@ 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 @@ 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 @@ 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 031a269..d8bb701 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,32 +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(theKernel, 0, data); + 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/arm/lib/bootu.c b/arch/arm/lib/bootu.c index e97ded0..89d793a 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 @@ 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 956ea82..40facf6 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 @@ 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 @@ } 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; diff --git a/arch/blackfin/lib/blackfin_linux.c b/arch/blackfin/lib/blackfin_linux.c index 9da9ec4..458d1b1 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 @@ 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 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/boards/generic/env/config b/arch/nios2/boards/generic/env/config index 5d23098..16adc49 100644 --- a/arch/nios2/boards/generic/env/config +++ b/arch/nios2/boards/generic/env/config @@ -5,7 +5,6 @@ root=flash kernel_loc=nor -kernelimage_type=uimage # use 'dhcp' todo dhcp in barebox and in kernel ip=none diff --git a/arch/nios2/lib/bootm.c b/arch/nios2/lib/bootm.c index b5b344f..1cd43c8 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 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 3446bb9..95dc83b 100644 --- a/arch/ppc/lib/ppclinux.c +++ b/arch/ppc/lib/ppclinux.c @@ -10,18 +10,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): @@ -40,8 +37,10 @@ } 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) @@ -50,4 +49,3 @@ } late_initcall(ppclinux_register_image_handler); - diff --git a/commands/Kconfig b/commands/Kconfig index ebc9c7f..3e9f06f 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -310,11 +310,40 @@ depends on CMD_BOOTM prompt "show image information" -config CMD_IMINFO +config CMD_BOOTM_VERBOSE bool - prompt "iminfo" + prompt "bootm verbose support" + depends on CMD_BOOTM help - Show information about uImages + 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 + bool + select OFTREE + prompt "bootm oftree support" + help + say yes here to support passing a flat device tree to the kernel + +config CMD_BOOTM_OFTREE_UIMAGE + bool + prompt "support passing oftree uImages" + depends on CMD_BOOTM_OFTREE + help + Support using oftree uImages. Without this only raw oftree + blobs can be used. + +config CMD_UIMAGE + tristate + prompt "uimage" + help + Show information about uImage and also extract and verify uImages. config CMD_BOOTZ tristate diff --git a/commands/Makefile b/commands/Makefile index aa013de..24753be 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -1,5 +1,5 @@ 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/bootm.c b/commands/bootm.c index f98a51c..c23f4f3 100644 --- a/commands/bootm.c +++ b/commands/bootm.c @@ -38,53 +38,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) { @@ -92,148 +68,380 @@ 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) @@ -244,13 +452,6 @@ 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/commands/iminfo.c b/commands/iminfo.c deleted file mode 100644 index 2fde9bc..0000000 --- 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 diff --git a/commands/uimage.c b/commands/uimage.c new file mode 100644 index 0000000..82efd78 --- /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 diff --git a/common/Makefile b/common/Makefile index 237c6b0..e02650b 100644 --- a/common/Makefile +++ b/common/Makefile @@ -22,6 +22,7 @@ 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/filetype.c b/common/filetype.c index 5635d40..40faff3 100644 --- a/common/filetype.c +++ b/common/filetype.c @@ -36,6 +36,7 @@ [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 @@ 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/common/image.c b/common/image.c index d68889b..e7d2242 100644 --- a/common/image.c +++ b/common/image.c @@ -144,290 +144,3 @@ 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); - } - } - } -} - -#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/common/oftree.c b/common/oftree.c index 2a2f464..a657d31 100644 --- a/common/oftree.c +++ b/common/oftree.c @@ -293,20 +293,28 @@ 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/common/uimage.c b/common/uimage.c new file mode 100644 index 0000000..28791b5 --- /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/defaultenv/bin/boot b/defaultenv/bin/boot index 90ebf9a..1120757 100644 --- a/defaultenv/bin/boot +++ b/defaultenv/bin/boot @@ -72,35 +72,12 @@ 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 @@ 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 0aaead5..9866273 100644 --- a/defaultenv/config +++ b/defaultenv/config @@ -31,14 +31,9 @@ # 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 diff --git a/include/boot.h b/include/boot.h index 297b944..a17bf25 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 */ diff --git a/include/filetype.h b/include/filetype.h index 64d32ef..88f31df 100644 --- a/include/filetype.h +++ b/include/filetype.h @@ -14,6 +14,7 @@ filetype_jffs2, filetype_gzip, filetype_bzip2, + filetype_oftree, }; const char *file_type_to_string(enum filetype f); diff --git a/include/image.h b/include/image.h index f3a9949..35ff01b 100644 --- a/include/image.h +++ b/include/image.h @@ -188,20 +188,6 @@ 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); @@ -232,121 +218,34 @@ #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); -} +struct uimage_handle_data { + size_t offset; /* offset in the image */ + ulong len; +}; -#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); \ -} +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 -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 */ +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 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); - -/* - * 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); +#define UIMAGE_INVALID_ADDRESS (~0) #endif /* __IMAGE_H__ */ diff --git a/include/libbb.h b/include/libbb.h index 2d17c3f..110e8ec 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -32,4 +32,7 @@ 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/include/of.h b/include/of.h index c2661ef..609b3b5 100644 --- a/include/of.h +++ b/include/of.h @@ -8,6 +8,7 @@ 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, diff --git a/lib/libbb.c b/lib/libbb.c index 3d02202..9a0a60b 100644 --- a/lib/libbb.c +++ b/lib/libbb.c @@ -127,3 +127,53 @@ 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); diff --git a/lib/uncompress.c b/lib/uncompress.c index beb96d1..cdfebe9 100644 --- a/lib/uncompress.c +++ b/lib/uncompress.c @@ -158,3 +158,11 @@ 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); +} diff --git a/scripts/mkimage.c b/scripts/mkimage.c index b219cb8..64290cf 100644 --- a/scripts/mkimage.c +++ b/scripts/mkimage.c @@ -62,6 +62,246 @@ 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) {