booti usage offset requirements for compressed kernel and initrd with dtb

Tom Rini trini at konsulko.com
Mon Jan 8 18:27:57 CET 2024


On Sat, Jan 06, 2024 at 02:45:47PM -0800, E Shattow wrote:
> Hi Simon,
> 
> "If this [fdt_high environment variable] is set to the special value
> 0xffffffff (32-bit machines) or 0xffffffffffffffff (64-bit machines) then
> the fdt will not be copied at all on boot. For this to work it must reside
> in writable memory, have sufficient padding on the end of it for U-Boot to
> add the information it needs into it, and the memory must be accessible by
> the kernel. This usage is strongly discouraged however as it also stops
> U-Boot from ensuring the device tree starting address is properly aligned
> and a misaligned tree will cause OS failures."
> 
> https://docs.u-boot.org/en/latest/usage/environment.html
> 
> "The device tree blob (dtb) must be placed on an 8-byte boundary"
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/arch/arm64/booting.rst
> 
> No mention of dtb alignment requirement at the similar documentation for
> riscv64, but there is this mention:
> "The RISC-V kernel expects to be placed at a PMD boundary (2MB aligned for
> rv64 and 4MB aligned for rv32)."
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/arch/riscv/boot.rst
> 
> Perhaps then it is both a dtb alignment issue (not mentioned in the
> documentation?) and the spurious extra requirement after the transferred
> data length?
> 
> If yes, how much is enough to pad after the end of devicetree blob?

One should not try and aim for the smallest possible memory region here,
but instead pick good defaults. Practically speaking, if I recall, 128MB
is an implicit limit in uncompressed kernel image size, so taking one
128MB chunk for the kernel, and the next 128MB chunk for a decompress-to
location is reasonable. Then carve a few MB for device tree next, then
initrd goes after that.

> 
> Thanks!
> 
> E Shattow
> 
> 
> 
> On Thu, Jan 4, 2024 at 8:02 AM Simon Glass <sjg at chromium.org> wrote:
> 
> > 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
> >

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20240108/06b2b46b/attachment.sig>


More information about the U-Boot mailing list