268 lines
9.8 KiB
Diff
268 lines
9.8 KiB
Diff
diff --git a/cmd/booti.c b/cmd/booti.c
|
|
index 841eff10..60bb4920 100644
|
|
--- a/cmd/booti.c
|
|
+++ b/cmd/booti.c
|
|
@@ -13,6 +13,7 @@
|
|
#include <linux/kernel.h>
|
|
#include <linux/sizes.h>
|
|
|
|
+DECLARE_GLOBAL_DATA_PTR;
|
|
/*
|
|
* Image booting support
|
|
*/
|
|
@@ -23,6 +24,12 @@ static int booti_start(cmd_tbl_t *cmdtp, int flag, int argc,
|
|
ulong ld;
|
|
ulong relocated_addr;
|
|
ulong image_size;
|
|
+ uint8_t *temp;
|
|
+ ulong dest;
|
|
+ ulong dest_end;
|
|
+ unsigned long comp_len;
|
|
+ unsigned long decomp_len;
|
|
+ int ctype;
|
|
|
|
ret = do_bootm_states(cmdtp, flag, argc, argv, BOOTM_STATE_START,
|
|
images, 1);
|
|
@@ -37,6 +44,33 @@ static int booti_start(cmd_tbl_t *cmdtp, int flag, int argc,
|
|
debug("* kernel: cmdline image address = 0x%08lx\n", ld);
|
|
}
|
|
|
|
+ temp = map_sysmem(ld, 0);
|
|
+ ctype = image_decomp_type(temp, 2);
|
|
+ if (ctype > 0) {
|
|
+ dest = env_get_ulong("kernel_comp_addr_r", 16, 0);
|
|
+ comp_len = env_get_ulong("filesize", 16, 0);
|
|
+ if (!dest || !comp_len) {
|
|
+ puts("kernel_comp_addr_r or filesize is not provided!\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ if (dest < gd->ram_base || dest > gd->ram_top) {
|
|
+ puts("kernel_comp_addr_r is outside of DRAM range!\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ debug("kernel image compression type %d size = 0x%08lx address = 0x%08lx\n",
|
|
+ ctype, comp_len, (ulong)dest);
|
|
+ decomp_len = comp_len * 10;
|
|
+ ret = image_decomp(ctype, 0, ld, IH_TYPE_KERNEL,
|
|
+ (void *)dest, (void *)ld, comp_len,
|
|
+ decomp_len, &dest_end);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ /* dest_end contains the uncompressed Image size */
|
|
+ memmove((void *) ld, (void *)dest, dest_end);
|
|
+ }
|
|
+ unmap_sysmem((void *)ld);
|
|
+
|
|
ret = booti_setup(ld, &relocated_addr, &image_size, false);
|
|
if (ret != 0)
|
|
return 1;
|
|
@@ -99,10 +133,14 @@ int do_booti(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|
#ifdef CONFIG_SYS_LONGHELP
|
|
static char booti_help_text[] =
|
|
"[addr [initrd[:size]] [fdt]]\n"
|
|
- " - boot Linux 'Image' stored at 'addr'\n"
|
|
+ " - boot Linux flat or compressed 'Image' stored at 'addr'\n"
|
|
"\tThe argument 'initrd' is optional and specifies the address\n"
|
|
"\tof an initrd in memory. The optional parameter ':size' allows\n"
|
|
"\tspecifying the size of a RAW initrd.\n"
|
|
+ "\tCurrently only booting from gz, bz2, lzma and lz4 compression\n"
|
|
+ "\ttypes are supported. In order to boot from any of these compressed\n"
|
|
+ "\timages, user have to set kernel_comp_addr_r and filesize enviornment\n"
|
|
+ "\tvariables beforehand.\n"
|
|
#if defined(CONFIG_OF_LIBFDT)
|
|
"\tSince booting a Linux kernel requires a flat device-tree, a\n"
|
|
"\tthird argument providing the address of the device-tree blob\n"
|
|
diff --git a/common/image.c b/common/image.c
|
|
index f17fa40c..cbd6c494 100644
|
|
--- a/common/image.c
|
|
+++ b/common/image.c
|
|
@@ -197,6 +197,14 @@ struct table_info {
|
|
const table_entry_t *table;
|
|
};
|
|
|
|
+static const struct comp_magic_map image_comp[] = {
|
|
+ { IH_COMP_BZIP2, "bzip2", {0x42, 0x5a},},
|
|
+ { IH_COMP_GZIP, "gzip", {0x1f, 0x8b},},
|
|
+ { IH_COMP_LZMA, "lzma", {0x5d, 0x00},},
|
|
+ { IH_COMP_LZO, "lzo", {0x89, 0x4c},},
|
|
+ { IH_COMP_NONE, "none", {}, },
|
|
+};
|
|
+
|
|
static const struct table_info table_info[IH_COUNT] = {
|
|
{ "architecture", IH_ARCH_COUNT, uimage_arch },
|
|
{ "compression", IH_COMP_COUNT, uimage_comp },
|
|
@@ -402,6 +410,21 @@ static void print_decomp_msg(int comp_type, int type, bool is_xip)
|
|
printf(" Uncompressing %s\n", name);
|
|
}
|
|
|
|
+int image_decomp_type(const unsigned char *buf, ulong len)
|
|
+{
|
|
+ const struct comp_magic_map *cmagic = image_comp;
|
|
+
|
|
+ if (len < 2)
|
|
+ return -EINVAL;
|
|
+
|
|
+ for (; cmagic->comp_id > 0; cmagic++) {
|
|
+ if (!memcmp(buf, cmagic->magic, 2))
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ return cmagic->comp_id;
|
|
+}
|
|
+
|
|
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)
|
|
diff --git a/doc/README.distro b/doc/README.distro
|
|
index ab6e6f4e..67b49e1e 100644
|
|
--- a/doc/README.distro
|
|
+++ b/doc/README.distro
|
|
@@ -246,6 +246,18 @@ kernel_addr_r:
|
|
|
|
A size of 16MB for the kernel is likely adequate.
|
|
|
|
+kernel_comp_addr_r:
|
|
+ Optional. This is only required if user wants to boot Linux from a compressed
|
|
+ Image(.gz, .bz2, .lzma, .lzo) using booti command. It represents the location
|
|
+ in RAM where the compressed Image will be decompressed temporarily. Once the
|
|
+ decompression is complete, decompressed data will be moved kernel_addr_r for
|
|
+ booting.
|
|
+
|
|
+filesize:
|
|
+ Optional. This is only required if user wants to boot Linux from a compressed
|
|
+ Image using booti command. It represents the size of the compressed file. The
|
|
+ size has to at least the size of loaded image for decompression to succeed.
|
|
+
|
|
pxefile_addr_r:
|
|
|
|
Mandatory. The location in RAM where extlinux.conf will be loaded to prior
|
|
diff --git a/doc/board/sifive/fu540.rst b/doc/board/sifive/fu540.rst
|
|
index 7807f5b2..df2c5ad8 100644
|
|
--- a/doc/board/sifive/fu540.rst
|
|
+++ b/doc/board/sifive/fu540.rst
|
|
@@ -138,6 +138,10 @@ load uImage.
|
|
=> setenv netmask 255.255.252.0
|
|
=> setenv serverip 10.206.4.143
|
|
=> setenv gateway 10.206.4.1
|
|
+
|
|
+If you want to use a flat kernel image such as Image file
|
|
+
|
|
+.. code-block:: none
|
|
=> tftpboot ${kernel_addr_r} /sifive/fu540/Image
|
|
ethernet@10090000: PHY present at 0
|
|
ethernet@10090000: Starting autonegotiation...
|
|
@@ -177,6 +181,57 @@ load uImage.
|
|
1.2 MiB/s
|
|
done
|
|
Bytes transferred = 8867100 (874d1c hex)
|
|
+
|
|
+Or if you want to use a compressed kernel image file such as Image.gz
|
|
+
|
|
+.. code-block:: none
|
|
+ => tftpboot ${kernel_addr_r} /sifive/fu540/Image.gz
|
|
+ ethernet@10090000: PHY present at 0
|
|
+ ethernet@10090000: Starting autonegotiation...
|
|
+ ethernet@10090000: Autonegotiation complete
|
|
+ ethernet@10090000: link up, 1000Mbps full-duplex (lpa: 0x3c00)
|
|
+ Using ethernet@10090000 device
|
|
+ TFTP from server 10.206.4.143; our IP address is 10.206.7.133
|
|
+ Filename '/sifive/fu540/Image.gz'.
|
|
+ Load address: 0x84000000
|
|
+ Loading: #################################################################
|
|
+ #################################################################
|
|
+ #################################################################
|
|
+ #################################################################
|
|
+ #################################################################
|
|
+ #################################################################
|
|
+ #################################################################
|
|
+ #################################################################
|
|
+ #################################################################
|
|
+ #################################################################
|
|
+ #################################################################
|
|
+ #################################################################
|
|
+ #################################################################
|
|
+ #################################################################
|
|
+ #################################################################
|
|
+ #################################################################
|
|
+ #################################################################
|
|
+ #################################################################
|
|
+ #################################################################
|
|
+ #################################################################
|
|
+ #################################################################
|
|
+ #################################################################
|
|
+ #################################################################
|
|
+ #################################################################
|
|
+ #################################################################
|
|
+ #################################################################
|
|
+ ##########################################
|
|
+ 1.2 MiB/s
|
|
+ done
|
|
+ Bytes transferred = 4809458 (4962f2 hex)
|
|
+ =>setenv kernel_comp_addr_r 0x90000000
|
|
+ =>setenv filesize 0x500000
|
|
+
|
|
+By this time, correct kernel image is loaded and required enviornment variables
|
|
+are set. You can proceed to load the ramdisk and device tree from the tftp server
|
|
+as well.
|
|
+
|
|
+.. code-block:: none
|
|
=> tftpboot ${ramdisk_addr_r} /sifive/fu540/uRamdisk
|
|
ethernet@10090000: PHY present at 0
|
|
ethernet@10090000: Starting autonegotiation...
|
|
diff --git a/include/image.h b/include/image.h
|
|
index f4d2aaf5..823c187b 100644
|
|
--- a/include/image.h
|
|
+++ b/include/image.h
|
|
@@ -447,6 +447,15 @@ typedef struct table_entry {
|
|
char *lname; /* long (output) name to print for messages */
|
|
} table_entry_t;
|
|
|
|
+/*
|
|
+ * Compression type and magic number mapping table.
|
|
+ */
|
|
+struct comp_magic_map {
|
|
+ int comp_id;
|
|
+ const char *name;
|
|
+ unsigned char magic[2];
|
|
+};
|
|
+
|
|
/*
|
|
* get_table_entry_id() scans the translation table trying to find an
|
|
* entry that matches the given short name. If a matching entry is
|
|
@@ -851,6 +860,18 @@ static inline int image_check_target_arch(const image_header_t *hdr)
|
|
}
|
|
#endif /* USE_HOSTCC */
|
|
|
|
+/**
|
|
+ * image_decomp_type() - Find out compression type of an image
|
|
+ *
|
|
+ * @buf: Address in U-Boot memory where image is loaded.
|
|
+ * @len: Length of the compressed image.
|
|
+ * @return compression type or IH_COMP_NONE if not compressed.
|
|
+ *
|
|
+ * Note: Only following compression types are supported now.
|
|
+ * lzo, lzma, gzip, bzip2
|
|
+ */
|
|
+int image_decomp_type(const unsigned char *buf, ulong len);
|
|
+
|
|
/**
|
|
* image_decomp() - decompress an image
|
|
*
|
|
diff --git a/lib/Kconfig b/lib/Kconfig
|
|
index b8a8509d..53661baf 100644
|
|
--- a/lib/Kconfig
|
|
+++ b/lib/Kconfig
|
|
@@ -397,6 +397,11 @@ config GZIP
|
|
help
|
|
This enables support for GZIP compression algorithm.
|
|
|
|
+config BZIP2
|
|
+ bool "Enable bzip2 decompression support"
|
|
+ help
|
|
+ This enables support for BZIP2 compression algorithm.
|
|
+
|
|
config ZLIB
|
|
bool
|
|
default y
|