Commit 414c34ed authored by Atish Patra's avatar Atish Patra Committed by Tom Rini
Browse files

image: Add compressed Image parsing support in booti.



Add compressed Image parsing support so that booti can parse both
flat and compressed Image to boot Linux. Currently, it is difficult
to calculate a safe address for every board where the compressed
image can be decompressed. It is also not possible to figure out the
size of the compressed file as well. Thus, user need to set two
additional environment variables kernel_comp_addr_r and filesize to
make this work.

Following compression methods are supported for now.
lzma, lzo, bzip2, gzip.

lz4 support is not added as ARM64 kernel generates a lz4 compressed
image with legacy header which U-Boot doesn't know how to parse and
decompress.

Tested on HiFive Unleashed and Qemu for RISC-V.
Tested on Qemu for ARM64.
Signed-off-by: default avatarAtish Patra <atish.patra@wdc.com>
Reviewed-by: Tom Rini's avatarTom Rini <trini@konsulko.com>
[trini: Fix minor rST formatting problems]
Signed-off-by: Tom Rini's avatarTom Rini <trini@konsulko.com>
parent 155d6a35
......@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/sizes.h>
DECLARE_GLOBAL_DATA_PTR;
/*
* Image booting support
*/
......@@ -24,6 +25,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);
......@@ -38,6 +45,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("kernel_comp_size", 16, 0);
if (!dest || !comp_len) {
puts("kernel_comp_addr_r or kernel_comp_size 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;
......@@ -100,10 +134,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 kernel_comp_size 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"
......
......@@ -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.
kernel_comp_size:
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
......
......@@ -135,6 +135,11 @@ 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...
......@@ -174,6 +179,59 @@ 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 kernel_comp_size 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...
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment