9
0
Fork 0

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:
Sascha Hauer 2011-12-17 16:33:57 +01:00
commit 146a7fe4a2
60 changed files with 1640 additions and 864 deletions

View File

@ -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)"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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'?"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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 */

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

108
commands/uimage.c Normal file
View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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(&timestamp));
#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

View File

@ -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;
}

505
common/uimage.c Normal file
View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -14,6 +14,7 @@ enum filetype {
filetype_jffs2,
filetype_gzip,
filetype_bzip2,
filetype_oftree,
};
const char *file_type_to_string(enum filetype f);

View File

@ -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__ */

View File

@ -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 */

View File

@ -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,

View File

@ -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);

View File

@ -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);
}

View File

@ -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(&timestamp));
}
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)
{