iMX8QXP NOR Flash Secondary Boot Container Set

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

iMX8QXP NOR Flash Secondary Boot Container Set

Jump to solution
987 Views
mwso_soe
Contributor II

I have an iMX8X iMX8QXP that I am trying to set the secondary boot container set on NOR Flash (and eventually eMMC). I am trying to verify the basic functionality before burning any of the OTP fuses so this is currently how I have my NOR flash partitioned

AddressSizeNameDescription
0x000000004MBboot0imx-boot-fspi.bin-flash_spl_flexspi
0x004000004MBboot1imx-boot-fspi.bin-flash_spl_flexspi
0x0080000064KBenv0u-boot env0
0x0081000064KBenv1u-boot env1
0x00820000(rest of flash)ubi

ubi (rootfs)

 

I am referencing IMX8DQXPRM.pdf and this is what I have:

  • OTP fuse row index 720 is set to 0, so Image Container Set1 offset is 4MB (1MB*2^2)
  • All OTP fuses are at their factory results
  • BOOT_MODE[0] = 0
  • BOOT_MODE[1] = 1
  • BOOT_MODE[2] = 1
  • BOOT_MODE[3] = 0

When I erase the `boot0` partition of my NOR flash, the iMX8 does not boot to the boot1 partition as I expect. Instead, the boot console remains blank and nothing happens. I am not sure what other steps I am missing, or if I am not testing this correctly.

0 Kudos
1 Solution
962 Views
seb_haezebrouck
NXP Employee
NXP Employee

Hi @mwso_soe ,

The i.MX8QXP boot ROM will always look for its SPINOR configuration block at offset 0x400 in the NOR flash. The primary container set starts at 0x1000.

If you fully erased everything in SPINOR between 0x0 and 0x3FFFFF, you lost the configuration block and the device cannot boot anymore from SPINOR. You should not touch the part between 0x400 and 0x5FF - as this is where the configuration block is stored. For your trial, please erase the flash starting from 0x1000 - this is where the container set is stored. See the i.MX8QXP reference manual, section 5.8.3.3 and 5.9.3 for more details. You can "see" the configuration block by opening the imx-boot-fspi.bin-flash_spl_flexspi file in an hex editor and checking offset 0x400. It should start with "FCFB" ASCII.

Note that the secondary container set can have the same format as the first one, with a configuration block at offset 0x00400400. The ROM code will ignore the second configuration block and try and boot the actual container from offset 0x00401000 (assuming default fusing for 2nd container offset). So burning imx-boot-fspi.bin-flash_spl_flexspi at offset 0x400000 should work just fine.

Best regards.

 

View solution in original post

0 Kudos
8 Replies
963 Views
seb_haezebrouck
NXP Employee
NXP Employee

Hi @mwso_soe ,

The i.MX8QXP boot ROM will always look for its SPINOR configuration block at offset 0x400 in the NOR flash. The primary container set starts at 0x1000.

If you fully erased everything in SPINOR between 0x0 and 0x3FFFFF, you lost the configuration block and the device cannot boot anymore from SPINOR. You should not touch the part between 0x400 and 0x5FF - as this is where the configuration block is stored. For your trial, please erase the flash starting from 0x1000 - this is where the container set is stored. See the i.MX8QXP reference manual, section 5.8.3.3 and 5.9.3 for more details. You can "see" the configuration block by opening the imx-boot-fspi.bin-flash_spl_flexspi file in an hex editor and checking offset 0x400. It should start with "FCFB" ASCII.

Note that the secondary container set can have the same format as the first one, with a configuration block at offset 0x00400400. The ROM code will ignore the second configuration block and try and boot the actual container from offset 0x00401000 (assuming default fusing for 2nd container offset). So burning imx-boot-fspi.bin-flash_spl_flexspi at offset 0x400000 should work just fine.

Best regards.

 

0 Kudos
959 Views
mwso_soe
Contributor II

Hi @seb_haezebrouck,

Thank you for this information, this was incredibly helpful! I was struggling to understand this from the reference manual.

I erased the first boot container set from u-boot by running:
`sf probe`
`sf erase 0x10000 0x30000`

(I had to start at offset 0x10000 because when I run `mtd list` my block size is 0x10000 bytes)

Now U-Boot is loaded from the secondary set (Per the serial log from the SPL "Secondary set selected")

Now I have a new issue that I need to troubleshoot, the SPL gives the following error:

