Colibri iMX6 U-Boot environment

I am creating a process to load some Colibri iMX6S 256MB IT V1.1A during production assembly.

The module is installed into a custom carrier board which has an SMSC (Microchip) USB2514B USB hub and four USB type A jacks.

I have compiled a custom U-Boot with some changes to the PIN MUX for a 24-bit parallel RGB display and some additional GPIOs. The default environment CONFIG_ENV_SIZE was also changed from 8192 to 16,384. I also compiled a custom Linux Kernel to support the 24-bit RGB display and some other devices on the carrier board.

The goal is to take a new board delivered from Toradex with the Toradex Easy Installer and install these customer images.

The process is:
Insert USB drive with a tezi_config.json file with a image_list to a HTTP server image_list.json.
The HTTP server image_list.json only has one entry to a subdirectory with the image.json file.
The image.json file defines the mmcblk0 paritions for the BOOT, two rootfs (ROOTFS0, ROOTFS1) and a fourth partition for DATA. The image.json has autoinstall=true.

The image.json section for mmcblk0boot0 defines the U-Boot images.
SPL with dd_options “seek=2”
u-boot.img with dd_options “seek=138”
env_uboot_16K.img with dd_options “seek=4063”

The env_uboot_16K.img has some custom environment variables such as removing the vidargs and setting panel equal to the name of the display I added to the displays in the colibri_imx6.c.

My initial testing to create this process was with a Colibri iMX6S 256MB V1.0A (not IT). When I insert the USB drive and power on the device the Toradex Easy Installer successfully installs the images and when it completes I power off the device and remove the USB drive. When I power it back on U-Boot has the custom environment I created and boots the Linux Kernel.

When I switched to the next device I have a Colibri iMX6S 256MB IT V1.1A installed, we want the IT version in the production product. I perform the same steps with the same USB drive and HTTP server and the Easy Installer does complete successfully. When power down the device and remove the USB drive and power the device back on U-Boot shows the Warning - bad CRC, using default environment.

I have read that there are some things done in the SPL to adjust the DRAM timings for the IT version. Is there something that would cause the CRC check on the environment to fail on the industrial temperature version and not the commercial temperature? Or is this a difference between the V1.0A and the V1.1A? I was thinking that there might be some difference in the config block that I don’t see.

I did discover that using either fw_printenv or fw_setenv during the wrapup.sh would cause a bad CRC. This is cause by the fact that the Easy Installer has a /etc/fw_env.config set to the 8K size and offset.

Thanks,
Chris

I am creating a process to load some Colibri iMX6S 256MB IT V1.1A during production assembly.

The module is installed into a custom carrier board which has an SMSC (Microchip) USB2514B USB hub and four USB type A jacks.

I have compiled a custom U-Boot with some changes to the PIN MUX for a 24-bit parallel RGB display and some additional GPIOs. The default environment CONFIG_ENV_SIZE was also changed from 8192 to 16,384.

I hope you understand all the implications of such a change. BTW: Would also be interesting to know the reason for such a change.

I also compiled a custom Linux Kernel to support the 24-bit RGB display and some other devices on the carrier board.

The goal is to take a new board delivered from Toradex with the Toradex Easy Installer and install these customer images.

The process is: Insert USB drive with a tezi_config.json file with a image_list to a HTTP server image_list.json. The HTTP server image_list.json only has one entry to a subdirectory with the image.json file. The image.json file defines the mmcblk0 paritions for the BOOT, two rootfs (ROOTFS0, ROOTFS1) and a fourth partition for DATA. The image.json has autoinstall=true.

The image.json section for mmcblk0boot0 defines the U-Boot images. SPL with dd_options “seek=2” u-boot.img with dd_options “seek=138” env_uboot_16K.img with dd_options “seek=4063”

Wondering where you got that last offset from. Definitely not from any of our code as this is not how it works.

The env_uboot_16K.img has some custom environment variables such as removing the vidargs and setting panel equal to the name of the display I added to the displays[] in the colibri_imx6.c.

Pre-loading the environment like that is not really recommended.

My initial testing to create this process was with a Colibri iMX6S 256MB V1.0A (not IT). When I insert the USB drive and power on the device the Toradex Easy Installer successfully installs the images and when it completes I power off the device and remove the USB drive. When I power it back on U-Boot has the custom environment I created and boots the Linux Kernel.

Mere chance.

When I switched to the next device I have a Colibri iMX6S 256MB IT V1.1A installed, we want the IT version in the production product. I perform the same steps with the same USB drive and HTTP server and the Easy Installer does complete successfully. When power down the device and remove the USB drive and power the device back on U-Boot shows the Warning - bad CRC, using default environment.

Well, guess where it is looking for its U-Boot environment?

I have read that there are some things done in the SPL to adjust the DRAM timings for the IT version. Is there something that would cause the CRC check on the environment to fail on the industrial temperature version and not the commercial temperature? Or is this a difference between the V1.0A and the V1.1A? I was thinking that there might be some difference in the config block that I don’t see.

No, it is just looking for its U-Boot environment where it got instructed to.

