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

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(-)
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)

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

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

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

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

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
participants (3)
-
Bin Meng
-
Hannes Schmelzer
-
Hannes Schmelzer