"Wrong container headerSPL: failed to boot from all boot devices"

This appears to come from `read_auth_container()` in `parse-container.c` in `/arch/arm/mach-imx/imx8` in the u-boot source code.

Is this something you are familiar with?

0 Kudos
954 Views
seb_haezebrouck
NXP Employee
NXP Employee

Hi @mwso_soe ,

Unfortunately this is not something I am familiar with, so I do not have a direct solution.

Looking quickly at the code, read_auth_container() is called by spl_load_imx_container() - so I assume that SPL will look for a container (probably containing  ATF or "full" u-boot) inside the container set.

The error you are getting is when read_auth_container() does not find a proper container start tag at the start of the structure it read from SPINOR. So either your image is corrupted (unlikely), or SPL is not looking at the right place for some reason (more likely).

I'd suggest you add a couple of traces to understand where in SPINOR SPL is trying to find its container. Looking at the code, spl_nor_get_uboot_base(), get_imageset_end(), get_boot_device_offset() and finally check_secondary_cnt_set() seem like promising places to check. There are already some debug traces there.

Best regards.

883 Views
mwso_soe
Contributor II

Hi @seb_haezebrouck ,

 

I was able to resolve the issue with it not fully booting after the SPL. It turns out there is a bug in NXP's code in `image.c` on my version of U-Boot IMX or, `image-container.c` in later versions of the source.

It turns out that the macro used to locate the secondary image offset is misused/incomplete:

In image.c Line 144:

static bool check_secondary_cnt_set(unsigned long *set_off)
{
	int ret;
	u8 set_id = 1;
	u32 fuse_val = 0;

	if (!(is_imx8qxp() && is_soc_rev(CHIP_REV_B))) {
		ret = sc_misc_get_boot_container(-1, &set_id);
		if (!ret) {
			/* Secondary boot */
			if (set_id == 2) {
				ret = sc_misc_otp_fuse_read(-1, FUSE_IMG_SET_OFF_WORD, &fuse_val);
				if (!ret) {
					if (set_off)
						*set_off = SND_IMG_NUM_TO_OFF(fuse_val);
					return true;
				}
			}
		}
	}

	return false;
}

The raw `fuse_val` is passed to the macro `SND_IMG_NUM_TO_OFF()`

There are a few problems with this implementation

  1. The fuse value is not masked, meaning other bits set in the same word will cause an incorrect offset to be calculated.
  2. The fuse value is not shifted to the correct bit position meaning the wrong bits are used to calculate the offset.
  3. The macro `SND_IMG_NUM_TO_OFF()` is not used when the fuse value is 0, resulting in an offset of `0x0` instead of `0x400000` as would be expected from the reference manual.
853 Views
Dhruvit
NXP TechSupport
NXP TechSupport

Hi @mwso_soe,

I hope you are doing well.

I'm glad that you resolved the issue, hence can I close this thread?

Thanks & Regards,
Dhruvit Vasavada

0 Kudos
850 Views
mwso_soe
Contributor II
Hi @Dhruvit,

You are welcome to close the issue, yes.
0 Kudos
968 Views
Dhruvit
NXP TechSupport
NXP TechSupport

Hi @mwso_soe,

I hope you are doing well.

->If one wants to Program NOR Flash please follow the below steps.
U-Boot uses the regular memory command to program NOR devices. Here is the command sequence for loading an image file to the NOR device.

flinfo
erase all
cp.b <DDR addr> <nor addr> <size>.

-> If one wants to flash u-boot on spi-nor please follow the below link.
->One can also refer to section 4.4.1.4 Flashing U-Boot on SPI-NOR from U-Boot.
https://www.nxp.com/docs/en/user-guide/IMX_LINUX_USERS_GUIDE.pdf

I hope this helps!

Thanks & Regards,
Dhruvit Vasavada

0 Kudos
964 Views
mwso_soe
Contributor II
Hi Dhruvit, thanks for the quick reply.

My problem is not that I cannot figure out how to program the NOR flash, but that I can't get the secondary boot container set feature working as described in the reference manual.

I have the imx-boot images from my Yocto build programmed to the flash partitions in the table in my question, but when I try to test the secondary boot container set failover behavior it does not work.

I can get the SoC to boot from NOR from the imx-boot image located at address 0x00000000, but not the other address.

I have read the following sections in the reference manual:
- 5.8.3.6
- 18.9.2
- 7.2
- 5.9
0 Kudos