Merge branch 'work/uimage' into next
Conflicts: arch/ppc/lib/ppclinux.c commands/bootm.c include/boot.h Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
commit
146a7fe4a2
|
@ -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)"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'?"
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include <malloc.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sizes.h>
|
||||
#include <libbb.h>
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/setup.h>
|
||||
|
@ -18,32 +20,223 @@
|
|||
#include <asm/armlinux.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
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);
|
||||
|
|
|
@ -3,12 +3,14 @@
|
|||
#include <fs.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <of.h>
|
||||
#include <asm/armlinux.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <fs.h>
|
||||
#include <of.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
|
@ -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;
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <asm/byteorder.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/blackfin.h>
|
||||
#include <errno.h>
|
||||
#include <init.h>
|
||||
#include <boot.h>
|
||||
|
||||
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -31,17 +31,20 @@
|
|||
#include <environment.h>
|
||||
#include <init.h>
|
||||
#include <boot.h>
|
||||
#include <errno.h>
|
||||
#include <asm/cache.h>
|
||||
|
||||
#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)
|
||||
|
|
|
@ -10,18 +10,15 @@
|
|||
#include <errno.h>
|
||||
#include <fs.h>
|
||||
|
||||
#ifdef CONFIG_OF_FLAT_TREE
|
||||
#include <ft_build.h>
|
||||
#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 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)
|
||||
|
@ -50,4 +49,3 @@ static int ppclinux_register_image_handler(void)
|
|||
}
|
||||
|
||||
late_initcall(ppclinux_register_image_handler);
|
||||
|
||||
|
|
|
@ -310,11 +310,40 @@ config CMD_BOOTM_SHOW_TYPE
|
|||
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
|
||||
|
|
|
@ -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
|
||||
|
|
461
commands/bootm.c
461
commands/bootm.c
|
@ -38,53 +38,29 @@
|
|||
#include <errno.h>
|
||||
#include <boot.h>
|
||||
#include <of.h>
|
||||
#include <libfdt.h>
|
||||
#include <rtc.h>
|
||||
#include <init.h>
|
||||
#include <of.h>
|
||||
#include <magicvar.h>
|
||||
#include <uncompress.h>
|
||||
#include <memory.h>
|
||||
#include <filetype.h>
|
||||
#include <asm-generic/memory_layout.h>
|
||||
|
||||
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 @@ 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 @<num> */
|
||||
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 <initrd>","specify an initrd image\n")
|
||||
BAREBOX_CMD_HELP_OPT ("-L <load addr>","specify initrd load address")
|
||||
BAREBOX_CMD_HELP_OPT ("-L <load addr>","specify initrd load address\n")
|
||||
#endif
|
||||
BAREBOX_CMD_HELP_OPT ("-a <load addr>","specify os load address\n")
|
||||
BAREBOX_CMD_HELP_OPT ("-e <ofs>","entry point to the image relative to start (0)\n")
|
||||
#ifdef CONFIG_OFTREE
|
||||
BAREBOX_CMD_HELP_OPT ("-o <oftree>","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_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
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <image.h>
|
||||
#include <fs.h>
|
||||
#include <malloc.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
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
|
|
@ -0,0 +1,108 @@
|
|||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <image.h>
|
||||
#include <libbb.h>
|
||||
#include <fcntl.h>
|
||||
#include <fs.h>
|
||||
#include <malloc.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
|
||||
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] <file>\n")
|
||||
BAREBOX_CMD_HELP_OPT ("-i", "show information about image\n")
|
||||
BAREBOX_CMD_HELP_OPT ("-v", "verify image\n")
|
||||
BAREBOX_CMD_HELP_OPT ("-e <outfile>", "extract image to <outfile>\n")
|
||||
BAREBOX_CMD_HELP_OPT ("-n <no>", "use image number <no> 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
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
287
common/image.c
287
common/image.c
|
@ -144,290 +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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,505 @@
|
|||
/*
|
||||
* uimage.c - uimage handling code
|
||||
*
|
||||
* Copyright (c) 2011 Sascha Hauer <s.hauer@pengutronix.de>, 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 <common.h>
|
||||
#include <image.h>
|
||||
#include <malloc.h>
|
||||
#include <errno.h>
|
||||
#include <libbb.h>
|
||||
#include <uncompress.h>
|
||||
#include <fcntl.h>
|
||||
#include <fs.h>
|
||||
#include <rtc.h>
|
||||
#include <filetype.h>
|
||||
#include <memory.h>
|
||||
|
||||
#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;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -2,25 +2,73 @@
|
|||
#define __BOOT_H
|
||||
|
||||
#include <image.h>
|
||||
#include <filetype.h>
|
||||
#include <of.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
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 */
|
||||
|
|
|
@ -14,6 +14,7 @@ enum filetype {
|
|||
filetype_jffs2,
|
||||
filetype_gzip,
|
||||
filetype_bzip2,
|
||||
filetype_oftree,
|
||||
};
|
||||
|
||||
const char *file_type_to_string(enum filetype f);
|
||||
|
|
153
include/image.h
153
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);
|
||||
|
@ -232,121 +218,34 @@ 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);
|
||||
}
|
||||
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__ */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
|
50
lib/libbb.c
50
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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue