summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/lib/bootm.c24
-rw-r--r--arch/blackfin/lib/blackfin_linux.c6
-rw-r--r--arch/nios2/lib/bootm.c6
-rw-r--r--arch/ppc/lib/ppclinux.c6
-rw-r--r--common/bootm.c49
-rw-r--r--include/boot.h2
6 files changed, 61 insertions, 32 deletions
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
index c0e4e15ea6..7401f2f05d 100644
--- a/arch/arm/lib/bootm.c
+++ b/arch/arm/lib/bootm.c
@@ -28,32 +28,22 @@ static int __do_bootm_linux(struct image_data *data, int swap)
unsigned long initrd_start = 0, initrd_size = 0, initrd_end = 0;
struct memory_bank *bank;
unsigned long load_address;
+ int ret;
- if (data->os_res) {
- load_address = data->os_res->start;
- } else if (data->os_address != UIMAGE_INVALID_ADDRESS) {
- load_address = data->os_address;
- } else {
+ if (data->os_address == UIMAGE_INVALID_ADDRESS) {
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);
+ } else {
+ load_address = data->os_address;
}
- 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;
- }
-
- if (!data->os_res) {
- data->os_res = file_to_sdram(data->os_file, load_address);
- if (!data->os_res)
- return -ENOMEM;
- }
+ ret = bootm_load_os(data, load_address);
+ if (ret)
+ return ret;
kernel = data->os_res->start + data->os_entry;
diff --git a/arch/blackfin/lib/blackfin_linux.c b/arch/blackfin/lib/blackfin_linux.c
index bb3c7745ea..2561a7e152 100644
--- a/arch/blackfin/lib/blackfin_linux.c
+++ b/arch/blackfin/lib/blackfin_linux.c
@@ -41,9 +41,11 @@ static int do_bootm_linux(struct image_data *idata)
int (*appl)(char *cmdline);
const char *cmdline = linux_bootargs_get();
char *cmdlinedest = (char *) CMD_LINE_ADDR;
+ int ret;
- if (!idata->os_res)
- return -EINVAL;
+ ret = bootm_load_os(idata, idata->os_address);
+ if (ret)
+ return ret;
appl = (void *)(idata->os_address + idata->os_entry);
printf("Starting Kernel at 0x%p\n", appl);
diff --git a/arch/nios2/lib/bootm.c b/arch/nios2/lib/bootm.c
index cc96290b8d..77da119bde 100644
--- a/arch/nios2/lib/bootm.c
+++ b/arch/nios2/lib/bootm.c
@@ -36,9 +36,11 @@ static int do_bootm_linux(struct image_data *idata)
{
void (*kernel)(int, int, int, const char *);
const char *commandline = linux_bootargs_get();
+ int ret;
- if (!idata->os_res)
- return -EINVAL;
+ ret = bootm_load_os(idata, idata->os_address);
+ if (ret)
+ return ret;
kernel = (void *)(idata->os_address + idata->os_entry);
diff --git a/arch/ppc/lib/ppclinux.c b/arch/ppc/lib/ppclinux.c
index 7c30ac3386..e25efecd43 100644
--- a/arch/ppc/lib/ppclinux.c
+++ b/arch/ppc/lib/ppclinux.c
@@ -47,9 +47,11 @@ static int do_bootm_linux(struct image_data *data)
{
void (*kernel)(void *, void *, unsigned long,
unsigned long, unsigned long);
+ int ret;
- if (!data->os_res)
- return -EINVAL;
+ ret = bootm_load_os(data, data->os_address);
+ if (ret)
+ return ret;
data->oftree = of_get_fixed_tree(data->of_root_node);
if (!data->oftree) {
diff --git a/common/bootm.c b/common/bootm.c
index 2da6e59129..5ad10d9a02 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -45,6 +45,46 @@ static struct image_handler *bootm_find_handler(enum filetype filetype,
return NULL;
}
+/*
+ * bootm_load_os() - load OS to RAM
+ *
+ * @data: image data context
+ * @load_address: The address where the OS should be loaded to
+ *
+ * This loads the OS to a RAM location. load_address must be a valid
+ * address. If the image_data doesn't have a OS specified it's considered
+ * an error.
+ *
+ * Return: 0 on success, negative error code otherwise
+ */
+int bootm_load_os(struct image_data *data, unsigned long load_address)
+{
+ if (data->os_res)
+ return 0;
+
+ if (load_address == UIMAGE_INVALID_ADDRESS)
+ return -EINVAL;
+
+ if (data->os) {
+ data->os_res = uimage_load_to_sdram(data->os,
+ data->os_num, load_address);
+ if (!data->os_res)
+ return -ENOMEM;
+
+ return 0;
+ }
+
+ if (data->os_file) {
+ data->os_res = file_to_sdram(data->os_file, load_address);
+ if (!data->os_res)
+ return -ENOMEM;
+
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
static int bootm_open_os_uimage(struct image_data *data)
{
int ret;
@@ -75,15 +115,6 @@ static int bootm_open_os_uimage(struct image_data *data)
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) {
- uimage_close(data->os);
- return -ENOMEM;
- }
- }
-
return 0;
}
diff --git a/include/boot.h b/include/boot.h
index 56f6c359b9..61ab5d0a4a 100644
--- a/include/boot.h
+++ b/include/boot.h
@@ -108,6 +108,8 @@ static inline int linux_bootargs_overwrite(const char *bootargs)
}
#endif
+int bootm_load_os(struct image_data *data, unsigned long load_address);
+
#define UIMAGE_SOME_ADDRESS (UIMAGE_INVALID_ADDRESS - 1)
#endif /* __BOOT_H */