9
0
Fork 0

bootm: use new uimage code

This switches the bootm code to the new uimage code. Also
bootm can now handle other types of images than uImages.
Currently the only architecture making use of this is
arm which allows to boot zImages, raw images and barebox
images.
I intended to make a more bisectable series from this but
I failed becuase there are many dependencies and no matter
how I tried the patches grew bigger and and bigger. So I
decided to put this all in a single patch.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
Sascha Hauer 2011-12-06 08:53:26 +01:00
parent 390249968c
commit d4e5c6b8a0
7 changed files with 638 additions and 168 deletions

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,33 +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((void *)theKernel, 0, data->initrd_address, data->initrd_size,
data->oftree);
kernel = data->os_res->start + data->os_entry;
return -1;
if (data->initrd_file && data->initrd_address == UIMAGE_INVALID_ADDRESS) {
initrd_start = data->os_res->start + SZ_8M;
if (bootm_verbose(data)) {
printf("no initrd load address, defaulting to 0x%08lx\n",
initrd_start);
}
}
if (data->initrd) {
data->initrd_res = uimage_load_to_sdram(data->initrd,
data->initrd_num, initrd_start);
if (!data->initrd_res)
return -ENOMEM;
} else if (data->initrd_file) {
data->initrd_res = file_to_sdram(data->initrd_file, initrd_start);
if (!data->initrd_res)
return -ENOMEM;
}
if (data->initrd_res) {
initrd_start = data->initrd_res->start;
initrd_size = data->initrd_res->size;
}
if (bootm_verbose(data)) {
printf("\nStarting kernel at 0x%08lx", kernel);
if (initrd_size)
printf(", initrd at 0x%08lx", initrd_start);
if (data->oftree)
printf(", oftree at 0x%p", data->oftree);
printf("...\n");
}
start_linux((void *)kernel, swap, initrd_start, initrd_size, data->oftree);
reset_cpu(0);
return -ERESTARTSYS;
}
static struct image_handler handler = {
static int do_bootm_linux(struct image_data *data)
{
return __do_bootm_linux(data, 0);
}
static struct image_handler uimage_handler = {
.name = "ARM Linux uImage",
.bootm = do_bootm_linux,
.image_type = IH_OS_LINUX,
.filetype = filetype_uimage,
.ih_os = IH_OS_LINUX,
};
static struct image_handler rawimage_handler = {
.name = "ARM raw image",
.bootm = do_bootm_linux,
.filetype = filetype_unknown,
};
struct zimage_header {
u32 unused[9];
u32 magic;
u32 start;
u32 end;
};
#define ZIMAGE_MAGIC 0x016F2818
static int do_bootz_linux(struct image_data *data)
{
int fd, ret, swap = 0;
struct zimage_header __header, *header;
void *zimage;
u32 end;
unsigned long load_address = data->os_address;
if (load_address == UIMAGE_INVALID_ADDRESS) {
struct memory_bank *bank = list_first_entry(&memory_banks,
struct memory_bank, list);
data->os_address = bank->start + SZ_8M;
if (bootm_verbose(data))
printf("no os load address, defaulting to 0x%08lx\n",
load_address);
}
fd = open(data->os_file, O_RDONLY);
if (fd < 0) {
perror("open");
return 1;
}
header = &__header;
ret = read(fd, header, sizeof(*header));
if (ret < sizeof(*header)) {
printf("could not read %s\n", data->os_file);
goto err_out;
}
switch (header->magic) {
case swab32(ZIMAGE_MAGIC):
swap = 1;
/* fall through */
case ZIMAGE_MAGIC:
break;
default:
printf("invalid magic 0x%08x\n", header->magic);
ret = -EINVAL;
goto err_out;
}
end = header->end;
if (swap)
end = swab32(end);
data->os_res = request_sdram_region("zimage", load_address, end);
if (!data->os_res) {
ret = -ENOMEM;
goto err_out;
}
zimage = (void *)data->os_res->start;
memcpy(zimage, header, sizeof(*header));
ret = read_full(fd, zimage + sizeof(*header), end - sizeof(*header));
if (ret < 0)
goto err_out;
if (ret < end - sizeof(*header)) {
printf("premature end of image\n");
ret = -EIO;
goto err_out;
}
if (swap) {
void *ptr;
for (ptr = zimage; ptr < zimage + end; ptr += 4)
*(u32 *)ptr = swab32(*(u32 *)ptr);
}
return __do_bootm_linux(data, swap);
err_out:
close(fd);
return ret;
}
static struct image_handler zimage_handler = {
.name = "ARM zImage",
.bootm = do_bootz_linux,
.filetype = filetype_arm_zimage,
};
static int do_bootm_barebox(struct image_data *data)
{
void (*barebox)(void);
barebox = read_file(data->os_file, NULL);
if (!barebox)
return -EINVAL;
shutdown_barebox();
barebox();
reset_cpu(0);
}
static struct image_handler barebox_handler = {
.name = "ARM barebox",
.bootm = do_bootm_barebox,
.filetype = filetype_arm_barebox,
};
static int armlinux_register_image_handler(void)
{
return register_image_handler(&handler);
}
register_image_handler(&barebox_handler);
register_image_handler(&uimage_handler);
register_image_handler(&rawimage_handler);
register_image_handler(&zimage_handler);
return 0;
}
late_initcall(armlinux_register_image_handler);

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

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

