diff mbox series

[U-Boot] x86/bootm: fix compressed image boot

Message ID 1539236715-30766-1-git-send-email-hannes.schmelzer@br-automation.com
State Deferred
Delegated to: Bin Meng
Headers show
Series [U-Boot] x86/bootm: fix compressed image boot | expand

Commit Message

Hannes Schmelzer Oct. 11, 2018, 5:45 a.m. UTC
If we're booting some u-boot module with compressed payload, we have to
use the pointer where the image really has been loaded (unzipped) to
instead the pointer to the payload of the u-boot module.

Signed-off-by: Hannes Schmelzer <hannes.schmelzer@br-automation.com>
---

 arch/x86/lib/bootm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Bin Meng Oct. 11, 2018, 6:01 a.m. UTC | #1
Hi Hannes,

On Thu, Oct 11, 2018 at 1:45 PM Hannes Schmelzer
<hannes.schmelzer@br-automation.com> wrote:
>
> If we're booting some u-boot module with compressed payload, we have to
> use the pointer where the image really has been loaded (unzipped) to
> instead the pointer to the payload of the u-boot module.
>
> Signed-off-by: Hannes Schmelzer <hannes.schmelzer@br-automation.com>
> ---
>
>  arch/x86/lib/bootm.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>

Can you describe with what reproduce steps current codes are failing? thanks!

Regards,
Bin
Hannes Schmelzer Oct. 11, 2018, 6:41 a.m. UTC | #2
On 11.10.2018 08:01, Bin Meng wrote:
> Hi Hannes,
Hi Bing,
thanks for very quick response on this.
>
> On Thu, Oct 11, 2018 at 1:45 PM Hannes Schmelzer
> <hannes.schmelzer@br-automation.com> wrote:
>> If we're booting some u-boot module with compressed payload, we have to
>> use the pointer where the image really has been loaded (unzipped) to
>> instead the pointer to the payload of the u-boot module.
>>
>> Signed-off-by: Hannes Schmelzer <hannes.schmelzer@br-automation.com>
>> ---
>>
>>   arch/x86/lib/bootm.c | 4 ++--
>>   1 file changed, 2 insertions(+), 2 deletions(-)
>>
> Can you describe with what reproduce steps current codes are failing? thanks!
The boot of a u-boot module with bootm walks like this:

=> bootm ${loadaddr} ${ramdisk} ${fdtcontroladdr}
this leads to call (coming through cmd/bootm.c) to "do_bootm_states".
The task of this "do_bootm_states" is to find out what todo with the 
provided image (u-boot module),
is it compressed or not, which kind of os should be booted, ...

So, for doing this work, "bootm_decomp_image" is called,
this function uses the image-header for finding out the compression 
method and does decompress the real payload to some location.

bootm_os_load moves on and finds out that some compressed linux payload 
shall be booted.
So the "do_bootm_linux" and finally "boot_prep_linux" from lib/x86, 
since wer'e actually running on a x86 machine, is called.

This function makes the assumption that the bootable binary is directly 
the payload of the u-boot module,
ignoring the work done by "bootm_decomp_image" during the step before 
and tries to boot directly in my case a gzip binary.

This is wrong.

>
> Regards,
> Bin
cheers,
Hannes
Bin Meng Nov. 20, 2018, 3:34 p.m. UTC | #3
Hi Hannes,

On Thu, Oct 11, 2018 at 2:41 PM Hannes Schmelzer <hannes@schmelzer.or.at> wrote:
>
>
> On 11.10.2018 08:01, Bin Meng wrote:
> > Hi Hannes,
> Hi Bing,
> thanks for very quick response on this.
> >
> > On Thu, Oct 11, 2018 at 1:45 PM Hannes Schmelzer
> > <hannes.schmelzer@br-automation.com> wrote:
> >> If we're booting some u-boot module with compressed payload, we have to
> >> use the pointer where the image really has been loaded (unzipped) to
> >> instead the pointer to the payload of the u-boot module.
> >>
> >> Signed-off-by: Hannes Schmelzer <hannes.schmelzer@br-automation.com>
> >> ---
> >>
> >>   arch/x86/lib/bootm.c | 4 ++--
> >>   1 file changed, 2 insertions(+), 2 deletions(-)
> >>
> > Can you describe with what reproduce steps current codes are failing? thanks!
> The boot of a u-boot module with bootm walks like this:
>
> => bootm ${loadaddr} ${ramdisk} ${fdtcontroladdr}
> this leads to call (coming through cmd/bootm.c) to "do_bootm_states".
> The task of this "do_bootm_states" is to find out what todo with the
> provided image (u-boot module),
> is it compressed or not, which kind of os should be booted, ...
>
> So, for doing this work, "bootm_decomp_image" is called,
> this function uses the image-header for finding out the compression
> method and does decompress the real payload to some location.
>
> bootm_os_load moves on and finds out that some compressed linux payload
> shall be booted.
> So the "do_bootm_linux" and finally "boot_prep_linux" from lib/x86,
> since wer'e actually running on a x86 machine, is called.
>
> This function makes the assumption that the bootable binary is directly
> the payload of the u-boot module,
> ignoring the work done by "bootm_decomp_image" during the step before
> and tries to boot directly in my case a gzip binary.
>
> This is wrong.
>

