summaryrefslogtreecommitdiff
path: root/common/cmd_bootm.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/cmd_bootm.c')
-rw-r--r--common/cmd_bootm.c230
1 files changed, 62 insertions, 168 deletions
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index 7438469..05130b6 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -36,6 +36,7 @@
#include <lmb.h>
#include <linux/ctype.h>
#include <asm/byteorder.h>
+#include <asm/io.h>
#include <linux/compiler.h>
#if defined(CONFIG_CMD_USB)
@@ -92,12 +93,7 @@ static int do_imls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
static void fixup_silent_linux(void);
#endif
-static image_header_t *image_get_kernel(ulong img_addr, int verify);
-#if defined(CONFIG_FIT)
-static int fit_check_kernel(const void *fit, int os_noffset, int verify);
-#endif
-
-static void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
+static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[], bootm_headers_t *images,
ulong *os_data, ulong *os_len);
@@ -203,8 +199,8 @@ static inline void boot_start_lmb(bootm_headers_t *images) { }
static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
- void *os_hdr;
- int ret;
+ const void *os_hdr;
+ int ret;
memset((void *)&images, 0, sizeof(images));
images.verify = getenv_yesno("verify");
@@ -275,7 +271,7 @@ static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
#if defined(CONFIG_FIT)
} else if (images.fit_uname_os) {
ret = fit_image_get_entry(images.fit_hdr_os,
- images.fit_noffset_os, &images.ep);
+ images.fit_noffset_os, &images.ep);
if (ret) {
puts("Can't get entry point property!\n");
return 1;
@@ -305,7 +301,7 @@ static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
#if defined(CONFIG_OF_LIBFDT)
/* find flattened device tree */
- ret = boot_get_fdt(flag, argc, argv, &images,
+ ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images,
&images.ft_addr, &images.ft_len);
if (ret) {
puts("Could not find a valid device tree\n");
@@ -335,12 +331,15 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
ulong image_len = os.image_len;
__maybe_unused uint unc_len = CONFIG_SYS_BOOTM_LEN;
int no_overlap = 0;
+ void *load_buf, *image_buf;
#if defined(CONFIG_LZMA) || defined(CONFIG_LZO)
int ret;
#endif /* defined(CONFIG_LZMA) || defined(CONFIG_LZO) */
const char *type_name = genimg_get_type_name(os.type);
+ load_buf = map_sysmem(load, image_len);
+ image_buf = map_sysmem(image_start, image_len);
switch (comp) {
case IH_COMP_NONE:
if (load == blob_start || load == image_start) {
@@ -348,8 +347,7 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
no_overlap = 1;
} else {
printf(" Loading %s ... ", type_name);
- memmove_wd((void *)load, (void *)image_start,
- image_len, CHUNKSZ);
+ memmove_wd(load_buf, image_buf, image_len, CHUNKSZ);
}
*load_end = load + image_len;
puts("OK\n");
@@ -357,8 +355,7 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
#ifdef CONFIG_GZIP
case IH_COMP_GZIP:
printf(" Uncompressing %s ... ", type_name);
- if (gunzip((void *)load, unc_len,
- (uchar *)image_start, &image_len) != 0) {
+ if (gunzip(load_buf, unc_len, image_buf, &image_len) != 0) {
puts("GUNZIP: uncompress, out-of-mem or overwrite "
"error - must RESET board to recover\n");
if (boot_progress)
@@ -377,9 +374,9 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
* use slower decompression algorithm which requires
* at most 2300 KB of memory.
*/
- int i = BZ2_bzBuffToBuffDecompress((char *)load,
- &unc_len, (char *)image_start, image_len,
- CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
+ int i = BZ2_bzBuffToBuffDecompress(load_buf, &unc_len,
+ image_buf, image_len,
+ CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
if (i != BZ_OK) {
printf("BUNZIP2: uncompress or overwrite error %d "
"- must RESET board to recover\n", i);
@@ -396,9 +393,8 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
SizeT lzma_len = unc_len;
printf(" Uncompressing %s ... ", type_name);
- ret = lzmaBuffToBuffDecompress(
- (unsigned char *)load, &lzma_len,
- (unsigned char *)image_start, image_len);
+ ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len,
+ image_buf, image_len);
unc_len = lzma_len;
if (ret != SZ_OK) {
printf("LZMA: uncompress or overwrite error %d "
@@ -414,9 +410,8 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
case IH_COMP_LZO:
printf(" Uncompressing %s ... ", type_name);
- ret = lzop_decompress((const unsigned char *)image_start,
- image_len, (unsigned char *)load,
- &unc_len);
+ ret = lzop_decompress(image_buf, image_len, load_buf,
+ &unc_len);
if (ret != LZO_E_OK) {
printf("LZO: uncompress or overwrite error %d "
"- must RESET board to recover\n", ret);
@@ -796,54 +791,6 @@ static image_header_t *image_get_kernel(ulong img_addr, int verify)
}
/**
- * fit_check_kernel - verify FIT format kernel subimage
- * @fit_hdr: pointer to the FIT image header
- * os_noffset: kernel subimage node offset within FIT image
- * @verify: data CRC verification flag
- *
- * fit_check_kernel() verifies integrity of the kernel subimage and from
- * specified FIT image.
- *
- * returns:
- * 1, on success
- * 0, on failure
- */
-#if defined(CONFIG_FIT)
-static int fit_check_kernel(const void *fit, int os_noffset, int verify)
-{
- fit_image_print(fit, os_noffset, " ");
-
- if (verify) {
- puts(" Verifying Hash Integrity ... ");
- if (!fit_image_check_hashes(fit, os_noffset)) {
- puts("Bad Data Hash\n");
- bootstage_error(BOOTSTAGE_ID_FIT_CHECK_HASH);
- return 0;
- }
- puts("OK\n");
- }
- bootstage_mark(BOOTSTAGE_ID_FIT_CHECK_ARCH);
-
- if (!fit_image_check_target_arch(fit, os_noffset)) {
- puts("Unsupported Architecture\n");
- bootstage_error(BOOTSTAGE_ID_FIT_CHECK_ARCH);
- return 0;
- }
-
- bootstage_mark(BOOTSTAGE_ID_FIT_CHECK_KERNEL);
- if (!fit_image_check_type(fit, os_noffset, IH_TYPE_KERNEL) &&
- !fit_image_check_type(fit, os_noffset, IH_TYPE_KERNEL_NOLOAD)) {
- puts("Not a kernel image\n");
- bootstage_error(BOOTSTAGE_ID_FIT_CHECK_KERNEL);
- return 0;
- }
-
- bootstage_mark(BOOTSTAGE_ID_FIT_CHECKED);
- return 1;
-}
-#endif /* CONFIG_FIT */
-
-/**
* boot_get_kernel - find kernel image
* @os_data: pointer to a ulong variable, will hold os data start address
* @os_len: pointer to a ulong variable, will hold os data length
@@ -855,19 +802,16 @@ static int fit_check_kernel(const void *fit, int os_noffset, int verify)
* pointer to image header if valid image was found, plus kernel start
* address and length, otherwise NULL
*/
-static void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
+static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[], bootm_headers_t *images, ulong *os_data,
ulong *os_len)
{
image_header_t *hdr;
ulong img_addr;
+ const void *buf;
#if defined(CONFIG_FIT)
- void *fit_hdr;
const char *fit_uname_config = NULL;
const char *fit_uname_kernel = NULL;
- const void *data;
- size_t len;
- int cfg_noffset;
int os_noffset;
#endif
@@ -898,7 +842,8 @@ static void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
/* check image type, for FIT images get FIT kernel node */
*os_data = *os_len = 0;
- switch (genimg_get_format((void *)img_addr)) {
+ buf = map_sysmem(img_addr, 0);
+ switch (genimg_get_format(buf)) {
case IMAGE_FORMAT_LEGACY:
printf("## Booting kernel from Legacy Image at %08lx ...\n",
img_addr);
@@ -943,84 +888,16 @@ static void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
break;
#if defined(CONFIG_FIT)
case IMAGE_FORMAT_FIT:
- fit_hdr = (void *)img_addr;
- printf("## Booting kernel from FIT Image at %08lx ...\n",
- img_addr);
-
- if (!fit_check_format(fit_hdr)) {
- puts("Bad FIT kernel image format!\n");
- bootstage_error(BOOTSTAGE_ID_FIT_FORMAT);
+ os_noffset = fit_image_load(images, FIT_KERNEL_PROP,
+ img_addr,
+ &fit_uname_kernel, fit_uname_config,
+ IH_ARCH_DEFAULT, IH_TYPE_KERNEL,
+ BOOTSTAGE_ID_FIT_KERNEL_START,
+ FIT_LOAD_IGNORED, os_data, os_len);
+ if (os_noffset < 0)
return NULL;
- }
- bootstage_mark(BOOTSTAGE_ID_FIT_FORMAT);
- if (!fit_uname_kernel) {
- /*
- * no kernel image node unit name, try to get config
- * node first. If config unit node name is NULL
- * fit_conf_get_node() will try to find default config
- * node
- */
- bootstage_mark(BOOTSTAGE_ID_FIT_NO_UNIT_NAME);
-#ifdef CONFIG_FIT_BEST_MATCH
- if (fit_uname_config)
- cfg_noffset =
- fit_conf_get_node(fit_hdr,
- fit_uname_config);
- else
- cfg_noffset =
- fit_conf_find_compat(fit_hdr,
- gd->fdt_blob);
-#else
- cfg_noffset = fit_conf_get_node(fit_hdr,
- fit_uname_config);
-#endif
- if (cfg_noffset < 0) {
- bootstage_error(BOOTSTAGE_ID_FIT_NO_UNIT_NAME);
- return NULL;
- }
- /* save configuration uname provided in the first
- * bootm argument
- */
- images->fit_uname_cfg = fdt_get_name(fit_hdr,
- cfg_noffset,
- NULL);
- printf(" Using '%s' configuration\n",
- images->fit_uname_cfg);
- bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG);
-
- os_noffset = fit_conf_get_kernel_node(fit_hdr,
- cfg_noffset);
- fit_uname_kernel = fit_get_name(fit_hdr, os_noffset,
- NULL);
- } else {
- /* get kernel component image node offset */
- bootstage_mark(BOOTSTAGE_ID_FIT_UNIT_NAME);
- os_noffset = fit_image_get_node(fit_hdr,
- fit_uname_kernel);
- }
- if (os_noffset < 0) {
- bootstage_error(BOOTSTAGE_ID_FIT_CONFIG);
- return NULL;
- }
-
- printf(" Trying '%s' kernel subimage\n", fit_uname_kernel);
-
- bootstage_mark(BOOTSTAGE_ID_FIT_CHECK_SUBIMAGE);
- if (!fit_check_kernel(fit_hdr, os_noffset, images->verify))
- return NULL;
-
- /* get kernel image data address and length */
- if (fit_image_get_data(fit_hdr, os_noffset, &data, &len)) {
- puts("Could not find kernel subimage data!\n");
- bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO_ERR);
- return NULL;
- }
- bootstage_mark(BOOTSTAGE_ID_FIT_KERNEL_INFO);
-
- *os_len = len;
- *os_data = (ulong)data;
- images->fit_hdr_os = fit_hdr;
+ images->fit_hdr_os = map_sysmem(img_addr, 0);
images->fit_uname_os = fit_uname_kernel;
images->fit_noffset_os = os_noffset;
break;
@@ -1034,7 +911,7 @@ static void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
debug(" kernel data at 0x%08lx, len = 0x%08lx (%ld)\n",
*os_data, *os_len, *os_len);
- return (void *)img_addr;
+ return buf;
}
#ifdef CONFIG_SYS_LONGHELP
@@ -1169,7 +1046,7 @@ static int image_info(ulong addr)
fit_print_contents(hdr);
- if (!fit_all_image_check_hashes(hdr)) {
+ if (!fit_all_image_verify(hdr)) {
puts("Bad hash in FIT image!\n");
return 1;
}
@@ -1420,9 +1297,14 @@ U_BOOT_CMD(
/* helper routines */
/*******************************************************************/
#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
+
+#define CONSOLE_ARG "console="
+#define CONSOLE_ARG_LEN (sizeof(CONSOLE_ARG) - 1)
+
static void fixup_silent_linux(void)
{
- char buf[256], *start, *end;
+ char *buf;
+ const char *env_val;
char *cmdline = getenv("bootargs");
/* Only fix cmdline when requested */
@@ -1430,25 +1312,37 @@ static void fixup_silent_linux(void)
return;
debug("before silent fix-up: %s\n", cmdline);
- if (cmdline) {
- start = strstr(cmdline, "console=");
+ if (cmdline && (cmdline[0] != '\0')) {
+ char *start = strstr(cmdline, CONSOLE_ARG);
+
+ /* Allocate space for maximum possible new command line */
+ buf = malloc(strlen(cmdline) + 1 + CONSOLE_ARG_LEN + 1);
+ if (!buf) {
+ debug("%s: out of memory\n", __func__);
+ return;
+ }
+
if (start) {
- end = strchr(start, ' ');
- strncpy(buf, cmdline, (start - cmdline + 8));
+ char *end = strchr(start, ' ');
+ int num_start_bytes = start - cmdline + CONSOLE_ARG_LEN;
+
+ strncpy(buf, cmdline, num_start_bytes);
if (end)
- strcpy(buf + (start - cmdline + 8), end);
+ strcpy(buf + num_start_bytes, end);
else
- buf[start - cmdline + 8] = '\0';
+ buf[num_start_bytes] = '\0';
} else {
- strcpy(buf, cmdline);
- strcat(buf, " console=");
+ sprintf(buf, "%s %s", cmdline, CONSOLE_ARG);
}
+ env_val = buf;
} else {
- strcpy(buf, "console=");
+ buf = NULL;
+ env_val = CONSOLE_ARG;
}
- setenv("bootargs", buf);
- debug("after silent fix-up: %s\n", buf);
+ setenv("bootargs", env_val);
+ debug("after silent fix-up: %s\n", env_val);
+ free(buf);
}
#endif /* CONFIG_SILENT_CONSOLE */
@@ -1800,7 +1694,7 @@ static int bootz_start(cmd_tbl_t *cmdtp, int flag, int argc,
#if defined(CONFIG_OF_LIBFDT)
/* find flattened device tree */
- ret = boot_get_fdt(flag, argc, argv, images,
+ ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, images,
&images->ft_addr, &images->ft_len);
if (ret) {
puts("Could not find a valid device tree\n");