- Add functions to register image handlers for booting uImages
This commit is contained in:
parent
e912912a48
commit
f95ec8a32d
|
@ -28,6 +28,7 @@
|
|||
#include <environment.h>
|
||||
#include <image.h>
|
||||
#include <zlib.h>
|
||||
#include <init.h>
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/global_data.h>
|
||||
|
@ -107,12 +108,13 @@ void __setup_serial_tag(struct tag **tmp);
|
|||
# define SHOW_BOOT_PROGRESS(arg)
|
||||
#endif
|
||||
|
||||
static int arm_architecture = CONFIG_ARCH_NUMBER;
|
||||
|
||||
int
|
||||
do_bootm_linux(struct image_handle *os_handle, struct image_handle *initrd)
|
||||
do_bootm_linux(struct image_data *data)
|
||||
{
|
||||
void (*theKernel)(int zero, int arch, uint params);
|
||||
image_header_t *os_header = &os_handle->header;
|
||||
image_header_t *os_header = &data->os->header;
|
||||
const char *commandline = getenv ("bootargs");
|
||||
|
||||
if (os_header->ih_type == IH_TYPE_MULTI) {
|
||||
|
@ -120,11 +122,11 @@ do_bootm_linux(struct image_handle *os_handle, struct image_handle *initrd)
|
|||
return -1;
|
||||
}
|
||||
|
||||
printf("commandline: %s\n", commandline);
|
||||
printf("commandline: %s\n"
|
||||
"arch_number: %d\n", commandline, arm_architecture);
|
||||
|
||||
theKernel = (void (*)(int, int, uint))ntohl((unsigned long)(os_header->ih_ep));
|
||||
|
||||
/* FIXME: replace by pr_debug */
|
||||
debug ("## Transferring control to Linux (at address %08lx) ...\n",
|
||||
(ulong) theKernel);
|
||||
|
||||
|
@ -140,25 +142,45 @@ do_bootm_linux(struct image_handle *os_handle, struct image_handle *initrd)
|
|||
setup_videolfb_tag((gd_t *) gd);
|
||||
setup_end_tag();
|
||||
|
||||
if (relocate_image(os_handle, (void *)ntohl(os_header->ih_load)))
|
||||
if (relocate_image(data->os, (void *)ntohl(os_header->ih_load)))
|
||||
return -1;
|
||||
|
||||
/* we assume that the kernel is in place */
|
||||
printf ("\nStarting kernel ...\n\n");
|
||||
|
||||
#ifdef CONFIG_USB_DEVICE
|
||||
{
|
||||
extern void udc_disconnect(void);
|
||||
udc_disconnect();
|
||||
}
|
||||
#endif
|
||||
|
||||
cleanup_before_linux();
|
||||
theKernel (0, CONFIG_ARCH_NUMBER, CONFIG_BOOT_PARAMS);
|
||||
theKernel (0, arm_architecture, CONFIG_BOOT_PARAMS);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int image_handle_cmdline_parse(struct image_data *data, int opt,
|
||||
char *optarg)
|
||||
{
|
||||
switch (opt) {
|
||||
case 'a':
|
||||
arm_architecture = simple_strtoul(optarg, NULL, 0);
|
||||
return 0;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static struct image_handler handler = {
|
||||
.cmdline_options = "a:",
|
||||
.cmdline_parse = image_handle_cmdline_parse,
|
||||
.help_string = " -a <arch> use architecture number <arch>",
|
||||
|
||||
.bootm = do_bootm_linux,
|
||||
.image_type = IH_OS_LINUX,
|
||||
};
|
||||
|
||||
static int armlinux_register_image_handler(void)
|
||||
{
|
||||
return register_image_handler(&handler);
|
||||
}
|
||||
|
||||
late_initcall(armlinux_register_image_handler);
|
||||
|
||||
void
|
||||
__setup_start_tag(void)
|
||||
|
|
|
@ -4,9 +4,11 @@
|
|||
#include <command.h>
|
||||
#include <watchdog.h>
|
||||
#include <image.h>
|
||||
#include <init.h>
|
||||
#include <environment.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <asm/bitops.h>
|
||||
#include <boot.h>
|
||||
#include <errno.h>
|
||||
#include <fs.h>
|
||||
|
||||
|
@ -16,8 +18,7 @@
|
|||
extern bd_t *bd;
|
||||
#define SHOW_BOOT_PROGRESS(x)
|
||||
|
||||
int
|
||||
do_bootm_linux(struct image_handle *os_handle, struct image_handle *initrd_handle, const char *oftree)
|
||||
static int do_bootm_linux(struct image_data *idata)
|
||||
{
|
||||
ulong sp;
|
||||
ulong initrd_end = 0;
|
||||
|
@ -31,7 +32,7 @@ do_bootm_linux(struct image_handle *os_handle, struct image_handle *initrd_handl
|
|||
#ifdef CONFIG_OF_FLAT_TREE
|
||||
char *of_flat_tree = NULL;
|
||||
#endif
|
||||
image_header_t *os_header = &os_handle->header;
|
||||
image_header_t *os_header = &idata->os->header;
|
||||
image_header_t *initrd_header = NULL;
|
||||
void *os_data = NULL;
|
||||
void *initrd_data = NULL;
|
||||
|
@ -39,14 +40,14 @@ do_bootm_linux(struct image_handle *os_handle, struct image_handle *initrd_handl
|
|||
struct image_handle *oftree_handle;
|
||||
unsigned long os_len, initrd_len;
|
||||
|
||||
if (initrd_handle)
|
||||
initrd_header = &initrd_handle->header;
|
||||
if (idata->initrd)
|
||||
initrd_header = &idata->initrd->header;
|
||||
|
||||
printf("entering %s: os_header: %p initrd_header: %p oftree: %p\n",
|
||||
__FUNCTION__, os_header, initrd_header, oftree);
|
||||
printf("entering %s: os_header: %p initrd_header: %p oftree: %s\n",
|
||||
__FUNCTION__, os_header, initrd_header, idata->oftree);
|
||||
|
||||
if (os_header->ih_type == IH_TYPE_MULTI) {
|
||||
unsigned long *data = (unsigned long *)(os_handle->data);
|
||||
unsigned long *data = (unsigned long *)(idata->os->data);
|
||||
unsigned long len1 = 0, len2 = 0;
|
||||
|
||||
if (!*data) {
|
||||
|
@ -88,25 +89,25 @@ do_bootm_linux(struct image_handle *os_handle, struct image_handle *initrd_handl
|
|||
initrd_len = len1;
|
||||
}
|
||||
} else {
|
||||
os_data = os_handle->data;
|
||||
os_data = idata->os->data;
|
||||
printf("set os_data to %p\n", os_data);
|
||||
}
|
||||
|
||||
if (initrd_handle)
|
||||
initrd_data = initrd_handle->data;
|
||||
if (idata->initrd)
|
||||
initrd_data = idata->initrd->data;
|
||||
|
||||
#ifdef CONFIG_OF_FLAT_TREE
|
||||
if (oftree) {
|
||||
if (idata->oftree) {
|
||||
/* The oftree can be given either as an uboot image or as a
|
||||
* binary blob. First try to read it as an image.
|
||||
*/
|
||||
oftree_handle = map_image(oftree, 1);
|
||||
oftree_handle = map_image(idata->oftree, 1);
|
||||
if (oftree_handle) {
|
||||
of_data = oftree_handle->data;
|
||||
} else {
|
||||
of_data = read_file(oftree, 0);
|
||||
of_data = read_file(idata->oftree, 0);
|
||||
if (!of_data) {
|
||||
printf("could not read %s: %s\n", oftree, errno_str());
|
||||
printf("could not read %s: %s\n", idata->oftree, errno_str());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -201,7 +202,7 @@ do_bootm_linux(struct image_handle *os_handle, struct image_handle *initrd_handl
|
|||
|
||||
kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ntohl(os_header->ih_ep); /* FIXME */
|
||||
|
||||
if (relocate_image(os_handle, (void *)ntohl(os_header->ih_load)))
|
||||
if (relocate_image(idata->os, (void *)ntohl(os_header->ih_load)))
|
||||
return -1;
|
||||
|
||||
#if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500)
|
||||
|
@ -254,7 +255,6 @@ do_bootm_linux(struct image_handle *os_handle, struct image_handle *initrd_handl
|
|||
*/
|
||||
ft_setup(of_flat_tree, kbd, (long)initrd_data, initrd_end);
|
||||
ft_cpu_setup(of_flat_tree, kbd);
|
||||
ft_dump_blob(of_flat_tree);
|
||||
|
||||
(*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0);
|
||||
#endif
|
||||
|
@ -264,3 +264,15 @@ do_bootm_linux(struct image_handle *os_handle, struct image_handle *initrd_handl
|
|||
return -1;
|
||||
}
|
||||
|
||||
static struct image_handler handler = {
|
||||
.bootm = do_bootm_linux,
|
||||
.image_type = IH_OS_LINUX,
|
||||
};
|
||||
|
||||
static int ppclinux_register_image_handler(void)
|
||||
{
|
||||
return register_image_handler(&handler);
|
||||
}
|
||||
|
||||
late_initcall(ppclinux_register_image_handler);
|
||||
|
||||
|
|
457
commands/bootm.c
457
commands/bootm.c
|
@ -41,6 +41,7 @@
|
|||
#include <errno.h>
|
||||
#include <boot.h>
|
||||
#include <rtc.h>
|
||||
#include <init.h>
|
||||
|
||||
#ifdef CONFIG_SHOW_BOOT_PROGRESS
|
||||
# include <status_led.h>
|
||||
|
@ -314,41 +315,101 @@ void unmap_image(struct image_handle *handle)
|
|||
}
|
||||
EXPORT_SYMBOL(unmap_image);
|
||||
|
||||
#ifdef CONFIG_OF_FLAT_TREE
|
||||
#define OPT_OFTREE "o:"
|
||||
#else
|
||||
#define OPT_OFTREE
|
||||
#endif
|
||||
LIST_HEAD(handler_list);
|
||||
|
||||
int register_image_handler(struct image_handler *handler)
|
||||
{
|
||||
list_add_tail(&handler->list, &handler_list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int initrd_handler_parse_options(struct image_data *data, int opt,
|
||||
char *optarg)
|
||||
{
|
||||
switch(opt) {
|
||||
case 'r':
|
||||
printf("use initrd %s\n", optarg);
|
||||
data->initrd = map_image(optarg, data->verify);
|
||||
if (!data->initrd)
|
||||
return -1;
|
||||
return 0;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static struct image_handler initrd_handler = {
|
||||
.cmdline_options = "r:",
|
||||
.cmdline_parse = initrd_handler_parse_options,
|
||||
.help_string = " -r <initrd> specify an initrd image",
|
||||
};
|
||||
|
||||
static int initrd_register_image_handler(void)
|
||||
{
|
||||
return register_image_handler(&initrd_handler);
|
||||
}
|
||||
|
||||
late_initcall(initrd_register_image_handler);
|
||||
|
||||
static int handler_parse_options(struct image_data *data, int opt, char *optarg)
|
||||
{
|
||||
struct image_handler *handler;
|
||||
int ret;
|
||||
|
||||
list_for_each_entry(handler, &handler_list, list) {
|
||||
if (!handler->cmdline_parse)
|
||||
continue;
|
||||
|
||||
ret = handler->cmdline_parse(data, opt, optarg);
|
||||
if (ret > 0)
|
||||
continue;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int do_bootm (cmd_tbl_t *cmdtp, int argc, char *argv[])
|
||||
{
|
||||
ulong iflag;
|
||||
int verify = 1;
|
||||
int opt;
|
||||
char *initrd = NULL;
|
||||
image_header_t *os_header;
|
||||
image_header_t *initrd_header = NULL;
|
||||
struct image_handle *os_handle, *initrd_handle = NULL;
|
||||
#ifdef CONFIG_OF_FLAT_TREE
|
||||
char *oftree = NULL;
|
||||
#endif
|
||||
struct image_handler *handler;
|
||||
struct image_data data;
|
||||
char options[53]; /* worst case: whole alphabet with colons */
|
||||
|
||||
memset(&data, 0, sizeof(struct image_data));
|
||||
|
||||
getopt_reset();
|
||||
|
||||
while((opt = getopt(argc, argv, "r:ni" OPT_OFTREE)) > 0) {
|
||||
/* Collect options from registered handlers */
|
||||
strcpy(options, "nh");
|
||||
list_for_each_entry(handler, &handler_list, list) {
|
||||
if (handler->cmdline_options)
|
||||
strcat(options, handler->cmdline_options);
|
||||
}
|
||||
|
||||
while((opt = getopt(argc, argv, options)) > 0) {
|
||||
switch(opt) {
|
||||
case 'r':
|
||||
initrd = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
verify = 0;
|
||||
data.verify = 0;
|
||||
break;
|
||||
#ifdef CONFIG_OF_FLAT_TREE
|
||||
case 'o':
|
||||
oftree = optarg;
|
||||
break;
|
||||
#endif
|
||||
case 'h':
|
||||
printf("bootm advanced options:\n");
|
||||
|
||||
list_for_each_entry(handler, &handler_list, list) {
|
||||
if (handler->help_string)
|
||||
printf("%s\n", handler->help_string);
|
||||
}
|
||||
|
||||
return 0;
|
||||
default:
|
||||
if (!handler_parse_options(&data, opt, optarg))
|
||||
continue;
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -361,6 +422,7 @@ static int do_bootm (cmd_tbl_t *cmdtp, int argc, char *argv[])
|
|||
os_handle = map_image(argv[optind], verify);
|
||||
if (!os_handle)
|
||||
return 1;
|
||||
data.os = os_handle;
|
||||
|
||||
os_header = &os_handle->header;
|
||||
|
||||
|
@ -369,36 +431,6 @@ static int do_bootm (cmd_tbl_t *cmdtp, int argc, char *argv[])
|
|||
goto err_out;
|
||||
}
|
||||
|
||||
if (initrd) {
|
||||
initrd_handle = map_image(initrd, verify);
|
||||
if (!initrd_handle)
|
||||
goto err_out;
|
||||
initrd_header = &initrd_handle->header;
|
||||
}
|
||||
#if 0
|
||||
switch (os_header->ih_type) {
|
||||
case IH_TYPE_STANDALONE:
|
||||
name = "Standalone Application";
|
||||
/* A second argument overwrites the load address */
|
||||
if (argc > 2) {
|
||||
os_header->ih_load = htonl(simple_strtoul(argv[2], NULL, 16));
|
||||
}
|
||||
break;
|
||||
case IH_TYPE_KERNEL:
|
||||
name = "Kernel Image";
|
||||
break;
|
||||
case IH_TYPE_MULTI:
|
||||
name = "Multi-File Image";
|
||||
len = ntohl(len_ptr[0]);
|
||||
/* OS kernel is always the first image */
|
||||
data += 8; /* kernel_len + terminator */
|
||||
for (i=1; len_ptr[i]; ++i)
|
||||
data += 4;
|
||||
break;
|
||||
default: printf ("Wrong Image Type for %s command\n", cmdtp->name);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* We have reached the point of no return: we are going to
|
||||
* overwrite all exception vector code, so we cannot easily
|
||||
|
@ -409,62 +441,16 @@ static int do_bootm (cmd_tbl_t *cmdtp, int argc, char *argv[])
|
|||
|
||||
puts ("OK\n");
|
||||
|
||||
switch (os_header->ih_os) {
|
||||
default: /* handled by (original) Linux case */
|
||||
case IH_OS_LINUX:
|
||||
#ifdef CONFIG_SILENT_CONSOLE
|
||||
fixup_silent_linux();
|
||||
#endif
|
||||
#ifdef CONFIG_OF_FLAT_TREE
|
||||
do_bootm_linux(os_handle, initrd_handle, oftree);
|
||||
#else
|
||||
do_bootm_linux(os_handle, initrd_handle);
|
||||
#endif
|
||||
break;
|
||||
#ifdef CONFIG_NETBSD
|
||||
case IH_OS_NETBSD:
|
||||
do_bootm_netbsd (cmdtp, argc, argv,
|
||||
addr, len_ptr, verify);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LYNXKDI
|
||||
case IH_OS_LYNXOS:
|
||||
do_bootm_lynxkdi (cmdtp, argc, argv,
|
||||
addr, len_ptr, verify);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RTEMS
|
||||
case IH_OS_RTEMS:
|
||||
do_bootm_rtems (cmdtp, argc, argv,
|
||||
addr, len_ptr, verify);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_ELF)
|
||||
case IH_OS_VXWORKS:
|
||||
do_bootm_vxworks (cmdtp, argc, argv,
|
||||
addr, len_ptr, verify);
|
||||
break;
|
||||
case IH_OS_QNX:
|
||||
do_bootm_qnxelf (cmdtp, argc, argv,
|
||||
addr, len_ptr, verify);
|
||||
break;
|
||||
#endif /* CFG_CMD_ELF */
|
||||
#ifdef CONFIG_ARTOS
|
||||
case IH_OS_ARTOS:
|
||||
do_bootm_artos (cmdtp, argc, argv,
|
||||
addr, len_ptr, verify);
|
||||
break;
|
||||
#endif
|
||||
/* loop through the registered handlers */
|
||||
list_for_each_entry(handler, &handler_list, list) {
|
||||
if (handler->image_type == os_header->ih_os) {
|
||||
handler->bootm(&data);
|
||||
printf("handler returned!\n");
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
|
||||
SHOW_BOOT_PROGRESS (-9);
|
||||
#ifdef DEBUG
|
||||
puts ("\n## Control returned to monitor - resetting...\n");
|
||||
do_reset (cmdtp, argc, argv);
|
||||
#endif
|
||||
printf("no image handler found for image type %d\n", os_header->ih_os);
|
||||
|
||||
err_out:
|
||||
if (os_handle)
|
||||
|
@ -477,197 +463,15 @@ err_out:
|
|||
U_BOOT_CMD_START(bootm)
|
||||
.maxargs = CONFIG_MAXARGS,
|
||||
.cmd = do_bootm,
|
||||
.usage = "boot application image from memory",
|
||||
.usage = "boot application image",
|
||||
U_BOOT_CMD_HELP(
|
||||
"[addr [arg ...]]\n - boot application image stored in memory\n"
|
||||
"\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"
|
||||
"\t'arg' can be the address of an initrd image\n"
|
||||
#ifdef CONFIG_OF_FLAT_TREE
|
||||
"\tWhen booting a Linux kernel which requires a flat device-tree\n"
|
||||
"\ta third argument is required which is the address of the of the\n"
|
||||
"\tdevice-tree blob. To boot that kernel without an initrd image,\n"
|
||||
"\tuse a '-' for the second argument. If you do not pass a third\n"
|
||||
"\ta bd_info struct will be passed instead\n"
|
||||
#endif
|
||||
"Usage: bootm [OPTION] image\n"
|
||||
"Boot application image\n"
|
||||
" -n do not verify the images (speeds up boot process)\n"
|
||||
" -h show advanced options\n"
|
||||
)
|
||||
U_BOOT_CMD_END
|
||||
|
||||
#ifdef CONFIG_NETBSD
|
||||
static void
|
||||
do_bootm_netbsd (cmd_tbl_t *cmdtp,
|
||||
int argc, char *argv[],
|
||||
ulong addr,
|
||||
ulong *len_ptr,
|
||||
int verify)
|
||||
{
|
||||
image_header_t *hdr = &header;
|
||||
#if 0
|
||||
void (*loader)(bd_t *, image_header_t *, char *, char *);
|
||||
#endif
|
||||
image_header_t *img_addr;
|
||||
char *consdev;
|
||||
char *cmdline;
|
||||
|
||||
|
||||
/*
|
||||
* Booting a (NetBSD) kernel image
|
||||
*
|
||||
* This process is pretty similar to a standalone application:
|
||||
* The (first part of an multi-) image must be a stage-2 loader,
|
||||
* which in turn is responsible for loading & invoking the actual
|
||||
* kernel. The only differences are the parameters being passed:
|
||||
* besides the board info strucure, the loader expects a command
|
||||
* line, the name of the console device, and (optionally) the
|
||||
* address of the original image header.
|
||||
*/
|
||||
|
||||
img_addr = 0;
|
||||
if ((hdr->ih_type==IH_TYPE_MULTI) && (len_ptr[1]))
|
||||
img_addr = (image_header_t *) addr;
|
||||
|
||||
|
||||
consdev = "";
|
||||
#if defined (CONFIG_8xx_CONS_SMC1)
|
||||
consdev = "smc1";
|
||||
#elif defined (CONFIG_8xx_CONS_SMC2)
|
||||
consdev = "smc2";
|
||||
#elif defined (CONFIG_8xx_CONS_SCC2)
|
||||
consdev = "scc2";
|
||||
#elif defined (CONFIG_8xx_CONS_SCC3)
|
||||
consdev = "scc3";
|
||||
#endif
|
||||
|
||||
if (argc > 2) {
|
||||
ulong len;
|
||||
int i;
|
||||
|
||||
for (i=2, len=0 ; i<argc ; i+=1)
|
||||
len += strlen (argv[i]) + 1;
|
||||
cmdline = malloc (len);
|
||||
|
||||
for (i=2, len=0 ; i<argc ; i+=1) {
|
||||
if (i > 2)
|
||||
cmdline[len++] = ' ';
|
||||
strcpy (&cmdline[len], argv[i]);
|
||||
len += strlen (argv[i]);
|
||||
}
|
||||
} else if ((cmdline = (char *)getenv("bootargs")) == NULL) {
|
||||
cmdline = "";
|
||||
}
|
||||
#if 0
|
||||
loader = (void (*)(bd_t *, image_header_t *, char *, char *)) ntohl(hdr->ih_ep);
|
||||
|
||||
printf ("## Transferring control to NetBSD stage-2 loader (at address %08lx) ...\n",
|
||||
(ulong)loader);
|
||||
#endif
|
||||
SHOW_BOOT_PROGRESS (15);
|
||||
|
||||
/*
|
||||
* NetBSD Stage-2 Loader Parameters:
|
||||
* r3: ptr to board info data
|
||||
* r4: image address
|
||||
* r5: console device
|
||||
* r6: boot args string
|
||||
*/
|
||||
#if 0
|
||||
(*loader) (gd->bd, img_addr, consdev, cmdline);
|
||||
#else
|
||||
#warning NetBSD Support is broken
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARTOS
|
||||
|
||||
/* Function that returns a character from the environment */
|
||||
extern uchar (*env_get_char)(int);
|
||||
|
||||
static void
|
||||
do_bootm_artos (cmd_tbl_t *cmdtp,
|
||||
int argc, char *argv[],
|
||||
ulong addr,
|
||||
ulong *len_ptr,
|
||||
int verify)
|
||||
{
|
||||
ulong top;
|
||||
char *s, *cmdline;
|
||||
char **fwenv, **ss;
|
||||
int i, j, nxt, len, envno, envsz;
|
||||
bd_t *kbd;
|
||||
void (*entry)(bd_t *bd, char *cmdline, char **fwenv, ulong top);
|
||||
image_header_t *hdr = &header;
|
||||
|
||||
/*
|
||||
* Booting an ARTOS kernel image + application
|
||||
*/
|
||||
|
||||
/* this used to be the top of memory, but was wrong... */
|
||||
|
||||
/* get stack pointer */
|
||||
asm volatile ("mr %0,1" : "=r"(top) );
|
||||
|
||||
debug ("## Current stack ends at 0x%08lX ", top);
|
||||
|
||||
top -= 2048; /* just to be sure */
|
||||
if (top > CFG_BOOTMAPSZ)
|
||||
top = CFG_BOOTMAPSZ;
|
||||
top &= ~0xF;
|
||||
|
||||
debug ("=> set upper limit to 0x%08lX\n", top);
|
||||
|
||||
/* first check the artos specific boot args, then the linux args*/
|
||||
if ((s = getenv("abootargs")) == NULL && (s = getenv("bootargs")) == NULL)
|
||||
s = "";
|
||||
|
||||
/* get length of cmdline, and place it */
|
||||
len = strlen(s);
|
||||
top = (top - (len + 1)) & ~0xF;
|
||||
cmdline = (char *)top;
|
||||
debug ("## cmdline at 0x%08lX ", top);
|
||||
strcpy(cmdline, s);
|
||||
|
||||
/* copy bdinfo */
|
||||
top = (top - sizeof(bd_t)) & ~0xF;
|
||||
debug ("## bd at 0x%08lX ", top);
|
||||
kbd = (bd_t *)top;
|
||||
memcpy(kbd, gd->bd, sizeof(bd_t));
|
||||
|
||||
/* first find number of env entries, and their size */
|
||||
envno = 0;
|
||||
envsz = 0;
|
||||
for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) {
|
||||
for (nxt = i; env_get_char(nxt) != '\0'; ++nxt)
|
||||
;
|
||||
envno++;
|
||||
envsz += (nxt - i) + 1; /* plus trailing zero */
|
||||
}
|
||||
envno++; /* plus the terminating zero */
|
||||
debug ("## %u envvars total size %u ", envno, envsz);
|
||||
|
||||
top = (top - sizeof(char **)*envno) & ~0xF;
|
||||
fwenv = (char **)top;
|
||||
debug ("## fwenv at 0x%08lX ", top);
|
||||
|
||||
top = (top - envsz) & ~0xF;
|
||||
s = (char *)top;
|
||||
ss = fwenv;
|
||||
|
||||
/* now copy them */
|
||||
for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) {
|
||||
for (nxt = i; env_get_char(nxt) != '\0'; ++nxt)
|
||||
;
|
||||
*ss++ = s;
|
||||
for (j = i; j < nxt; ++j)
|
||||
*s++ = env_get_char(j);
|
||||
*s++ = '\0';
|
||||
}
|
||||
*ss++ = NULL; /* terminate */
|
||||
|
||||
entry = (void (*)(bd_t *, char *, char **, ulong))ntohl(hdr->ih_ep);
|
||||
(*entry)(kbd, cmdline, fwenv, top);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CMD_IMI
|
||||
static int do_iminfo ( cmd_tbl_t *cmdtp, int argc, char *argv[])
|
||||
{
|
||||
|
@ -779,81 +583,12 @@ print_image_hdr (image_header_t *hdr)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_BZLIB
|
||||
static void bz_internal_error(int errcode)
|
||||
void bz_internal_error(int errcode)
|
||||
{
|
||||
printf ("BZIP2 internal error %d\n", errcode);
|
||||
}
|
||||
#endif /* CONFIG_BZLIB */
|
||||
|
||||
#ifdef CONFIG_RTEMS
|
||||
static void
|
||||
do_bootm_rtems (cmd_tbl_t *cmdtp, int argc, char *argv[],
|
||||
ulong addr, ulong *len_ptr, int verify)
|
||||
{
|
||||
#if 0
|
||||
image_header_t *hdr = &header;
|
||||
void (*entry_point)(bd_t *);
|
||||
|
||||
entry_point = (void (*)(bd_t *)) ntohl(hdr->ih_ep);
|
||||
|
||||
printf ("## Transferring control to RTEMS (at address %08lx) ...\n",
|
||||
(ulong)entry_point);
|
||||
#endif
|
||||
SHOW_BOOT_PROGRESS (15);
|
||||
|
||||
/*
|
||||
* RTEMS Parameters:
|
||||
* r3: ptr to board info data
|
||||
*/
|
||||
#if 0
|
||||
(*entry_point ) ( gd->bd );
|
||||
#else
|
||||
#warning RTEMS support is broken
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_ELF)
|
||||
static void
|
||||
do_bootm_vxworks (cmd_tbl_t *cmdtp, int argc, char *argv[],
|
||||
ulong addr, ulong *len_ptr, int verify)
|
||||
{
|
||||
image_header_t *hdr = &header;
|
||||
char str[80];
|
||||
|
||||
sprintf(str, "%x", ntohl(hdr->ih_ep)); /* write entry-point into string */
|
||||
setenv("loadaddr", str);
|
||||
do_bootvx(cmdtp, 0, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
do_bootm_qnxelf (cmd_tbl_t *cmdtp, int argc, char *argv[],
|
||||
ulong addr, ulong *len_ptr, int verify)
|
||||
{
|
||||
image_header_t *hdr = &header;
|
||||
char *local_args[2];
|
||||
char str[16];
|
||||
|
||||
sprintf(str, "%x", ntohl(hdr->ih_ep)); /* write entry-point into string */
|
||||
local_args[0] = argv[0];
|
||||
local_args[1] = str; /* and provide it via the arguments */
|
||||
do_bootelf(cmdtp, 2, local_args);
|
||||
}
|
||||
#endif /* CFG_CMD_ELF */
|
||||
|
||||
#ifdef CONFIG_LYNXKDI
|
||||
static void
|
||||
do_bootm_lynxkdi (cmd_tbl_t *cmdtp,
|
||||
int argc, char *argv[],
|
||||
ulong addr,
|
||||
ulong *len_ptr,
|
||||
int verify)
|
||||
{
|
||||
lynxkdi_boot( &header );
|
||||
}
|
||||
|
||||
#endif /* CONFIG_LYNXKDI */
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Boot support for Linux
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <boot.h>
|
||||
#include <init.h>
|
||||
#include <malloc.h>
|
||||
#include <environment.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
@ -589,3 +591,29 @@ void ft_setup(void *blob, bd_t * bd, ulong initrd_start, ulong initrd_end)
|
|||
#endif
|
||||
}
|
||||
|
||||
static int oftree_handler_cmdline_parse(struct image_data *data, int opt,
|
||||
char *optarg)
|
||||
{
|
||||
switch(opt) {
|
||||
case 'o':
|
||||
printf("using oftree %s\n", optarg);
|
||||
data->oftree = optarg;
|
||||
return 0;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static struct image_handler of_handler = {
|
||||
.cmdline_options = "o:",
|
||||
.cmdline_parse = oftree_handler_cmdline_parse,
|
||||
.help_string = " -o <oftree> use oftree",
|
||||
};
|
||||
|
||||
static int oftree_register_image_handler(void)
|
||||
{
|
||||
return register_image_handler(&of_handler);
|
||||
}
|
||||
|
||||
late_initcall(oftree_register_image_handler);
|
||||
|
||||
|
|
|
@ -2,13 +2,27 @@
|
|||
#define __BOOT_H
|
||||
|
||||
#include <image.h>
|
||||
#include <list.h>
|
||||
|
||||
#ifdef CONFIG_OF_FLAT_TREE
|
||||
extern int do_bootm_linux(struct image_handle *os, struct image_handle *initrd,
|
||||
const char *oftree);
|
||||
#else
|
||||
extern int do_bootm_linux(struct image_handle *os, struct image_handle *initrd);
|
||||
#endif
|
||||
struct image_data {
|
||||
struct image_handle *os;
|
||||
struct image_handle *initrd;
|
||||
const char *oftree;
|
||||
int verify;
|
||||
};
|
||||
|
||||
struct image_handler {
|
||||
struct list_head list;
|
||||
|
||||
char *cmdline_options;
|
||||
int (*cmdline_parse)(struct image_data *data, int opt, char *optarg);
|
||||
char *help_string;
|
||||
|
||||
int image_type;
|
||||
int (*bootm)(struct image_data *data);
|
||||
};
|
||||
|
||||
int register_image_handler(struct image_handler *handle);
|
||||
|
||||
#endif /* __BOOT_H */
|
||||
|
||||
|
|
Loading…
Reference in New Issue