Thanks for the explanation. This patch looks good to me.

However I was unable to proceed some testing to verify this.

When I use 'bootm' to boot a uImage with uncompressed bzImage, I simply get:

=> bootm 2000000 3000000
## Booting kernel from Legacy Image at 02000000 ...
   Image Name:   linux
   Created:      2018-11-20  15:23:19 UTC
   Image Type:   Intel x86 Linux Kernel Image (uncompressed)
   Data Size:    7716768 Bytes = 7.4 MiB
   Load Address: 01000000
   Entry Point:  01000000
   Verifying Checksum ... OK
Could not find a valid setup.bin for x86

It looks the error message comes from boot_get_setup() which expects
bootm payload is of FIT format. However this patch expects a uImage
with legacy format (images->legacy_hdr_valid == true).

Can you please post your complete instructions, including how to
create uImage for U-Boot's bootm work for legacy booting?

Regards,
Bin
Hannes Schmelzer Nov. 23, 2018, 6:50 a.m. UTC | #4
On 20.11.2018 16:34, Bin Meng wrote:
> Hi Hannes,
Hi Bin,
thanks for having a look into and sorry for my late response.

>
> On Thu, Oct 11, 2018 at 2:41 PM Hannes Schmelzer <hannes@schmelzer.or.at> wrote:
>>
>> On 11.10.2018 08:01, Bin Meng wrote:
>>> Hi Hannes,
>> Hi Bing,
>> thanks for very quick response on this.
>>> On Thu, Oct 11, 2018 at 1:45 PM Hannes Schmelzer
>>> <hannes.schmelzer@br-automation.com> wrote:
>>>> If we're booting some u-boot module with compressed payload, we have to
>>>> use the pointer where the image really has been loaded (unzipped) to
>>>> instead the pointer to the payload of the u-boot module.
>>>>
>>>> Signed-off-by: Hannes Schmelzer <hannes.schmelzer@br-automation.com>
>>>> ---
>>>>
>>>>    arch/x86/lib/bootm.c | 4 ++--
>>>>    1 file changed, 2 insertions(+), 2 deletions(-)
>>>>
>>> Can you describe with what reproduce steps current codes are failing? thanks!
>> The boot of a u-boot module with bootm walks like this:
>>
>> => bootm ${loadaddr} ${ramdisk} ${fdtcontroladdr}
>> this leads to call (coming through cmd/bootm.c) to "do_bootm_states".
>> The task of this "do_bootm_states" is to find out what todo with the
>> provided image (u-boot module),
>> is it compressed or not, which kind of os should be booted, ...
>>
>> So, for doing this work, "bootm_decomp_image" is called,
>> this function uses the image-header for finding out the compression
>> method and does decompress the real payload to some location.
>>
>> bootm_os_load moves on and finds out that some compressed linux payload
>> shall be booted.
>> So the "do_bootm_linux" and finally "boot_prep_linux" from lib/x86,
>> since wer'e actually running on a x86 machine, is called.
>>
>> This function makes the assumption that the bootable binary is directly
>> the payload of the u-boot module,
>> ignoring the work done by "bootm_decomp_image" during the step before
>> and tries to boot directly in my case a gzip binary.
>>
>> This is wrong.
>>
> Thanks for the explanation. This patch looks good to me.
>
> However I was unable to proceed some testing to verify this.
>
> When I use 'bootm' to boot a uImage with uncompressed bzImage, I simply get:
>
> => bootm 2000000 3000000
> ## Booting kernel from Legacy Image at 02000000 ...
>     Image Name:   linux
>     Created:      2018-11-20  15:23:19 UTC
>     Image Type:   Intel x86 Linux Kernel Image (uncompressed)
>     Data Size:    7716768 Bytes = 7.4 MiB
>     Load Address: 01000000
>     Entry Point:  01000000
>     Verifying Checksum ... OK
> Could not find a valid setup.bin for x86
>
> It looks the error message comes from boot_get_setup() which expects
> bootm payload is of FIT format. However this patch expects a uImage
> with legacy format (images->legacy_hdr_valid == true).
>
> Can you please post your complete instructions, including how to
> create uImage for U-Boot's bootm work for legacy booting?
Yes, i create the u-boot module by hand for testing with:

