On Sat, Nov 9, 2019 at 2:14 AM Atish Patra <atish.pa...@wdc.com> wrote: > > 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: Atish Patra <atish.pa...@wdc.com> > --- > I could not test this patch on any ARM64 boards due to lack of > access to any ARM64 board. If anybody can test it on ARM64, that > would be great. > --- > cmd/booti.c | 40 ++++++++++++++++++++++++++- > doc/README.distro | 12 +++++++++ > doc/board/sifive/fu540.rst | 55 ++++++++++++++++++++++++++++++++++++++ > 3 files changed, 106 insertions(+), 1 deletion(-) > > diff --git a/cmd/booti.c b/cmd/booti.c > index c36b0235df8c..cd8670a9a8db 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; > @@ -96,10 +130,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/doc/README.distro b/doc/README.distro > index ab6e6f4e74be..67b49e1e4b6a 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. > +
I am not sure I like using filesize here compared to kernel_gz_size. It's true that $filesize will be set once your load the binary, e.g. from mmc. But in EXTLINUX/PXE situation $filesize could be wrong. The load happens in this order: - initrd - kernel - fdt So if I specify FDT in my EXTLINUX/PXE config the $filesize will be wrong while attempting to boot the kernel. Unless we save filesize of kernel after loading and set it again before calling do_booti() in pxe.c. Currently I set kernel_gz_size in board environment, which is set to max allowed size. david > 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 7807f5b2c128..df2c5ad8d3e3 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... > -- > 2.24.0 > > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > https://lists.denx.de/listinfo/u-boot _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot