[U-Boot] [PATCH] tools: make imxheader size align on page size

From: Stefan Agner stefan@agner.ch
The i.MX V2 headers total size is 0x7fc. The header is placed in front of the U-Boot binary which of course is aligned to text base. Hence the header starting point is not page aligned (e.g. at 0x3f400404). This is still a valid header, which boots fine using serial loader. However, the image fails to boot from NAND (tested on a VF61x SoC).
Most parts of the header have a length of a multiply of 16 bytes.The rest of the header is filled with 8 bytes long DCD data. Only the boot data header is 3 word long (12 bytes).
This patch makes sure the whole image is exactly 0x800 by adding one padding word after the boot data header. Since the individual data structures are referenced by pointers, this still results in a valid i.MX V2 header while maintaining page alignment.
Signed-off-by: Stefan Agner stefan@agner.ch --- I'm not 100% sure wheather this is the right approach solving this issue. This works for me, also tested with DCD data.
tools/imximage.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/tools/imximage.h b/tools/imximage.h index 01f861e..b596fb1 100644 --- a/tools/imximage.h +++ b/tools/imximage.h @@ -149,6 +149,7 @@ typedef struct { typedef struct { flash_header_v2_t fhdr; boot_data_t boot_data; + uint32_t reserved1; dcd_v2_t dcd_table; } imx_header_v2_t;

Hi Stefan,
On 16/04/2014 15:29, stefan@agner.ch wrote:
From: Stefan Agner stefan@agner.ch
The i.MX V2 headers total size is 0x7fc. The header is placed in front of the U-Boot binary which of course is aligned to text base. Hence the header starting point is not page aligned (e.g. at 0x3f400404). This is still a valid header, which boots fine using serial loader. However, the image fails to boot from NAND (tested on a VF61x SoC).
Can you better explain this ? There is only one board in mainline with vf610. CONFIG_SYS_TEXT_BASE is set to 0x3f008000. I cannot get the offset in your example. Are you referring to NAND page ? But if the header must be aligned with the NAND page, this is pretty bad because we have to adjust the header depending on the selected NAND chip. I do not see this limitation in the manual.
You have also added FCB to the image to flash into the NAND. Are you sure that everything is fine there ?
As feeling, it seems that adding this integer you move the limit and you constraint the SOC to read more data as before.
Most parts of the header have a length of a multiply of 16 bytes.The rest of the header is filled with 8 bytes long DCD data.
I do not understand this phrase. The header is mainly composed by 32 bit fields. See the structure dcd_addr_data_t.
Only the boot data header is 3 word long (12 bytes).
/ivt_header>
ivt_header is defined as 32bit integer. What are you meaning here with boot data header ?
This patch makes sure the whole image is exactly 0x800 by adding one padding word after the boot data header. Since the individual data structures are referenced by pointers, this still results in a valid i.MX V2 header while maintaining page alignment.
Signed-off-by: Stefan Agner stefan@agner.ch
I'm not 100% sure wheather this is the right approach solving this issue. This works for me, also tested with DCD data.
tools/imximage.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/tools/imximage.h b/tools/imximage.h index 01f861e..b596fb1 100644 --- a/tools/imximage.h +++ b/tools/imximage.h @@ -149,6 +149,7 @@ typedef struct { typedef struct { flash_header_v2_t fhdr; boot_data_t boot_data;
- uint32_t reserved1; dcd_v2_t dcd_table;
} imx_header_v2_t;
The patch does not clarify the issue. It hides the problem, because adding this additional place you can boot your board, but without really understand why. What does it happen if you add additional fields before dcd_table ? If it continues to work, the header must not be aligned with the NAND page. But again, doing this, let the SOC reading more bytes as it does without this fix.
Best regards, Stefano Babic

Hi Stefano,
Am 2014-04-16 17:44, schrieb Stefano Babic:
On 16/04/2014 15:29, stefan@agner.ch wrote:
From: Stefan Agner stefan@agner.ch
The i.MX V2 headers total size is 0x7fc. The header is placed in front of the U-Boot binary which of course is aligned to text base. Hence the header starting point is not page aligned (e.g. at 0x3f400404). This is still a valid header, which boots fine using serial loader. However, the image fails to boot from NAND (tested on a VF61x SoC).
Can you better explain this ? There is only one board in mainline with vf610. CONFIG_SYS_TEXT_BASE is set to 0x3f008000. I cannot get the offset in your example. Are you referring to NAND page ? But if the header must be aligned with the NAND page, this is pretty bad because we have to adjust the header depending on the selected NAND chip. I do not see this limitation in the manual.
I've not submitted my board yet, I altered it to use 0x3f400800 as CONFIG_SYS_TEXT_BASE. I just realize that a header length of 0x7fc doesn't fit with 0x3f400404 even though (that would be 0x3f400004 if anything). But the mkimage utility reports Load Address: 3f400420 Entry Point: 3f400800 I'm a bit confused now, why is the header only 0x400 now?
You have also added FCB to the image to flash into the NAND. Are you sure that everything is fine there ?
As feeling, it seems that adding this integer you move the limit and you constraint the SOC to read more data as before.
Well, I use downstream U-Boot to create a FCB. Thats why I use 0x3f400800 as text base, so those two U-Boots are aligned. I only flashed Mainline U-Boot (leaving FCB as is) and thats when I detected this issue: Diffing the IVT headers I found out that downstream was aligned to 0x400 while mainline was not.
Quite possible that an altered/correct FCB would actually work. But speaking about FCB, is there already something for Vybrid? I'm currently try to create an Image with FCB+IVT V2 header using the mxsboot utility, which seems to create a similar FCB. However it doesn't worked in a first try, there seem to be some subtle but relevant differences...
Most parts of the header have a length of a multiply of 16 bytes.The rest of the header is filled with 8 bytes long DCD data.
I do not understand this phrase. The header is mainly composed by 32 bit fields. See the structure dcd_addr_data_t.
Only the boot data header is 3 word long (12 bytes).
/ivt_header>
ivt_header is defined as 32bit integer. What are you meaning here with boot data header ?
By boot data header I mean boot_data_t. The whole structure is filled by the DCD table using an array of 121 dcd_addr_data_t. Since sizeof(dcd_addr_data_t) == 8, the whole structure is not nicely filled to be exactly 0x800...
This patch makes sure the whole image is exactly 0x800 by adding one padding word after the boot data header. Since the individual data structures are referenced by pointers, this still results in a valid i.MX V2 header while maintaining page alignment.
Signed-off-by: Stefan Agner stefan@agner.ch
I'm not 100% sure wheather this is the right approach solving this issue. This works for me, also tested with DCD data.
tools/imximage.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/tools/imximage.h b/tools/imximage.h index 01f861e..b596fb1 100644 --- a/tools/imximage.h +++ b/tools/imximage.h @@ -149,6 +149,7 @@ typedef struct { typedef struct { flash_header_v2_t fhdr; boot_data_t boot_data;
- uint32_t reserved1; dcd_v2_t dcd_table;
} imx_header_v2_t;
The patch does not clarify the issue. It hides the problem, because adding this additional place you can boot your board, but without really understand why. What does it happen if you add additional fields before dcd_table ? If it continues to work, the header must not be aligned with the NAND page. But again, doing this, let the SOC reading more bytes as it does without this fix.
Ok, in the end this actually seems not to be an issue at all, more a unfortunate circumstance.
-- Stefan

Am 2014-04-16 15:17, schrieb Stefan Agner:
Hi Stefano,
Am 2014-04-16 17:44, schrieb Stefano Babic:
On 16/04/2014 15:29, stefan@agner.ch wrote:
From: Stefan Agner stefan@agner.ch
The i.MX V2 headers total size is 0x7fc. The header is placed in front of the U-Boot binary which of course is aligned to text base. Hence the header starting point is not page aligned (e.g. at 0x3f400404). This is still a valid header, which boots fine using serial loader. However, the image fails to boot from NAND (tested on a VF61x SoC).
Can you better explain this ? There is only one board in mainline with vf610. CONFIG_SYS_TEXT_BASE is set to 0x3f008000. I cannot get the offset in your example. Are you referring to NAND page ? But if the header must be aligned with the NAND page, this is pretty bad because we have to adjust the header depending on the selected NAND chip. I do not see this limitation in the manual.
I've not submitted my board yet, I altered it to use 0x3f400800 as CONFIG_SYS_TEXT_BASE. I just realize that a header length of 0x7fc doesn't fit with 0x3f400404 even though (that would be 0x3f400004 if anything). But the mkimage utility reports Load Address: 3f400420 Entry Point: 3f400800 I'm a bit confused now, why is the header only 0x400 now?
Ok I checked this again, the header total size is _not_ 0x7fc, thats imximage_init_loadsize, which is the header size + flash load size (0x400 for NAND).
The header total size is 0x3fc (sizeof(imx_header_v2_t)) right now. This patch would make alter it to be exactly 0x400.
In case this discussion ends up adding this padding word, I will send a new patch with correct numbers and better description.

Hi Stefan,
On 16/04/2014 15:36, Stefan Agner wrote:
Can you better explain this ? There is only one board in mainline with vf610. CONFIG_SYS_TEXT_BASE is set to 0x3f008000. I cannot get the offset in your example. Are you referring to NAND page ? But if the header must be aligned with the NAND page, this is pretty bad because we have to adjust the header depending on the selected NAND chip. I do not see this limitation in the manual.
I've not submitted my board yet, I altered it to use 0x3f400800 as CONFIG_SYS_TEXT_BASE. I just realize that a header length of 0x7fc doesn't fit with 0x3f400404 even though (that would be 0x3f400004 if anything). But the mkimage utility reports Load Address: 3f400420 Entry Point: 3f400800 I'm a bit confused now, why is the header only 0x400 now?
Ok I checked this again, the header total size is _not_ 0x7fc, thats imximage_init_loadsize, which is the header size + flash load size (0x400 for NAND).
The header total size is 0x3fc (sizeof(imx_header_v2_t)) right now. This patch would make alter it to be exactly 0x400.
This renforces my suspect. Making the image bigger, it seems that the SOC loads more data as before.
However, reading in the manual, the initial load image (what the SOC should load initially) is 4K (Table 19.37), and adding 4 bytes should have no influence.
In case this discussion ends up adding this padding word, I will send a new patch with correct numbers and better description.
It is not clear what is the cause of the issue and then which is the solution. Adding the pad at the moment seems only a work-around for you.
Best regards, Stefano Babic

Hi Stefano,
Am 2014-04-17 10:50, schrieb Stefano Babic:
On 16/04/2014 15:36, Stefan Agner wrote:
Can you better explain this ? There is only one board in mainline with vf610. CONFIG_SYS_TEXT_BASE is set to 0x3f008000. I cannot get the offset in your example. Are you referring to NAND page ? But if the header must be aligned with the NAND page, this is pretty bad because we have to adjust the header depending on the selected NAND chip. I do not see this limitation in the manual.
I've not submitted my board yet, I altered it to use 0x3f400800 as CONFIG_SYS_TEXT_BASE. I just realize that a header length of 0x7fc doesn't fit with 0x3f400404 even though (that would be 0x3f400004 if anything). But the mkimage utility reports Load Address: 3f400420 Entry Point: 3f400800 I'm a bit confused now, why is the header only 0x400 now?
Ok I checked this again, the header total size is _not_ 0x7fc, thats imximage_init_loadsize, which is the header size + flash load size (0x400 for NAND).
The header total size is 0x3fc (sizeof(imx_header_v2_t)) right now. This patch would make alter it to be exactly 0x400.
This renforces my suspect. Making the image bigger, it seems that the SOC loads more data as before.
However, reading in the manual, the initial load image (what the SOC should load initially) is 4K (Table 19.37), and adding 4 bytes should have no influence.
I'm still trying to figure out what the real problem is here. I could not alter the FCB to boot the default IMX V2 image (with IVT header). Inside the FCB one can only specify the page offset where the image starts. Within that page, the Boot ROM expects a IVT header at exactly 0x400. However, on NAND, the IVT header _is_ exactly at 0x400.
I also think the Boot ROM can read the IVT header but the jump to the entry point of U-Boot fails somehow. If the IVT header is not correct, the Boot ROM usually enters serial loader, in my case this doesn't happen. I have no JTAG environment ready, so I can't easily debug this.
I also try shorter versions of the IVT header by alter the dcd_addr_data_t array inside dcd_v2_t. interesting is, that a total length of 0x3f8 works, while 0x3fc or 0x3f4 do not work.
In case this discussion ends up adding this padding word, I will send a new patch with correct numbers and better description.
It is not clear what is the cause of the issue and then which is the solution. Adding the pad at the moment seems only a work-around for you.
For me it seems as if Vybrid requires the header base in memory requires to be at 8 byte boundary. Probably there is also a nicer solution enforce this rather than just extend the struct.
-- Stefan

Hi Stefan,
On 23/04/2014 04:34, Stefan Agner wrote:
The header total size is 0x3fc (sizeof(imx_header_v2_t)) right now. This patch would make alter it to be exactly 0x400.
This renforces my suspect. Making the image bigger, it seems that the SOC loads more data as before.
However, reading in the manual, the initial load image (what the SOC should load initially) is 4K (Table 19.37), and adding 4 bytes should have no influence.
I'm still trying to figure out what the real problem is here. I could not alter the FCB to boot the default IMX V2 image (with IVT header). Inside the FCB one can only specify the page offset where the image starts. Within that page, the Boot ROM expects a IVT header at exactly 0x400. However, on NAND, the IVT header _is_ exactly at 0x400.
I also think the Boot ROM can read the IVT header but the jump to the entry point of U-Boot fails somehow. If the IVT header is not correct, the Boot ROM usually enters serial loader, in my case this doesn't happen. I have no JTAG environment ready, so I can't easily debug this.
That is true - another possible cause could be that for some unknown reason to us, the IVT header is read but reading the whole U-Boot image fails.
We could also know if the IVT header is read and parsed correctly if the DRAM controller is set up even when boot fails. That means that the DCD data is read and applied. Rather I have no idea how to proof this without a JTAG debugger.
I also try shorter versions of the IVT header by alter the dcd_addr_data_t array inside dcd_v2_t. interesting is, that a total length of 0x3f8 works, while 0x3fc or 0x3f4 do not work.
Strange enough - sure I have seen not 8-byte alignment on other i.MXes.
In case this discussion ends up adding this padding word, I will send a new patch with correct numbers and better description.
It is not clear what is the cause of the issue and then which is the solution. Adding the pad at the moment seems only a work-around for you.
For me it seems as if Vybrid requires the header base in memory requires to be at 8 byte boundary. Probably there is also a nicer solution enforce this rather than just extend the struct.
Have you tried to ask Freescale about this issue ? It is quite strage and it seems Vybrid-related.
Best regards, Stefano Babic

Hi Stefano,
Am 2014-04-23 17:19, schrieb Stefano Babic:
Hi Stefan,
On 23/04/2014 04:34, Stefan Agner wrote:
The header total size is 0x3fc (sizeof(imx_header_v2_t)) right now. This patch would make alter it to be exactly 0x400.
This renforces my suspect. Making the image bigger, it seems that the SOC loads more data as before.
However, reading in the manual, the initial load image (what the SOC should load initially) is 4K (Table 19.37), and adding 4 bytes should have no influence.
I'm still trying to figure out what the real problem is here. I could not alter the FCB to boot the default IMX V2 image (with IVT header). Inside the FCB one can only specify the page offset where the image starts. Within that page, the Boot ROM expects a IVT header at exactly 0x400. However, on NAND, the IVT header _is_ exactly at 0x400.
I also think the Boot ROM can read the IVT header but the jump to the entry point of U-Boot fails somehow. If the IVT header is not correct, the Boot ROM usually enters serial loader, in my case this doesn't happen. I have no JTAG environment ready, so I can't easily debug this.
That is true - another possible cause could be that for some unknown reason to us, the IVT header is read but reading the whole U-Boot image fails.
We could also know if the IVT header is read and parsed correctly if the DRAM controller is set up even when boot fails. That means that the DCD data is read and applied. Rather I have no idea how to proof this without a JTAG debugger.
FYI, on Vybrid, there is enough internal RAM for U-Boot. I don't have to use a DCD table to setup the DRAM controller.
I also try shorter versions of the IVT header by alter the dcd_addr_data_t array inside dcd_v2_t. interesting is, that a total length of 0x3f8 works, while 0x3fc or 0x3f4 do not work.
Strange enough - sure I have seen not 8-byte alignment on other i.MXes.
I forgot to mention: This issue is _only_ when booting from NAND. I can load and run the very same image using serial loader (over USB or UART). The JUMP command that the serial loader sends at the end jumps to ...404 (IVT Header start in Memory). Also booting from SD-Card works with all images.
This isolates the problem to the "NAND image loader" part of the ROM. The fact that Vybrid's NAND peripheral is not the same as on other i.MXes goes well with that assumption too (since other i.MXes don't have that limitation).
In case this discussion ends up adding this padding word, I will send a new patch with correct numbers and better description.
It is not clear what is the cause of the issue and then which is the solution. Adding the pad at the moment seems only a work-around for you.
For me it seems as if Vybrid requires the header base in memory requires to be at 8 byte boundary. Probably there is also a nicer solution enforce this rather than just extend the struct.
Have you tried to ask Freescale about this issue ? It is quite strage and it seems Vybrid-related.
No not yet. I need to setup an example. However, in the end they will not change the ROM anyway, especially not on Vybrids already delivered ;-)
-- Stefan

Hi Stefan,
On 23/04/2014 11:55, Stefan Agner wrote:
Have you tried to ask Freescale about this issue ? It is quite strage and it seems Vybrid-related.
No not yet. I need to setup an example. However, in the end they will not change the ROM anyway, especially not on Vybrids already delivered ;-)
Of course, they won't do. Anyway, we need to identify exactly the problem and its cause, If Freescale will confirm that Vybrid needs a 8-byte alignment for NAND booting, we are sure that this can be a fix and we are not hiding the real cause.
Best regards, Stefano

Hi Stefan,
On 16/04/2014 15:17, Stefan Agner wrote:
Quite possible that an altered/correct FCB would actually work. But speaking about FCB, is there already something for Vybrid? I'm currently try to create an Image with FCB+IVT V2 header using the mxsboot utility,
mxsboot is not the right tool.
There are some discussion about this some time ago. The best thing is that mkimage can be improved to add the FCB when the image is generated. As far as I know, nobody has started to develop it - patches are welcome, if you decide to do it ;-)
Best regards, Stefano Babic
participants (3)
-
Stefan Agner
-
stefan@agner.ch
-
Stefano Babic