gzip -9 bzImage (which doesn't much because the bzImage already contains 
compressed stuff)
mkimage -A x86 -O linux -e 100000 -a 100000 -d bzImage.gz -c gzip ulinux

afterwards i load the created 'ulinux' to my target and boot:

=> tftp ${loadaddr} ulinux
Using e1000#0 device
TFTP from server 192.168.21.254; our IP address is 192.168.21.70
Filename 'ulinux'.
Load address: 0x121a1000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
###############################################################
          8.9 MiB/s
done
Bytes transferred = 7597600 (73ee20 hex)
=> bootm ${loadaddr} - ${fdtcontroladdr}
## Booting kernel from Legacy Image at 121a1000 ...
    Image Name:
    Created:      2018-11-21   8:23:30 UTC
    Image Type:   Intel x86 Linux Kernel Image (gzip compressed)
    Data Size:    7597536 Bytes = 7.2 MiB
    Load Address: 00100000
    Entry Point:  00100000
    Verifying Checksum ... OK
## Flattened Device Tree blob at 7f2fe240
    Booting using the fdt blob at 0x7f2fe240
    Uncompressing Kernel Image ... OK
    Loading Device Tree to 0007a000, end 0007f166 ... OK
Valid Boot Flag
Setup Size = 0x00003e00
Magic signature found
Using boot protocol version 2.0e
Linux kernel version 4.20.0-rc3+ (schmelzerh@ategge3722) #1 SMP Wed Nov 
21 09:03:31 CET 2018
Building boot_params at 0x00090000
Loading bzImage at address 100000 (7703104 bytes)
Setup at 0x090000
Magic signature found
Kernel command line: "gei(0,0)host:vxWorks h=192.168.60.254 
e=192.168.60.1:255.255.255.0 g=192.168.60.254 u=vxWorksFTP pw=vxWorks"
Magic signature found

Starting kernel ...

--
this was just for testing this with a linux kernel. In real life on my 
target a vxWorks kernel is running.
My vxWorks 6.9 kernel also has the zero-page in front of the image and 
is booted in the same manner.
>
> Regards,
> Bin
cheers,
Hannes
Bin Meng Nov. 24, 2018, 3:30 p.m. UTC | #5
Hi Hannes,

On Fri, Nov 23, 2018 at 2:50 PM Hannes Schmelzer <hannes@schmelzer.or.at> wrote:
>
>
>
> On 20.11.2018 16:34, Bin Meng wrote:
> > Hi Hannes,
> Hi Bin,
> thanks for having a look into and sorry for my late response.
>
> >
> > On Thu, Oct 11, 2018 at 2:41 PM Hannes Schmelzer <hannes@schmelzer.or.at> wrote:
> >>
> >> On 11.10.2018 08:01, Bin Meng wrote:
> >>> Hi Hannes,
> >> Hi Bing,
> >> thanks for very quick response on this.
> >>> On Thu, Oct 11, 2018 at 1:45 PM Hannes Schmelzer
> >>> <hannes.schmelzer@br-automation.com> wrote:
> >>>> If we're booting some u-boot module with compressed payload, we have to
> >>>> use the pointer where the image really has been loaded (unzipped) to
> >>>> instead the pointer to the payload of the u-boot module.
> >>>>
> >>>> Signed-off-by: Hannes Schmelzer <hannes.schmelzer@br-automation.com>
> >>>> ---
> >>>>
> >>>>    arch/x86/lib/bootm.c | 4 ++--
> >>>>    1 file changed, 2 insertions(+), 2 deletions(-)
> >>>>
> >>> Can you describe with what reproduce steps current codes are failing? thanks!
> >> The boot of a u-boot module with bootm walks like this:
> >>
> >> => bootm ${loadaddr} ${ramdisk} ${fdtcontroladdr}
> >> this leads to call (coming through cmd/bootm.c) to "do_bootm_states".
> >> The task of this "do_bootm_states" is to find out what todo with the
> >> provided image (u-boot module),
> >> is it compressed or not, which kind of os should be booted, ...
> >>
> >> So, for doing this work, "bootm_decomp_image" is called,
> >> this function uses the image-header for finding out the compression
> >> method and does decompress the real payload to some location.
> >>
> >> bootm_os_load moves on and finds out that some compressed linux payload
> >> shall be booted.
> >> So the "do_bootm_linux" and finally "boot_prep_linux" from lib/x86,
> >> since wer'e actually running on a x86 machine, is called.
> >>
> >> This function makes the assumption that the bootable binary is directly
> >> the payload of the u-boot module,
> >> ignoring the work done by "bootm_decomp_image" during the step before
> >> and tries to boot directly in my case a gzip binary.
> >>
> >> This is wrong.
> >>
> > Thanks for the explanation. This patch looks good to me.
> >
> > However I was unable to proceed some testing to verify this.
> >
> > When I use 'bootm' to boot a uImage with uncompressed bzImage, I simply get:
> >
> > => bootm 2000000 3000000
> > ## Booting kernel from Legacy Image at 02000000 ...
> >     Image Name:   linux
> >     Created:      2018-11-20  15:23:19 UTC
> >     Image Type:   Intel x86 Linux Kernel Image (uncompressed)
> >     Data Size:    7716768 Bytes = 7.4 MiB
> >     Load Address: 01000000
> >     Entry Point:  01000000
> >     Verifying Checksum ... OK
> > Could not find a valid setup.bin for x86
> >
> > It looks the error message comes from boot_get_setup() which expects
> > bootm payload is of FIT format. However this patch expects a uImage
> > with legacy format (images->legacy_hdr_valid == true).
> >
> > Can you please post your complete instructions, including how to
> > create uImage for U-Boot's bootm work for legacy booting?
> Yes, i create the u-boot module by hand for testing with:
>
> gzip -9 bzImage (which doesn't much because the bzImage already contains
> compressed stuff)
> mkimage -A x86 -O linux -e 100000 -a 100000 -d bzImage.gz -c gzip ulinux
>
> afterwards i load the created 'ulinux' to my target and boot:
>
> => tftp ${loadaddr} ulinux
> Using e1000#0 device
> TFTP from server 192.168.21.254; our IP address is 192.168.21.70
> Filename 'ulinux'.
> Load address: 0x121a1000
> Loading: #################################################################
> #################################################################
> #################################################################
> #################################################################
> #################################################################
> #################################################################
> #################################################################
> ###############################################################
>           8.9 MiB/s
> done
> Bytes transferred = 7597600 (73ee20 hex)
> => bootm ${loadaddr} - ${fdtcontroladdr}
> ## Booting kernel from Legacy Image at 121a1000 ...
>     Image Name:
>     Created:      2018-11-21   8:23:30 UTC
>     Image Type:   Intel x86 Linux Kernel Image (gzip compressed)
>     Data Size:    7597536 Bytes = 7.2 MiB
>     Load Address: 00100000
>     Entry Point:  00100000
>     Verifying Checksum ... OK
> ## Flattened Device Tree blob at 7f2fe240
>     Booting using the fdt blob at 0x7f2fe240
>     Uncompressing Kernel Image ... OK
>     Loading Device Tree to 0007a000, end 0007f166 ... OK
> Valid Boot Flag
> Setup Size = 0x00003e00
> Magic signature found
> Using boot protocol version 2.0e
> Linux kernel version 4.20.0-rc3+ (schmelzerh@ategge3722) #1 SMP Wed Nov
> 21 09:03:31 CET 2018
> Building boot_params at 0x00090000
> Loading bzImage at address 100000 (7703104 bytes)
> Setup at 0x090000
> Magic signature found
> Kernel command line: "gei(0,0)host:vxWorks h=192.168.60.254
> e=192.168.60.1:255.255.255.0 g=192.168.60.254 u=vxWorksFTP pw=vxWorks"
> Magic signature found
>
> Starting kernel ...
>
> --
> this was just for testing this with a linux kernel. In real life on my
> target a vxWorks kernel is running.
> My vxWorks 6.9 kernel also has the zero-page in front of the image and
> is booted in the same manner.

Using exact the same instructions as you used, I still got the "Could
not find a valid setup.bin for x86" error message. Did you test this
on top of u-boot/master?

Regards,
Bin
diff mbox series

Patch

diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c
index 54c22fe..4102bcb 100644
--- a/arch/x86/lib/bootm.c
+++ b/arch/x86/lib/bootm.c
@@ -94,8 +94,8 @@  static int boot_prep_linux(bootm_headers_t *images)
 			len = os_len;
 		} else {
 			/* otherwise get image data */
-			data = (void *)image_get_data(hdr);
-			len = image_get_data_size(hdr);
+			data = (void *)images->os.load;
+			len = 0;
 		}
 		is_zimage = 1;
 #if defined(CONFIG_FIT)