cancel
Showing results for 
Search instead for 
Did you mean: 

Kernel load address when using FIT images

Grodriguez
Senior

Hi all,

I am trying to switch to using FIT images and I am looking at the example .its file here:

https://github.com/STMicroelectronics/u-boot/blob/0e6522cbd1bfccd7281acdf8ab5ebbd37d29eab1/board/st/stm32mp1/fit_kernel_dtb.its

I am trying to understand why 0xC0008000 is used for the load address/entry point. If I understand correctly:

  1. By default, U-boot will load the FIT image to address 0xC2000000
  2. Then it will copy the kernel image to load address 0xC0008000, and jump to it
  3. The kernel image needs to decompress itself to final address 0xC0008000; however since the entry point of the zImage is 0xC0008000, it will need to relocate itself first to some address which is higher than (0xC0008000 + uncompressed kernel length)
  4. And then finally decompress to final location 0xC0008000

Wouldn't it be possible to skip the relocation in step 3 by choosing a different address for the load address/entry point in the FIT image?

Thanks,

Guillermo

1 ACCEPTED SOLUTION

Accepted Solutions
PatrickD
ST Employee

Hi,

when I test FIT, I experiment Image (with or without compression)  and zImage.

And when I upstream the patch, I let the value  0xC0008000 required for "Image" (kernel image without embedded decompression).

With zImage it is working but the kernel decompression need to move the kernel code before decompression at final address 0xC0008000.

A good choice to load zImage is 0xC4000000.

It is aligned with "fdt_addr_r=0xc4000000" in stm32mp1.h to allow 32MB kernel image, so it will work with 32MB FIT.

You have 3 solution it is possible to avoid relocation during decompression:

1/ load Zimage at correct location = 0xC4000000

kernel {

description = "Linux kernel";

data = /incbin/("zImage");

type = "kernel";

arch = "arm";

os = "linux";

compression = "none";

load = <0xC4000000>;

entry = <0xC4000000>;

hash-1 {

algo = "sha1";

};

};

2/ use Image.gz , lets U-Boot decompress the kenel = "Image" at the correcct location (it is my preferred solution that avoid the first copy)

kernel {

description = "Linux kernel";

data = /incbin/("Image.gz");

type = "kernel";

arch = "arm";

os = "linux";

compression = "gzip";

load = <0xC0008000>;

entry = <0xC0008000>;

hash-1 {

algo = "sha1";

};

};

3/ use zImage in place (inside the FIP) : with 0xCC offset in my example but this offset depends on FIT content so it is less flexible

  kernel {

   description = "Linux kernel";

   data = /incbin/("zImage");

   type = "kernel";

   arch = "arm";

   os = "linux";

   compression = "none";

   load = <0xC20000cc>;

   entry = <0xC20000cc>;

   hash-1 {

   algo = "sha1";

   };

  };

Or you can used uncomprressed kernel: "Image" (time with decompression need to be chacked)

kernel {

description = "Linux kernel";

data = /incbin/("Image");

type = "kernel";

arch = "arm";

os = "linux";

compression = "none";

load = <0xC0008000>;

entry = <0xC0008000>;

hash-1 {

algo = "sha1";

};

};

Regards

Patrick

View solution in original post

2 REPLIES 2
PatrickD
ST Employee

Hi,

when I test FIT, I experiment Image (with or without compression)  and zImage.

And when I upstream the patch, I let the value  0xC0008000 required for "Image" (kernel image without embedded decompression).

With zImage it is working but the kernel decompression need to move the kernel code before decompression at final address 0xC0008000.

A good choice to load zImage is 0xC4000000.

It is aligned with "fdt_addr_r=0xc4000000" in stm32mp1.h to allow 32MB kernel image, so it will work with 32MB FIT.

You have 3 solution it is possible to avoid relocation during decompression:

1/ load Zimage at correct location = 0xC4000000

kernel {

description = "Linux kernel";

data = /incbin/("zImage");

type = "kernel";

arch = "arm";

os = "linux";

compression = "none";

load = <0xC4000000>;

entry = <0xC4000000>;

hash-1 {

algo = "sha1";

};

};

2/ use Image.gz , lets U-Boot decompress the kenel = "Image" at the correcct location (it is my preferred solution that avoid the first copy)

kernel {

description = "Linux kernel";

data = /incbin/("Image.gz");

type = "kernel";

arch = "arm";

os = "linux";

compression = "gzip";

load = <0xC0008000>;

entry = <0xC0008000>;

hash-1 {

algo = "sha1";

};

};

3/ use zImage in place (inside the FIP) : with 0xCC offset in my example but this offset depends on FIT content so it is less flexible

  kernel {

   description = "Linux kernel";

   data = /incbin/("zImage");

   type = "kernel";

   arch = "arm";

   os = "linux";

   compression = "none";

   load = <0xC20000cc>;

   entry = <0xC20000cc>;

   hash-1 {

   algo = "sha1";

   };

  };

Or you can used uncomprressed kernel: "Image" (time with decompression need to be chacked)

kernel {

description = "Linux kernel";

data = /incbin/("Image");

type = "kernel";

arch = "arm";

os = "linux";

compression = "none";

load = <0xC0008000>;

entry = <0xC0008000>;

hash-1 {

algo = "sha1";

};

};

Regards

Patrick

Grodriguez
Senior

Hi @Community member​

Perfectly clear, thank you.

It is a pity that for option 3 (run zImage in place) one needs to manually calculate the load/entry addresses since, as you say, these addresses depend on the content of the FIT image. It would be great if mkimage had an option for this.

I agree that option 2 should be the fastest.

Thank you,

Guillermo