I did discover that using either fw_printenv or fw_setenv during the wrapup.sh would cause a bad CRC. This is cause by the fact that the Easy Installer has a /etc/fw_env.config set to the 8K size and offset.

I guess changing any such would also imply having to change such configuration accordingly. With that I still believe our recommended fw_printenv/fw_setenv approach via wrapup.sh would work best.

BTW: Would also be interesting to know the reason for such a change.

The reason for the change is that we have added several environment variables which exceeded the 8192 byte size.

Wondering where you got that last offset from. Definitely not from any of our code as this is not how it works.

Following the example https://www.toradex.com/community/questions/14746/how-to-erase-emmc-automatically-during-flashing-im.html

Since the flash layout was not clear https://developer.toradex.com/knowledge-base/flash-layout-i-mx6
The page is more for wec2017, wec7 and the detail information on the config block relate to the Windows OS image. Is there any documentation to describes how or what parts of the config block are used for Linux?

I referenced the update.sh this is how I understand the eMMC layout. I created a spreadsheet to help calculate the locations.

The boot partition starts at sector 8192 and is 32768 sectors in size. It has three areas.
Boot0 (mmcblk0boot0) which is 4096 sectors in size. Starting at sector 8192.
Boot1 (mmcblk0boot1) which is 4096 sectors in size. Starting at sector 12288.
Linux Boot fat32 (mmcblk0p1) which is 24576 sectors in size. Starting at sector 16384.

Boot0 has a base offset of 2 sectors.
SPL size is 136 sectors.  Starting at the 2 sector offset seek=2 0x400
u-boot.img starts after the SPL at sector 138 seek=138 0x11400
The Toradex config block is 1 sector in size starting at the end. 4096-1=4095 0x1FFE00
The original U-Boot environment is 8K or 16 sectors in size in front of the config block. 4096-1-16=4079 0x1FDE00
The U-Boot environment with 16K is 32 sectors in size.  So 4096-1-32=4063 seek=4063 0x1FBE00

Pre-loading the environment like that is not really recommended.

I was following the example given here https://www.toradex.com/community/questions/7352/copy-u-boot-u-boot-vars-using-dd.html
Though I don’t want to U-Boot environment to have the ethaddr or serial# variables since those should be unique and generated from the config block.
I also tried creating the U-Boot environment using mkenvimage.

Well, guess where it is looking for its U-Boot environment?

The colibri_imx6.h you linked to I have modified in the U-Boot image I have built.

#define CONFIG_ENV_SIZE (16 * 1024)
#deine CONFIG_ENV_OFFSET (-CONFIG_ENV_SIZE + CONFIG_TDX_CFG_BLOCK_OFFSET)
CONFIG_TDX_CFG_BLOCK_OFFSET = -512
CONFIG_ENV_OFFSET=-16384 + -512=-16896

So if mmcblk0boot0 is 4096 sectors the total size is 2097152 bytes 0x200000.  2097152-16896=2080256 0x1FBE00.

U-Boot should be looking in the correct location. Which seems to be verified since it works on the V1.0A module.
What I don’t understand is why the V1.1A module is different.

Thanks for your help.

The reason for the change is that we have added several environment variables which exceeded the 8192 byte size.

I still seriously doubt that what you are trying to store in there makes sense, after all it is just a boot loader environment.

Following the example https://www.toradex.com/community/questions/14746/how-to-erase-emmc-automatically-during-flashing-im.html

Sorry about that but what my Chinese colleague @benjamin.tx suggested there is really not recommended at all (I did update that answer now BTW).

Since the flash layout was not clear https://developer.toradex.com/knowledge-base/flash-layout-i-mx6 The page is more for wec2017, wec7 and the detail information on the config block relate to the Windows OS image.

I wasn’t aware there is a wec2017 (;-p) and yes, that article is WinCE only.

Is there any documentation to describes how or what parts of the config block are used for Linux?

I understand that the WinCE folks are misusing the term config block also for boot loader environment but Embedded Linux does not do so. The only information used from the config block is the hardware revision and serial number.

I referenced the update.sh this is how I understand the eMMC layout. I created a spreadsheet to help calculate the locations.

Sorry, but your understanding is not correct. Some information may be found here or the U-Boot configuration as already referred to before.

I was following the example given here https://www.toradex.com/community/questions/7352/copy-u-boot-u-boot-vars-using-dd.html

No, you were not as my Colleague @max.tx clearly stated that the size of mmcblk0boot0 depends on the stuffed eMMC and might change in future revisions.

Though I don’t want to U-Boot environment to have the ethaddr or serial# variables since those should be unique and generated from the config block.

Yes, they are unique and just read from the config block.

I also tried creating the U-Boot environment using mkenvimage.

As stated before we do recommend the fw_printenv/fw_setenv approach via wrapup.sh as anything else is prone to be problematic in the future and therefore not believed to be any good approach.

U-Boot should be looking in the correct location. Which seems to be verified since it works on the V1.0A module. What I don’t understand is why the V1.1A module is different.

It has different eMMC parts stuffed with different hardware area boot partition sizes which U-Boot is automatically taking care of.