summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Kconfig162
-rw-r--r--common/autoboot.c121
-rw-r--r--common/board_r.c4
-rw-r--r--common/bootm.c150
-rw-r--r--common/edid.c26
-rw-r--r--common/image-fit.c143
-rw-r--r--common/image.c111
-rw-r--r--common/main.c5
8 files changed, 478 insertions, 244 deletions
diff --git a/common/Kconfig b/common/Kconfig
index b556b59e9f0..28d5e9a0ccf 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -125,6 +125,168 @@ config BOOTSTAGE_STASH_SIZE
This should be large enough to hold the bootstage stash. A value of
4096 (4KiB) is normally plenty.
+config SHOW_BOOT_PROGRESS
+ bool "Show boot progress in a board-specific manner"
+ help
+ Defining this option allows to add some board-specific code (calling
+ a user-provided function show_boot_progress(int) that enables you to
+ show the system's boot progress on some display (for example, some
+ LEDs) on your board. At the moment, the following checkpoints are
+ implemented:
+
+ Legacy uImage format:
+
+ Arg Where When
+ 1 common/cmd_bootm.c before attempting to boot an image
+ -1 common/cmd_bootm.c Image header has bad magic number
+ 2 common/cmd_bootm.c Image header has correct magic number
+ -2 common/cmd_bootm.c Image header has bad checksum
+ 3 common/cmd_bootm.c Image header has correct checksum
+ -3 common/cmd_bootm.c Image data has bad checksum
+ 4 common/cmd_bootm.c Image data has correct checksum
+ -4 common/cmd_bootm.c Image is for unsupported architecture
+ 5 common/cmd_bootm.c Architecture check OK
+ -5 common/cmd_bootm.c Wrong Image Type (not kernel, multi)
+ 6 common/cmd_bootm.c Image Type check OK
+ -6 common/cmd_bootm.c gunzip uncompression error
+ -7 common/cmd_bootm.c Unimplemented compression type
+ 7 common/cmd_bootm.c Uncompression OK
+ 8 common/cmd_bootm.c No uncompress/copy overwrite error
+ -9 common/cmd_bootm.c Unsupported OS (not Linux, BSD, VxWorks, QNX)
+
+ 9 common/image.c Start initial ramdisk verification
+ -10 common/image.c Ramdisk header has bad magic number
+ -11 common/image.c Ramdisk header has bad checksum
+ 10 common/image.c Ramdisk header is OK
+ -12 common/image.c Ramdisk data has bad checksum
+ 11 common/image.c Ramdisk data has correct checksum
+ 12 common/image.c Ramdisk verification complete, start loading
+ -13 common/image.c Wrong Image Type (not PPC Linux ramdisk)
+ 13 common/image.c Start multifile image verification
+ 14 common/image.c No initial ramdisk, no multifile, continue.
+
+ 15 arch/<arch>/lib/bootm.c All preparation done, transferring control to OS
+
+ -30 arch/powerpc/lib/board.c Fatal error, hang the system
+ -31 post/post.c POST test failed, detected by post_output_backlog()
+ -32 post/post.c POST test failed, detected by post_run_single()
+
+ 34 common/cmd_doc.c before loading a Image from a DOC device
+ -35 common/cmd_doc.c Bad usage of "doc" command
+ 35 common/cmd_doc.c correct usage of "doc" command
+ -36 common/cmd_doc.c No boot device
+ 36 common/cmd_doc.c correct boot device
+ -37 common/cmd_doc.c Unknown Chip ID on boot device
+ 37 common/cmd_doc.c correct chip ID found, device available
+ -38 common/cmd_doc.c Read Error on boot device
+ 38 common/cmd_doc.c reading Image header from DOC device OK
+ -39 common/cmd_doc.c Image header has bad magic number
+ 39 common/cmd_doc.c Image header has correct magic number
+ -40 common/cmd_doc.c Error reading Image from DOC device
+ 40 common/cmd_doc.c Image header has correct magic number
+ 41 common/cmd_ide.c before loading a Image from a IDE device
+ -42 common/cmd_ide.c Bad usage of "ide" command
+ 42 common/cmd_ide.c correct usage of "ide" command
+ -43 common/cmd_ide.c No boot device
+ 43 common/cmd_ide.c boot device found
+ -44 common/cmd_ide.c Device not available
+ 44 common/cmd_ide.c Device available
+ -45 common/cmd_ide.c wrong partition selected
+ 45 common/cmd_ide.c partition selected
+ -46 common/cmd_ide.c Unknown partition table
+ 46 common/cmd_ide.c valid partition table found
+ -47 common/cmd_ide.c Invalid partition type
+ 47 common/cmd_ide.c correct partition type
+ -48 common/cmd_ide.c Error reading Image Header on boot device
+ 48 common/cmd_ide.c reading Image Header from IDE device OK
+ -49 common/cmd_ide.c Image header has bad magic number
+ 49 common/cmd_ide.c Image header has correct magic number
+ -50 common/cmd_ide.c Image header has bad checksum
+ 50 common/cmd_ide.c Image header has correct checksum
+ -51 common/cmd_ide.c Error reading Image from IDE device
+ 51 common/cmd_ide.c reading Image from IDE device OK
+ 52 common/cmd_nand.c before loading a Image from a NAND device
+ -53 common/cmd_nand.c Bad usage of "nand" command
+ 53 common/cmd_nand.c correct usage of "nand" command
+ -54 common/cmd_nand.c No boot device
+ 54 common/cmd_nand.c boot device found
+ -55 common/cmd_nand.c Unknown Chip ID on boot device
+ 55 common/cmd_nand.c correct chip ID found, device available
+ -56 common/cmd_nand.c Error reading Image Header on boot device
+ 56 common/cmd_nand.c reading Image Header from NAND device OK
+ -57 common/cmd_nand.c Image header has bad magic number
+ 57 common/cmd_nand.c Image header has correct magic number
+ -58 common/cmd_nand.c Error reading Image from NAND device
+ 58 common/cmd_nand.c reading Image from NAND device OK
+
+ -60 common/env_common.c Environment has a bad CRC, using default
+
+ 64 net/eth.c starting with Ethernet configuration.
+ -64 net/eth.c no Ethernet found.
+ 65 net/eth.c Ethernet found.
+
+ -80 common/cmd_net.c usage wrong
+ 80 common/cmd_net.c before calling net_loop()
+ -81 common/cmd_net.c some error in net_loop() occurred
+ 81 common/cmd_net.c net_loop() back without error
+ -82 common/cmd_net.c size == 0 (File with size 0 loaded)
+ 82 common/cmd_net.c trying automatic boot
+ 83 common/cmd_net.c running "source" command
+ -83 common/cmd_net.c some error in automatic boot or "source" command
+ 84 common/cmd_net.c end without errors
+
+ FIT uImage format:
+
+ Arg Where When
+ 100 common/cmd_bootm.c Kernel FIT Image has correct format
+ -100 common/cmd_bootm.c Kernel FIT Image has incorrect format
+ 101 common/cmd_bootm.c No Kernel subimage unit name, using configuration
+ -101 common/cmd_bootm.c Can't get configuration for kernel subimage
+ 102 common/cmd_bootm.c Kernel unit name specified
+ -103 common/cmd_bootm.c Can't get kernel subimage node offset
+ 103 common/cmd_bootm.c Found configuration node
+ 104 common/cmd_bootm.c Got kernel subimage node offset
+ -104 common/cmd_bootm.c Kernel subimage hash verification failed
+ 105 common/cmd_bootm.c Kernel subimage hash verification OK
+ -105 common/cmd_bootm.c Kernel subimage is for unsupported architecture
+ 106 common/cmd_bootm.c Architecture check OK
+ -106 common/cmd_bootm.c Kernel subimage has wrong type
+ 107 common/cmd_bootm.c Kernel subimage type OK
+ -107 common/cmd_bootm.c Can't get kernel subimage data/size
+ 108 common/cmd_bootm.c Got kernel subimage data/size
+ -108 common/cmd_bootm.c Wrong image type (not legacy, FIT)
+ -109 common/cmd_bootm.c Can't get kernel subimage type
+ -110 common/cmd_bootm.c Can't get kernel subimage comp
+ -111 common/cmd_bootm.c Can't get kernel subimage os
+ -112 common/cmd_bootm.c Can't get kernel subimage load address
+ -113 common/cmd_bootm.c Image uncompress/copy overwrite error
+
+ 120 common/image.c Start initial ramdisk verification
+ -120 common/image.c Ramdisk FIT image has incorrect format
+ 121 common/image.c Ramdisk FIT image has correct format
+ 122 common/image.c No ramdisk subimage unit name, using configuration
+ -122 common/image.c Can't get configuration for ramdisk subimage
+ 123 common/image.c Ramdisk unit name specified
+ -124 common/image.c Can't get ramdisk subimage node offset
+ 125 common/image.c Got ramdisk subimage node offset
+ -125 common/image.c Ramdisk subimage hash verification failed
+ 126 common/image.c Ramdisk subimage hash verification OK
+ -126 common/image.c Ramdisk subimage for unsupported architecture
+ 127 common/image.c Architecture check OK
+ -127 common/image.c Can't get ramdisk subimage data/size
+ 128 common/image.c Got ramdisk subimage data/size
+ 129 common/image.c Can't get ramdisk load address
+ -129 common/image.c Got ramdisk load address
+
+ -130 common/cmd_doc.c Incorrect FIT image format
+ 131 common/cmd_doc.c FIT image format OK
+
+ -140 common/cmd_ide.c Incorrect FIT image format
+ 141 common/cmd_ide.c FIT image format OK
+
+ -150 common/cmd_nand.c Incorrect FIT image format
+ 151 common/cmd_nand.c FIT image format OK
+
endmenu
menu "Boot media"
diff --git a/common/autoboot.c b/common/autoboot.c
index 94133eaeda7..42fbd7614a8 100644
--- a/common/autoboot.c
+++ b/common/autoboot.c
@@ -10,6 +10,7 @@
#include <cli.h>
#include <console.h>
#include <fdtdec.h>
+#include <hash.h>
#include <menu.h>
#include <post.h>
#include <u-boot/sha256.h>
@@ -27,9 +28,19 @@ DECLARE_GLOBAL_DATA_PTR;
/* Stored value of bootdelay, used by autoboot_command() */
static int stored_bootdelay;
+static int menukey;
+
+#ifdef CONFIG_AUTOBOOT_ENCRYPTION
+#define AUTOBOOT_STOP_STR_SHA256 CONFIG_AUTOBOOT_STOP_STR_SHA256
+#else
+#define AUTOBOOT_STOP_STR_SHA256 ""
+#endif
-#if defined(CONFIG_AUTOBOOT_KEYED)
-#if defined(CONFIG_AUTOBOOT_STOP_STR_SHA256)
+#ifdef CONFIG_USE_AUTOBOOT_MENUKEY
+#define AUTOBOOT_MENUKEY CONFIG_USE_AUTOBOOT_MENUKEY
+#else
+#define AUTOBOOT_MENUKEY 0
+#endif
/*
* Use a "constant-length" time compare function for this
@@ -48,7 +59,15 @@ static int slow_equals(u8 *a, u8 *b, int len)
return diff == 0;
}
-static int passwd_abort(uint64_t etime)
+/**
+ * passwd_abort_sha256() - check for a hashed key sequence to abort booting
+ *
+ * This checks for the user entering a SHA256 hash within a given time.
+ *
+ * @etime: Timeout value ticks (stop when get_ticks() reachs this)
+ * @return 0 if autoboot should continue, 1 if it should stop
+ */
+static int passwd_abort_sha256(uint64_t etime)
{
const char *sha_env_str = env_get("bootstopkeysha256");
u8 sha_env[SHA256_SUM_LEN];
@@ -61,7 +80,7 @@ static int passwd_abort(uint64_t etime)
int ret;
if (sha_env_str == NULL)
- sha_env_str = CONFIG_AUTOBOOT_STOP_STR_SHA256;
+ sha_env_str = AUTOBOOT_STOP_STR_SHA256;
/*
* Generate the binary value from the environment hash value
@@ -99,8 +118,16 @@ static int passwd_abort(uint64_t etime)
return abort;
}
-#else
-static int passwd_abort(uint64_t etime)
+
+/**
+ * passwd_abort_key() - check for a key sequence to aborted booting
+ *
+ * This checks for the user entering a string within a given time.
+ *
+ * @etime: Timeout value ticks (stop when get_ticks() reachs this)
+ * @return 0 if autoboot should continue, 1 if it should stop
+ */
+static int passwd_abort_key(uint64_t etime)
{
int abort = 0;
struct {
@@ -176,13 +203,12 @@ static int passwd_abort(uint64_t etime)
return abort;
}
-#endif
/***************************************************************************
* Watch for 'delay' seconds for autoboot stop or autoboot delay string.
* returns: 0 - no key string, allow autoboot 1 - got key string, abort
*/
-static int __abortboot(int bootdelay)
+static int abortboot_key_sequence(int bootdelay)
{
int abort;
uint64_t etime = endtick(bootdelay);
@@ -195,29 +221,22 @@ static int __abortboot(int bootdelay)
printf(CONFIG_AUTOBOOT_PROMPT, bootdelay);
# endif
- abort = passwd_abort(etime);
+ if (IS_ENABLED(CONFIG_AUTOBOOT_ENCRYPTION))
+ abort = passwd_abort_sha256(etime);
+ else
+ abort = passwd_abort_key(etime);
if (!abort)
debug_bootkeys("key timeout\n");
return abort;
}
-# else /* !defined(CONFIG_AUTOBOOT_KEYED) */
-
-#ifdef CONFIG_MENUKEY
-static int menukey;
-#endif
-
-static int __abortboot(int bootdelay)
+static int abortboot_single_key(int bootdelay)
{
int abort = 0;
unsigned long ts;
-#ifdef CONFIG_MENUPROMPT
- printf(CONFIG_MENUPROMPT);
-#else
printf("Hit any key to stop autoboot: %2d ", bootdelay);
-#endif
/*
* Check if key already pressed
@@ -234,13 +253,13 @@ static int __abortboot(int bootdelay)
ts = get_timer(0);
do {
if (tstc()) { /* we got a key press */
+ int key;
+
abort = 1; /* don't auto boot */
bootdelay = 0; /* no more delay */
-# ifdef CONFIG_MENUKEY
- menukey = getc();
-# else
- (void) getc(); /* consume input */
-# endif
+ key = getc(); /* consume input */
+ if (IS_ENABLED(CONFIG_USE_AUTOBOOT_MENUKEY))
+ menukey = key;
break;
}
udelay(10000);
@@ -253,26 +272,27 @@ static int __abortboot(int bootdelay)
return abort;
}
-# endif /* CONFIG_AUTOBOOT_KEYED */
static int abortboot(int bootdelay)
{
int abort = 0;
- if (bootdelay >= 0)
- abort = __abortboot(bootdelay);
+ if (bootdelay >= 0) {
+ if (IS_ENABLED(CONFIG_AUTOBOOT_KEYED))
+ abort = abortboot_key_sequence(bootdelay);
+ else
+ abort = abortboot_single_key(bootdelay);
+ }
-#ifdef CONFIG_SILENT_CONSOLE
- if (abort)
+ if (IS_ENABLED(CONFIG_SILENT_CONSOLE) && abort)
gd->flags &= ~GD_FLG_SILENT;
-#endif
return abort;
}
static void process_fdt_options(const void *blob)
{
-#if defined(CONFIG_OF_CONTROL) && defined(CONFIG_SYS_TEXT_BASE)
+#ifdef CONFIG_SYS_TEXT_BASE
ulong addr;
/* Add an env variable to point to a kernel payload, if available */
@@ -284,7 +304,7 @@ static void process_fdt_options(const void *blob)
addr = fdtdec_get_config_int(gd->fdt_blob, "rootdisk-offset", 0);
if (addr)
env_set_addr("rootaddr", (void *)(CONFIG_SYS_TEXT_BASE + addr));
-#endif /* CONFIG_OF_CONTROL && CONFIG_SYS_TEXT_BASE */
+#endif /* CONFIG_SYS_TEXT_BASE */
}
const char *bootdelay_process(void)
@@ -297,16 +317,14 @@ const char *bootdelay_process(void)
s = env_get("bootdelay");
bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
-#ifdef CONFIG_OF_CONTROL
- bootdelay = fdtdec_get_config_int(gd->fdt_blob, "bootdelay",
- bootdelay);
-#endif
+ if (IS_ENABLED(CONFIG_OF_CONTROL))
+ bootdelay = fdtdec_get_config_int(gd->fdt_blob, "bootdelay",
+ bootdelay);
debug("### main_loop entered: bootdelay=%d\n\n", bootdelay);
-#if defined(CONFIG_MENU_SHOW)
- bootdelay = menu_show(bootdelay);
-#endif
+ if (IS_ENABLED(CONFIG_AUTOBOOT_MENU_SHOW))
+ bootdelay = menu_show(bootdelay);
bootretry_init_cmd_timeout();
#ifdef CONFIG_POST
@@ -319,7 +337,8 @@ const char *bootdelay_process(void)
else
s = env_get("bootcmd");
- process_fdt_options(gd->fdt_blob);
+ if (IS_ENABLED(CONFIG_OF_CONTROL))
+ process_fdt_options(gd->fdt_blob);
stored_bootdelay = bootdelay;
return s;
@@ -330,22 +349,24 @@ void autoboot_command(const char *s)
debug("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");
if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay)) {
-#if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC)
- int prev = disable_ctrlc(1); /* disable Control C checking */
-#endif
+ bool lock;
+ int prev;
+
+ lock = IS_ENABLED(CONFIG_AUTOBOOT_KEYED) &&
+ !IS_ENABLED(CONFIG_AUTOBOOT_KEYED_CTRLC);
+ if (lock)
+ prev = disable_ctrlc(1); /* disable Ctrl-C checking */
run_command_list(s, -1, 0);
-#if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC)
- disable_ctrlc(prev); /* restore Control C checking */
-#endif
+ if (lock)
+ disable_ctrlc(prev); /* restore Ctrl-C checking */
}
-#ifdef CONFIG_MENUKEY
- if (menukey == CONFIG_MENUKEY) {
+ if (IS_ENABLED(CONFIG_USE_AUTOBOOT_MENUKEY) &&
+ menukey == AUTOBOOT_MENUKEY) {
s = env_get("menucmd");
if (s)
run_command_list(s, -1, 0);
}
-#endif /* CONFIG_MENUKEY */
}
diff --git a/common/board_r.c b/common/board_r.c
index ee4dcedd5fa..84aec7fc71c 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -49,7 +49,7 @@
#include <linux/err.h>
#include <efi_loader.h>
#include <wdt.h>
-#if defined(CONFIG_DM_GPIO_HOG)
+#if defined(CONFIG_GPIO_HOG)
#include <asm/gpio.h>
#endif
@@ -799,7 +799,7 @@ static init_fnc_t init_sequence_r[] = {
#ifdef CONFIG_CMD_NET
initr_ethaddr,
#endif
-#if defined(CONFIG_DM_GPIO_HOG)
+#if defined(CONFIG_GPIO_HOG)
gpio_hog_probe_all,
#endif
#ifdef CONFIG_BOARD_LATE_INIT
diff --git a/common/bootm.c b/common/bootm.c
index bea516025fd..4629cdd82d4 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -7,17 +7,12 @@
#ifndef USE_HOSTCC
#include <common.h>
#include <bootstage.h>
-#include <bzlib.h>
#include <errno.h>
#include <fdt_support.h>
#include <lmb.h>
#include <malloc.h>
#include <mapmem.h>
#include <asm/io.h>
-#include <linux/lzo.h>
-#include <lzma/LzmaTypes.h>
-#include <lzma/LzmaDec.h>
-#include <lzma/LzmaTools.h>
#if defined(CONFIG_CMD_USB)
#include <usb.h>
#endif
@@ -299,23 +294,7 @@ static int bootm_find_other(cmd_tbl_t *cmdtp, int flag, int argc,
}
#endif /* USE_HOSTC */
-/**
- * print_decomp_msg() - Print a suitable decompression/loading message
- *
- * @type: OS type (IH_OS_...)
- * @comp_type: Compression type being used (IH_COMP_...)
- * @is_xip: true if the load address matches the image start
- */
-static void print_decomp_msg(int comp_type, int type, bool is_xip)
-{
- const char *name = genimg_get_type_name(type);
-
- if (comp_type == IH_COMP_NONE)
- printf(" %s %s ... ", is_xip ? "XIP" : "Loading", name);
- else
- printf(" Uncompressing %s ... ", name);
-}
-
+#if !defined(USE_HOSTCC) || defined(CONFIG_FIT_SIGNATURE)
/**
* handle_decomp_error() - display a decompression error
*
@@ -325,16 +304,18 @@ static void print_decomp_msg(int comp_type, int type, bool is_xip)
*
* @comp_type: Compression type being used (IH_COMP_...)
* @uncomp_size: Number of bytes uncompressed
- * @unc_len: Amount of space available for decompression
- * @ret: Error code to report
- * @return BOOTM_ERR_RESET, indicating that the board must be reset
+ * @ret: errno error code received from compression library
+ * @return Appropriate BOOTM_ERR_ error code
*/
-static int handle_decomp_error(int comp_type, size_t uncomp_size,
- size_t unc_len, int ret)
+static int handle_decomp_error(int comp_type, size_t uncomp_size, int ret)
{
const char *name = genimg_get_comp_name(comp_type);
- if (uncomp_size >= unc_len)
+ /* ENOSYS means unimplemented compression type, don't reset. */
+ if (ret == -ENOSYS)
+ return BOOTM_ERR_UNIMPLEMENTED;
+
+ if (uncomp_size >= CONFIG_SYS_BOOTM_LEN)
printf("Image too large: increase CONFIG_SYS_BOOTM_LEN\n");
else
printf("%s: uncompress error %d\n", name, ret);
@@ -351,93 +332,7 @@ static int handle_decomp_error(int comp_type, size_t uncomp_size,
return BOOTM_ERR_RESET;
}
-
-int bootm_decomp_image(int comp, ulong load, ulong image_start, int type,
- void *load_buf, void *image_buf, ulong image_len,
- uint unc_len, ulong *load_end)
-{
- int ret = 0;
-
- *load_end = load;
- print_decomp_msg(comp, type, load == image_start);
-
- /*
- * Load the image to the right place, decompressing if needed. After
- * this, image_len will be set to the number of uncompressed bytes
- * loaded, ret will be non-zero on error.
- */
- switch (comp) {
- case IH_COMP_NONE:
- if (load == image_start)
- break;
- if (image_len <= unc_len)
- memmove_wd(load_buf, image_buf, image_len, CHUNKSZ);
- else
- ret = 1;
- break;
-#ifdef CONFIG_GZIP
- case IH_COMP_GZIP: {
- ret = gunzip(load_buf, unc_len, image_buf, &image_len);
- break;
- }
-#endif /* CONFIG_GZIP */
-#ifdef CONFIG_BZIP2
- case IH_COMP_BZIP2: {
- uint size = unc_len;
-
- /*
- * If we've got less than 4 MB of malloc() space,
- * use slower decompression algorithm which requires
- * at most 2300 KB of memory.
- */
- ret = BZ2_bzBuffToBuffDecompress(load_buf, &size,
- image_buf, image_len,
- CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
- image_len = size;
- break;
- }
-#endif /* CONFIG_BZIP2 */
-#ifdef CONFIG_LZMA
- case IH_COMP_LZMA: {
- SizeT lzma_len = unc_len;
-
- ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len,
- image_buf, image_len);
- image_len = lzma_len;
- break;
- }
-#endif /* CONFIG_LZMA */
-#ifdef CONFIG_LZO
- case IH_COMP_LZO: {
- size_t size = unc_len;
-
- ret = lzop_decompress(image_buf, image_len, load_buf, &size);
- image_len = size;
- break;
- }
-#endif /* CONFIG_LZO */
-#ifdef CONFIG_LZ4
- case IH_COMP_LZ4: {
- size_t size = unc_len;
-
- ret = ulz4fn(image_buf, image_len, load_buf, &size);
- image_len = size;
- break;
- }
-#endif /* CONFIG_LZ4 */
- default:
- printf("Unimplemented compression type %d\n", comp);
- return BOOTM_ERR_UNIMPLEMENTED;
- }
-
- if (ret)
- return handle_decomp_error(comp, image_len, unc_len, ret);
- *load_end = load + image_len;
-
- puts("OK\n");
-
- return 0;
-}
+#endif
#ifndef USE_HOSTCC
static int bootm_load_os(bootm_headers_t *images, int boot_progress)
@@ -456,10 +351,11 @@ static int bootm_load_os(bootm_headers_t *images, int boot_progress)
load_buf = map_sysmem(load, 0);
image_buf = map_sysmem(os.image_start, image_len);
- err = bootm_decomp_image(os.comp, load, os.image_start, os.type,
- load_buf, image_buf, image_len,
- CONFIG_SYS_BOOTM_LEN, &load_end);
+ err = image_decomp(os.comp, load, os.image_start, os.type,
+ load_buf, image_buf, image_len,
+ CONFIG_SYS_BOOTM_LEN, &load_end);
if (err) {
+ err = handle_decomp_error(os.comp, load_end - load, err);
bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
return err;
}
@@ -919,11 +815,6 @@ void __weak switch_to_non_secure_mode(void)
#else /* USE_HOSTCC */
-void memmove_wd(void *to, void *from, size_t len, ulong chunksz)
-{
- memmove(to, from, len);
-}
-
#if defined(CONFIG_FIT_SIGNATURE)
static int bootm_host_load_image(const void *fit, int req_image_type)
{
@@ -957,13 +848,16 @@ static int bootm_host_load_image(const void *fit, int req_image_type)
/* Allow the image to expand by a factor of 4, should be safe */
load_buf = malloc((1 << 20) + len * 4);
- ret = bootm_decomp_image(imape_comp, 0, data, image_type, load_buf,
- (void *)data, len, CONFIG_SYS_BOOTM_LEN,
- &load_end);
+ ret = image_decomp(imape_comp, 0, data, image_type, load_buf,
+ (void *)data, len, CONFIG_SYS_BOOTM_LEN,
+ &load_end);
free(load_buf);
- if (ret && ret != BOOTM_ERR_UNIMPLEMENTED)
- return ret;
+ if (ret) {
+ ret = handle_decomp_error(imape_comp, load_end - 0, ret);
+ if (ret != BOOTM_ERR_UNIMPLEMENTED)
+ return ret;
+ }
return 0;
}
diff --git a/common/edid.c b/common/edid.c
index 90d1167f6ee..f99f42dc406 100644
--- a/common/edid.c
+++ b/common/edid.c
@@ -168,8 +168,12 @@ static bool cea_is_hdmi_vsdb_present(struct edid_cea861_info *info)
return false;
}
-int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing,
- int *panel_bits_per_colourp)
+int edid_get_timing_validate(u8 *buf, int buf_size,
+ struct display_timing *timing,
+ int *panel_bits_per_colourp,
+ bool (*mode_valid)(void *priv,
+ const struct display_timing *timing),
+ void *mode_valid_priv)
{
struct edid1_info *edid = (struct edid1_info *)buf;
bool timing_done;
@@ -193,8 +197,14 @@ int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing,
desc = &edid->monitor_details.descriptor[i];
if (desc->zero_flag_1 != 0) {
decode_timing((u8 *)desc, timing);
- timing_done = true;
- break;
+ if (mode_valid)
+ timing_done = mode_valid(mode_valid_priv,
+ timing);
+ else
+ timing_done = true;
+
+ if (timing_done)
+ break;
}
}
if (!timing_done)
@@ -225,6 +235,14 @@ int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing,
return 0;
}
+int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing,
+ int *panel_bits_per_colourp)
+{
+ return edid_get_timing_validate(buf, buf_size, timing,
+ panel_bits_per_colourp, NULL, NULL);
+}
+
+
/**
* Snip the tailing whitespace/return of a string.
*
diff --git a/common/image-fit.c b/common/image-fit.c
index a74b44f2982..e346fed550e 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -22,6 +22,7 @@
DECLARE_GLOBAL_DATA_PTR;
#endif /* !USE_HOSTCC*/
+#include <bootm.h>
#include <image.h>
#include <bootstage.h>
#include <u-boot/crc.h>
@@ -1521,6 +1522,10 @@ int fit_check_format(const void *fit)
* compatible list, "foo,bar", matches a compatible string in the root of fdt1.
* "bim,bam" in fdt2 matches the second string which isn't as good as fdt1.
*
+ * As an optimization, the compatible property from the FDT's root node can be
+ * copied into the configuration node in the FIT image. This is required to
+ * match configurations with compressed FDTs.
+ *
* returns:
* offset to the configuration to use if one was found
* -1 otherwise
@@ -1553,48 +1558,62 @@ int fit_conf_find_compat(const void *fit, const void *fdt)
for (noffset = fdt_next_node(fit, confs_noffset, &ndepth);
(noffset >= 0) && (ndepth > 0);
noffset = fdt_next_node(fit, noffset, &ndepth)) {
- const void *kfdt;
+ const void *fdt;
const char *kfdt_name;
- int kfdt_noffset;
+ int kfdt_noffset, compat_noffset;
const char *cur_fdt_compat;
int len;
- size_t size;
+ size_t sz;
int i;
if (ndepth > 1)
continue;
- kfdt_name = fdt_getprop(fit, noffset, "fdt", &len);
- if (!kfdt_name) {
- debug("No fdt property found.\n");
- continue;
- }
- kfdt_noffset = fdt_subnode_offset(fit, images_noffset,
- kfdt_name);
- if (kfdt_noffset < 0) {
- debug("No image node named \"%s\" found.\n",
- kfdt_name);
- continue;
- }
- /*
- * Get a pointer to this configuration's fdt.
- */
- if (fit_image_get_data(fit, kfdt_noffset, &kfdt, &size)) {
- debug("Failed to get fdt \"%s\".\n", kfdt_name);
- continue;
+ /* If there's a compat property in the config node, use that. */
+ if (fdt_getprop(fit, noffset, "compatible", NULL)) {
+ fdt = fit; /* search in FIT image */
+ compat_noffset = noffset; /* search under config node */
+ } else { /* Otherwise extract it from the kernel FDT. */
+ kfdt_name = fdt_getprop(fit, noffset, "fdt", &len);
+ if (!kfdt_name) {
+ debug("No fdt property found.\n");
+ continue;
+ }
+ kfdt_noffset = fdt_subnode_offset(fit, images_noffset,
+ kfdt_name);
+ if (kfdt_noffset < 0) {
+ debug("No image node named \"%s\" found.\n",
+ kfdt_name);
+ continue;
+ }
+
+ if (!fit_image_check_comp(fit, kfdt_noffset,
+ IH_COMP_NONE)) {
+ debug("Can't extract compat from \"%s\" "
+ "(compressed)\n", kfdt_name);
+ continue;
+ }
+
+ /* search in this config's kernel FDT */
+ if (fit_image_get_data(fit, kfdt_noffset, &fdt, &sz)) {
+ debug("Failed to get fdt \"%s\".\n", kfdt_name);
+ continue;
+ }
+
+ compat_noffset = 0; /* search kFDT under root node */
}
len = fdt_compat_len;
cur_fdt_compat = fdt_compat;
/*
* Look for a match for each U-Boot compatibility string in
- * turn in this configuration's fdt.
+ * turn in the compat string property.
*/
for (i = 0; len > 0 &&
(!best_match_offset || best_match_pos > i); i++) {
int cur_len = strlen(cur_fdt_compat) + 1;
- if (!fdt_node_check_compatible(kfdt, 0,
+ if (!fdt_node_check_compatible(fdt, compat_noffset,
cur_fdt_compat)) {
best_match_offset = noffset;
best_match_pos = i;
@@ -1795,11 +1814,12 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
const char *fit_uname_config;
const char *fit_base_uname_config;
const void *fit;
- const void *buf;
+ void *buf;
+ void *loadbuf;
size_t size;
int type_ok, os_ok;
- ulong load, data, len;
- uint8_t os;
+ ulong load, load_end, data, len;
+ uint8_t os, comp;
#ifndef USE_HOSTCC
uint8_t os_arch;
#endif
@@ -1895,12 +1915,6 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
images->os.arch = os_arch;
#endif
- if (image_type == IH_TYPE_FLATDT &&
- !fit_image_check_comp(fit, noffset, IH_COMP_NONE)) {
- puts("FDT image is compressed");
- return -EPROTONOSUPPORT;
- }
-
bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
type_ok = fit_image_check_type(fit, noffset, image_type) ||
fit_image_check_type(fit, noffset, IH_TYPE_FIRMWARE) ||
@@ -1931,7 +1945,8 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL_OK);
/* get image data address and length */
- if (fit_image_get_data_and_size(fit, noffset, &buf, &size)) {
+ if (fit_image_get_data_and_size(fit, noffset,
+ (const void **)&buf, &size)) {
printf("Could not find %s subimage data!\n", prop_name);
bootstage_error(bootstage_id + BOOTSTAGE_SUB_GET_DATA);
return -ENOENT;
@@ -1939,30 +1954,15 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
#if !defined(USE_HOSTCC) && defined(CONFIG_FIT_IMAGE_POST_PROCESS)
/* perform any post-processing on the image data */
- board_fit_image_post_process((void **)&buf, &size);
+ board_fit_image_post_process(&buf, &size);
#endif
len = (ulong)size;
- /* verify that image data is a proper FDT blob */
- if (image_type == IH_TYPE_FLATDT && fdt_check_header(buf)) {
- puts("Subimage data is not a FDT");
- return -ENOEXEC;
- }
-
bootstage_mark(bootstage_id + BOOTSTAGE_SUB_GET_DATA_OK);
- /*
- * Work-around for eldk-4.2 which gives this warning if we try to
- * cast in the unmap_sysmem() call:
- * warning: initialization discards qualifiers from pointer target type
- */
- {
- void *vbuf = (void *)buf;
-
- data = map_to_sysmem(vbuf);
- }
-
+ data = map_to_sysmem(buf);
+ load = data;
if (load_op == FIT_LOAD_IGNORED) {
/* Don't load */
} else if (fit_image_get_load(fit, noffset, &load)) {
@@ -1974,8 +1974,6 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
}
} else if (load_op != FIT_LOAD_OPTIONAL_NON_ZERO || load) {
ulong image_start, image_end;
- ulong load_end;
- void *dst;
/*
* move image data to the load address,
@@ -1993,14 +1991,45 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
printf(" Loading %s from 0x%08lx to 0x%08lx\n",
prop_name, data, load);
+ } else {
+ load = data; /* No load address specified */
+ }
+
+ comp = IH_COMP_NONE;
+ loadbuf = buf;
+ /* Kernel images get decompressed later in bootm_load_os(). */
+ if (!(image_type == IH_TYPE_KERNEL ||
+ image_type == IH_TYPE_KERNEL_NOLOAD) &&
+ !fit_image_get_comp(fit, noffset, &comp) &&
+ comp != IH_COMP_NONE) {
+ ulong max_decomp_len = len * 20;
+ if (load == data) {
+ loadbuf = malloc(max_decomp_len);
+ load = map_to_sysmem(loadbuf);
+ } else {
+ loadbuf = map_sysmem(load, max_decomp_len);
+ }
+ if (image_decomp(comp, load, data, image_type,
+ loadbuf, buf, len, max_decomp_len, &load_end)) {
+ printf("Error decompressing %s\n", prop_name);
- dst = map_sysmem(load, len);
- memmove(dst, buf, len);
- data = load;
+ return -ENOEXEC;
+ }
+ len = load_end - load;
+ } else if (load != data) {
+ loadbuf = map_sysmem(load, len);
+ memcpy(loadbuf, buf, len);
}
+
+ /* verify that image data is a proper FDT blob */
+ if (image_type == IH_TYPE_FLATDT && fdt_check_header(loadbuf)) {
+ puts("Subimage data is not a FDT");
+ return -ENOEXEC;
+ }
+
bootstage_mark(bootstage_id + BOOTSTAGE_SUB_LOAD);
- *datap = data;
+ *datap = load;
*lenp = len;
if (fit_unamep)
*fit_unamep = (char *)fit_uname;
diff --git a/common/image.c b/common/image.c
index 9f9538fac2f..495883185d4 100644
--- a/common/image.c
+++ b/common/image.c
@@ -32,6 +32,12 @@
#include <linux/errno.h>
#include <asm/io.h>
+#include <bzlib.h>
+#include <linux/lzo.h>
+#include <lzma/LzmaTypes.h>
+#include <lzma/LzmaDec.h>
+#include <lzma/LzmaTools.h>
+
#ifdef CONFIG_CMD_BDI
extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
#endif
@@ -375,6 +381,106 @@ void image_print_contents(const void *ptr)
}
}
+/**
+ * print_decomp_msg() - Print a suitable decompression/loading message
+ *
+ * @type: OS type (IH_OS_...)
+ * @comp_type: Compression type being used (IH_COMP_...)
+ * @is_xip: true if the load address matches the image start
+ */
+static void print_decomp_msg(int comp_type, int type, bool is_xip)
+{
+ const char *name = genimg_get_type_name(type);
+
+ if (comp_type == IH_COMP_NONE)
+ printf(" %s %s\n", is_xip ? "XIP" : "Loading", name);
+ else
+ printf(" Uncompressing %s\n", name);
+}
+
+int image_decomp(int comp, ulong load, ulong image_start, int type,
+ void *load_buf, void *image_buf, ulong image_len,
+ uint unc_len, ulong *load_end)
+{
+ int ret = 0;
+
+ *load_end = load;
+ print_decomp_msg(comp, type, load == image_start);
+
+ /*
+ * Load the image to the right place, decompressing if needed. After
+ * this, image_len will be set to the number of uncompressed bytes
+ * loaded, ret will be non-zero on error.
+ */
+ switch (comp) {
+ case IH_COMP_NONE:
+ if (load == image_start)
+ break;
+ if (image_len <= unc_len)
+ memmove_wd(load_buf, image_buf, image_len, CHUNKSZ);
+ else
+ ret = -ENOSPC;
+ break;
+#ifdef CONFIG_GZIP
+ case IH_COMP_GZIP: {
+ ret = gunzip(load_buf, unc_len, image_buf, &image_len);
+ break;
+ }
+#endif /* CONFIG_GZIP */
+#ifdef CONFIG_BZIP2
+ case IH_COMP_BZIP2: {
+ uint size = unc_len;
+
+ /*
+ * If we've got less than 4 MB of malloc() space,
+ * use slower decompression algorithm which requires
+ * at most 2300 KB of memory.
+ */
+ ret = BZ2_bzBuffToBuffDecompress(load_buf, &size,
+ image_buf, image_len,
+ CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
+ image_len = size;
+ break;
+ }
+#endif /* CONFIG_BZIP2 */
+#ifdef CONFIG_LZMA
+ case IH_COMP_LZMA: {
+ SizeT lzma_len = unc_len;
+
+ ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len,
+ image_buf, image_len);
+ image_len = lzma_len;
+ break;
+ }
+#endif /* CONFIG_LZMA */
+#ifdef CONFIG_LZO
+ case IH_COMP_LZO: {
+ size_t size = unc_len;
+
+ ret = lzop_decompress(image_buf, image_len, load_buf, &size);
+ image_len = size;
+ break;
+ }
+#endif /* CONFIG_LZO */
+#ifdef CONFIG_LZ4
+ case IH_COMP_LZ4: {
+ size_t size = unc_len;
+
+ ret = ulz4fn(image_buf, image_len, load_buf, &size);
+ image_len = size;
+ break;
+ }
+#endif /* CONFIG_LZ4 */
+ default:
+ printf("Unimplemented compression type %d\n", comp);
+ return -ENOSYS;
+ }
+
+ *load_end = load + image_len;
+
+ return ret;
+}
+
#ifndef USE_HOSTCC
#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
@@ -551,6 +657,11 @@ void memmove_wd(void *to, void *from, size_t len, ulong chunksz)
memmove(to, from, len);
#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
}
+#else /* USE_HOSTCC */
+void memmove_wd(void *to, void *from, size_t len, ulong chunksz)
+{
+ memmove(to, from, len);
+}
#endif /* !USE_HOSTCC */
void genimg_print_size(uint32_t size)
diff --git a/common/main.c b/common/main.c
index 07b34bf2b05..ce39c8d1899 100644
--- a/common/main.c
+++ b/common/main.c
@@ -19,7 +19,6 @@ __weak void show_boot_progress(int val) {}
static void run_preboot_environment_command(void)
{
-#ifdef CONFIG_PREBOOT
char *p;
p = env_get("preboot");
@@ -34,7 +33,6 @@ static void run_preboot_environment_command(void)
if (IS_ENABLED(CONFIG_AUTOBOOT_KEYED))
disable_ctrlc(prev); /* restore Ctrl-C checking */
}
-#endif /* CONFIG_PREBOOT */
}
/* We come here after U-Boot is initialised and ready to process commands */
@@ -49,7 +47,8 @@ void main_loop(void)
cli_init();
- run_preboot_environment_command();
+ if (IS_ENABLED(CONFIG_USE_PREBOOT))
+ run_preboot_environment_command();
if (IS_ENABLED(CONFIG_UPDATE_TFTP))
update_tftp(0UL, NULL, NULL);