@ -11,18 +11,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):
@ -41,8 +38,10 @@ static int do_bootm_linux(struct image_data *data)
}
static struct image_handler handler = {
.name = "PowerPC Linux",
.bootm = do_bootm_linux,
.image_type = IH_OS_LINUX,
.filetype = filetype_uimage,
.ih_os = IH_OS_LINUX,
};
static int ppclinux_register_image_handler(void)
@ -51,4 +50,3 @@ static int ppclinux_register_image_handler(void)
}
late_initcall(ppclinux_register_image_handler);

View File

@ -310,6 +310,28 @@ config CMD_BOOTM_SHOW_TYPE
depends on CMD_BOOTM
prompt "show image information"
config CMD_BOOTM_VERBOSE
bool
prompt "bootm verbose support"
depends on CMD_BOOTM
help
support verbose bootm (-v switch)
config CMD_BOOTM_INITRD
bool
prompt "bootm initrd support"
depends on CMD_BOOTM
help
support initrds in bootm
config CMD_BOOTM_OFTREE_UIMAGE
bool
prompt "support passing oftree uImages"
depends on CMD_BOOTM
help
Support using oftree uImages. Without this only raw oftree
blobs can be used.
config CMD_IMINFO
bool
prompt "iminfo"

View File

@ -39,53 +39,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)
{
@ -93,148 +69,380 @@ int register_image_handler(struct image_handler *handler)
return 0;
}
/*
* generate a image_handle from a multi_image
* this image_handle can be freed by unmap_image
*/
static struct image_handle *get_fake_image_handle(struct image_data *data, int num)
#define UIMAGE_SOME_ADDRESS (UIMAGE_INVALID_ADDRESS - 1)
static int bootm_open_os_uimage(struct image_data *data)
{
struct image_handle *handle;
struct image_handle_data* iha;
image_header_t *header;
int ret;
iha = image_handle_data_get_by_num(data->os, num);
data->os = uimage_open(data->os_file);
if (!data->os)
return -EINVAL;
handle = xzalloc(sizeof(struct image_handle));
header = &handle->header;
handle->data_entries = gen_image_handle_data(iha->data, iha->len);
handle->nb_data_entries = 1;
header->ih_size = cpu_to_uimage(iha->len);
handle->data = handle->data_entries[0].data;
if (data->verify) {
ret = uimage_verify(data->os);
if (ret) {
printf("Checking data crc failed with %s\n",
strerror(-ret));
return ret;
}
}
return handle;
uimage_print_contents(data->os);
if (data->os->header.ih_arch != IH_ARCH) {
printf("Unsupported Architecture 0x%x\n",
data->os->header.ih_arch);
return -EINVAL;
}
if (data->os_address == UIMAGE_SOME_ADDRESS)
data->os_address = data->os->header.ih_load;
if (data->os_address != UIMAGE_INVALID_ADDRESS) {
data->os_res = uimage_load_to_sdram(data->os, 0,
data->os_address);
if (!data->os_res)
return -ENOMEM;
}
return 0;
}
static int bootm_open_initrd_uimage(struct image_data *data)
{
int ret;
if (!data->initrd_file)
return 0;
if (strcmp(data->os_file, data->initrd_file)) {
data->initrd = uimage_open(data->initrd_file);
if (!data->initrd)
return -EINVAL;
if (data->verify) {
ret = uimage_verify(data->initrd);
if (ret) {
printf("Checking data crc failed with %s\n",
strerror(-ret));
}
}
uimage_print_contents(data->initrd);
} else {
data->initrd = data->os;
}
if (data->initrd_address == UIMAGE_SOME_ADDRESS)
data->initrd_address = data->initrd->header.ih_load;
if (data->initrd_address != UIMAGE_INVALID_ADDRESS) {
data->initrd_res = uimage_load_to_sdram(data->initrd,
data->initrd_num,
data->initrd_address);
if (!data->initrd_res)
return -ENOMEM;
}
return 0;
}
#ifdef CONFIG_OFTREE
static int bootm_open_oftree(struct image_data *data, char *oftree, int num)
{
enum filetype ft;
struct fdt_header *fdt;
int ret;
size_t size;
ft = file_name_detect_type(oftree);
if ((int)ft < 0)
return ft;
if (ft == filetype_uimage) {
#ifdef CONFIG_CMD_BOOTM_OFTREE_UIMAGE
struct uimage_handle *of_handle;
int release = 0;
if (!strcmp(data->os_file, oftree)) {
of_handle = data->os;
} else if (!strcmp(data->initrd_file, oftree)) {
of_handle = data->initrd;
} else {
of_handle = uimage_open(oftree);
if (!of_handle)
return -ENODEV;
uimage_print_contents(of_handle);
release = 1;
}
fdt = uimage_load_to_buf(of_handle, num, &size);
if (release)
uimage_close(of_handle);
#else
return -EINVAL;
#endif
} else {
fdt = read_file(oftree, &size);
if (!fdt) {
perror("open");
return -ENODEV;
}
}
ft = file_detect_type(fdt);
if (ft != filetype_oftree) {
printf("%s is not a oftree but %s\n", oftree,
file_type_to_string(ft));
}
if (bootm_verbose(data))
printf("Loading oftree from '%s'\n", oftree);
fdt = xrealloc(fdt, size + 0x8000);
fdt_open_into(fdt, fdt, size + 0x8000);
if (!fdt) {
printf("unable to read %s\n", oftree);
return -ENODEV;
}
ret = of_fix_tree(fdt);
if (ret)
return ret;
if (bootm_verbose(data) > 1)
fdt_print(fdt, "/");
data->oftree = fdt;
return ret;
}
#endif
static struct image_handler *bootm_find_handler(enum filetype filetype,
struct image_data *data)
{
struct image_handler *handler;
list_for_each_entry(handler, &handler_list, list) {
if (filetype != filetype_uimage &&
handler->filetype == filetype)
return handler;
if (filetype == filetype_uimage &&
handler->ih_os == data->os->header.ih_os)
return handler;
}
return NULL;
}
static void bootm_image_name_and_no(char *name, int *no)
{
char *at;
*no = 0;
at = strchr(name, '@');
if (!at)
return;
*at++ = 0;
*no = simple_strtoul(at, NULL, 10);
}
static int do_bootm(struct command *cmdtp, int argc, char *argv[])
{
int opt;
image_header_t *os_header;
struct image_handle *os_handle = NULL;
int opt;
struct image_handler *handler;
struct image_data data;
const char *initrdname = NULL;
int ret = 1;
enum filetype os_type, initrd_type = filetype_unknown;
char *oftree = NULL;
int fallback = 0;
memset(&data, 0, sizeof(struct image_data));
data.verify = 1;
data.initrd_address = ~0;
while ((opt = getopt(argc, argv, "nr:L:")) > 0) {
data.initrd_address = UIMAGE_SOME_ADDRESS;
data.os_address = UIMAGE_SOME_ADDRESS;
data.verify = 0;
data.verbose = 0;
while ((opt = getopt(argc, argv, "cL:r:a:e:vo:f")) > 0) {
switch(opt) {
case 'n':
data.verify = 0;
case 'c':
data.verify = 1;
break;
#ifdef CONFIG_CMD_BOOTM_INITRD
case 'L':
data.initrd_address = simple_strtoul(optarg, NULL, 0);
break;
case 'r':
initrdname = optarg;
data.initrd_file = optarg;
break;
#endif
case 'a':
data.os_address = simple_strtoul(optarg, NULL, 0);
break;
case 'e':
data.os_entry = simple_strtoul(optarg, NULL, 0);
break;
case 'v':
data.verbose++;
break;
case 'o':
oftree = optarg;
break;
case 'f':
fallback = 1;
break;
default:
break;
}
}
#ifdef CONFIG_OFTREE
data.oftree = of_get_fixed_tree();
#endif
if (optind == argc)
return COMMAND_ERROR_USAGE;
if (optind == argc) {
ret = COMMAND_ERROR_USAGE;
data.os_file = argv[optind];
bootm_image_name_and_no(data.os_file, &data.os_num);
os_type = file_name_detect_type(data.os_file);
if ((int)os_type < 0) {
printf("could not open %s: %s\n", data.os_file,
strerror(-os_type));
goto err_out;
}
os_handle = map_image(argv[optind], data.verify);
if (!os_handle)
goto err_out;
data.os = os_handle;
os_header = &os_handle->header;
if (image_get_arch(os_header) != IH_ARCH) {
printf("Unsupported Architecture 0x%x\n",
image_get_arch(os_header));
if (!fallback && os_type == filetype_unknown) {
printf("Unknown OS filetype (try -f)\n");
goto err_out;
}
if (initrdname) {
/* check for multi image @<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)
@ -245,13 +453,6 @@ BAREBOX_CMD_END
BAREBOX_MAGICVAR(bootargs, "Linux Kernel parameters");
#ifdef CONFIG_BZLIB
void bz_internal_error(int errcode)
{
printf ("BZIP2 internal error %d\n", errcode);
}
#endif /* CONFIG_BZLIB */
/**
* @file
* @brief Boot support for Linux

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