booti usage offset requirements for compressed kernel and initrd with dtb

Simon Glass sjg at chromium.org
Thu Jan 4 17:02:38 CET 2024


Hi,

On Thu, Jan 4, 2024 at 5:19 AM E Shattow <lucent at gmail.com> wrote:
>
> Hello,
>
> There is data corruption when using booti on a JH7110 (riscv64) board to
> load (over tftp or ymodem) a compressed kernel, compressed initrd, and
> device tree blob, when the data are too close together (even though not
> overlapping). In the adjustments I have tried it seems to be consistent but
> not clear "why?" by how much for each adjustment is needed to observe the
> failure versus success.
>
> My question is simple enough, what are the intended offset requirements for
> loading these data into memory for use with booti ?
>
> For example:
>
> setenv ip 192.168.2.216
> setenv loadaddr 0x60000000  # default from Milk-V vendor for Mars CM product
> setenv kernel_uncomp_size 24193024  # uncompressed size of
> vmlinuz-5.15.0-gpu117 from file command information
> setenv kernel_comp_addr_r $loadaddr
> setenv kernel_addr_r 0x61712800  # $kernel_comp_addr_r + $kernel_uncomp_size
> dhcp $kernel_addr_r
> $ip:mars-cm_debian-desktop_sdk-boot/vmlinuz-5.15.0-gpu117
> setenv kernel_comp_size 0x$filesize
> setenv dtb_addr 0x62e25000  # $kernel_addr_r + $kernel_uncomp_size
> dhcp $dtb_addr
> $ip:mars-cm_debian-desktop_sdk-boot/dtbs/starfive/jh7110-visionfive-v2.dtb
> setenv initrd_addr 0x62e31d7f  # $dtb_addr + 0x$filesize
> dhcp $initrd_addr $ip:debian-installer-netboot/initrd.gz; setenv
> initrd_size 0x$filesize
> booti $kernel_addr_r $initrd_addr:$initrd_size $dtb_addr
>
> Waiting for root device ...
>
> (and nothing else, this is a failure)
>
> If 0x62e31d7f is replaced by 0x62e31ec6 then the boot is successful and
> dmesg from debian-installer shows the additional information:
>
>  Freeing unused kernel image (initmem) memory: 2196K
>  Run /init as init process
>    with arguments:
>      /init
>    with environment:
>      HOME=/
>      TERM=linux
>
>
> So in this the kernel boots and all works normally. Even if that address is
> 0x62e31ec5 one byte earlier it is a failure.
>
> In other attempts I would change the ordering i.e. so the initrd is first
> at $loadaddr and then kernel and DTB, or DTB and kernel. If I learned
> anything it is that compressed initrd must be loaded to a span of memory at
> least the size of its uncompressed length, and this is also true of the
> compressed kernel vmlinuz even though booti documentation vaguely infers
> that there is an area of memory specified for decompression - so a
> compressed kernel needs two times its uncompressed size is that correct?
> Also there's no hint anywhere if the device tree blob has special memory
> constraints but if it is not starting on some 16byte aligned address at
> least my superstition from observations in testing is that it is not
> successful... and now, where it ends (in the above example) and initrd
> begins seems arbitrary.
>
> Sure I could pad things out, they tend to work that way, but I would like
> to know "why?"

I don't know why, but I imagine that Linux finds the initrd in one
case and not inthe other...does the kernel log give you any clues?

Also, can you use U-Boot's 'md5sum' command or similar to check that
the initrd and DT are the same in each case?

Also, you could use a FIT [1] rather than booti.

Regards,
Simon

[1] https://docs.u-boot.org/en/latest/usage/fit/index.html


More information about the U-Boot mailing list