Cannot get custom imx6 board to boot into Linux from eMMC

Over the last few years we have designed a custom board based on imx6q SabreSD for our data acquisition system. It is working well and has been for the last couple of years.

We based out SPL/U-Boot/Linux kernel/Debian setup on those here at Digikey I think created by Robert C Nelson (we created custom variants of the imx6q SabreSD code and tailored it to our hardware customisations):

Debian: Getting Started with the i.MX6q SABRE Board

We of course had to customise U-boot for our device and also the kernel device tree etc. We are on kernel v5.15.x-rt and U-boot v2018.11 and Debian 10.12.

Until now we’ve been running from SD cards but we do have a 16GB eMMC 5.2 fitted. If I boot from the SD card and then in Linux get the info about the MMC we see:

root@arm:~# cat /sys/kernel/debug/mmc2/ios
clock: 52000000 Hz
vdd: 21 (3.3 ~ 3.4 V)
bus mode: 2 (push-pull)
chip select: 0 (don’t care)
power mode: 2 (on)
bus width: 3 (8 bits)
timing spec: 8 (mmc DDR52)
signal voltage: 0 (3.30 V)
driver type: 0 (driver type B)

and also:

root@arm:~# lsblk -p
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
/dev/mmcblk1 179:0 0 29.8G 0 disk
└─/dev/mmcblk1p1 179:1 0 29.8G 0 part /
/dev/mmcblk2 179:256 0 14.7G 0 disk
└─/dev/mmcblk2p1 179:257 0 14.7G 0 part
/dev/mmcblk2boot0 179:512 0 4M 1 disk
/dev/mmcblk2boot1 179:768 0 4M 1 disk

mmcblk1 is the SD card, mmcblk2 is the eMMC.

I have tried a couple of approaches. The first was to simply try and flash what we’d use to create the SD card (using similar steps to the Digikey link above in this post) onto mmcblk2 (ultimately a partition mmcblk2p1) and not use boot0 or boot1. I can then power off, remove the SD card and change our 8 way dip switches to select MMC instead of SD (similar to the dip switches on the iMX6 SabreSD dev kit board). When I do this it ultimately drops to a U-boot console with errors about invalid partitions on the MMC and invalid file system format. I did try repeating this using a rebuilt version of our U-boot where I made sure in our header files (based on mx6sabre_common.h and mx6sabresd.h) I tweaked some values to select MMC instead of SD. Again this made no difference.

Next I tried to make use of mmcblkboot0, like shown here:

eMMC Hardware Boot Area Partitions

In the above when it came to using dd to flash a U-boot image to boot0 I used the .img file from our build.

Anyway when I tried the boot0 approach our board wouldn’t even boot at all, I cannot even see any serial output.

I’m sure I’m missing something silly so any hints/help would be much appreciated. In particular what would I need to do to be able to use our U-boot/Linux Kernel/Debian images base don the Robert C Nelson ones I linked above to work from eMMC?

Many thanks in advance.

old versions of u-boot had so many hard-coded device access routines, double check it’s the correct base device… Today we usually default to scanning for extlinux.conf, please share your u-boot log, so we can try to see what’s going on…

As far as boot0/boot1, i don’t remember if the imx6 bootrom actually natively supported those memory sections.

Sadly i retired my imx6 based ci farm, (WandBoard’s), as they didn’t have the memory needed anymore for my ci builders (8GB)…

Regards,

Here is the log from putty:

U-Boot SPL 2018.11-dirty (Feb 05 2024 - 15:43:19 +0000)
HGL board_init_f: hello!
HGL board_init_f: setup_pcie() does not appear to have been called
HGL board_init_f: Clear the BSS
HGL board_init_f: calling board_init_r
Trying to boot from MMC1
HGL board_mmc_init
HGL board_mmc_init: CONFIG_SPL_BUILD is defined
HGL board_mmc_init: set struct src *psrc, calling readl(&psrc->sbmr1)
HGL board_mmc_init: readl(&psrc->sbmr1) has returned
HGL board_mmc_init: reg = 10
HGL board_mmc_init: reg & 3 = 2
HGL board_mmc_init: (CONFIG_SPL_BUILD) setting pads for uSDHC3 (eMMC) on MMC1
HGL board_mmc_init: (CONFIG_SPL_BUILD) calling fsl_esdhc_initialize
HGL board_mmc_init: (CONFIG_SPL_BUILD) fsl_esdhc_initialize returned 0
HGL board_mmc_getcd
HGL board_mmc_getcd: USDHC3_BASE_ADDR
HGL board_mmc_getcd: ret = 1
mmc_load_image_raw_sector: mmc block read error

U-Boot 2018.11-dirty (Feb 05 2024 - 15:43:19 +0000)

CPU: Freescale i.MX6Q rev1.6 996 MHz (running at 792 MHz)
CPU: Automotive temperature grade (-40C to 125C) at 21C
Reset cause: POR
Board: MX6-Dragonfly
I2C: ready
DRAM: HGL dram_init
1 GiB
HGL board_init
HGL board_init: calling setup_i2c, is_mx6dq() == true
MMC: HGL board_mmc_init
HGL board_mmc_init: CONFIG_SPL_BUILD is not defined
HGL board_mmc_init: setting pads for SD2 [uSD] (MMC0)
HGL board_mmc_init: calling fsl_esdhc_initialize
HGL board_mmc_init: setting pads for SD3 [eMMC] (MMC1)
HGL board_mmc_init: calling fsl_esdhc_initialize
HGL board_mmc_init: returning 0
FSL_SDHC: 0, FSL_SDHC: 1
Loading Environment from MMC… HGL board_mmc_get_env_dev: devno = 2, returning 1
HGL board_mmc_getcd
HGL board_mmc_getcd: USDHC3_BASE_ADDR
HGL board_mmc_getcd: ret = 1
*** Warning - bad CRC, using default environment

PCI:
00:01.0 - 16c3:abcd - Bridge device
01:00.0 - 8086:1533 - Network controller
HGL overwrite_console
In: serial
Out: serial
Err: serial
HGL board_late_init
HGL board_late_init: calling add_board_boot_modes
HGL board_late_init: setting board_name = DRAGONFLY 24/32CH
HGL board_late_init: setting board_rev = MX6Q
Net: HGL setup_pcie
Board Net Initialization Failed
No ethernet found.
Press SPACE to abort autoboot in 2 seconds
HGL board_mmc_getcd
HGL board_mmc_getcd: USDHC2_BASE_ADDR
HGL board_mmc_getcd: ret = 1
Card did not respond to voltage select!
HGL board_mmc_getcd
HGL board_mmc_getcd: USDHC2_BASE_ADDR
HGL board_mmc_getcd: ret = 1
Card did not respond to voltage select!
HGL board_mmc_getcd
HGL board_mmc_getcd: USDHC3_BASE_ADDR
HGL board_mmc_getcd: ret = 1
switch to partitions #0, OK
mmc1(part 0) is current device
HGL board_mmc_getcd
HGL board_mmc_getcd: USDHC3_BASE_ADDR
HGL board_mmc_getcd: ret = 1
SD/MMC found on device 1
Checking for: /uEnv.txt …
** Unrecognized filesystem type **
Checking for: /boot/uEnv.txt …
** Unrecognized filesystem type **
** Invalid partition 2 **
** Invalid partition 3 **
** Invalid partition 4 **
** Invalid partition 5 **
** Invalid partition 6 **
** Invalid partition 7 **
HGL board_mmc_getcd
HGL board_mmc_getcd: USDHC2_BASE_ADDR
HGL board_mmc_getcd: ret = 1
Card did not respond to voltage select!
HGL board_mmc_getcd
HGL board_mmc_getcd: USDHC3_BASE_ADDR
HGL board_mmc_getcd: ret = 1
switch to partitions #0, OK
mmc1(part 0) is current device
** Unrecognized filesystem type **
=>

Also attached are the uboot header files for out custom device. I’ve attached the ones that work for our SD card version which boots fine and also attached the ones I tried to tweak for the failed MMC version.

uboot_device_headers_sd_card_good.7z (3.1 KB)
uboot_device_headers_mmc_boot_fails.7z (3.1 KB)

Note that this log is for the case where I have (in Linux booted from SD card using mmc tool) set the MMC back to not use boot0 or boot1, so in other words back to its initial state. We have the dip switches set for MMC and have removed the SD card. As there is no SD card in this at least means that it is finding SPL/U-boot on the MMC and running them from there on boot up, it is just not locating the Linux side of things to start them up.

Ok I have worked out the problem myself and fixed it!

The script we have that does all the hard work flashing the SD card, which I reused to flash the MMC had essentially a bug in it only when dealing with the MMC.

When flashing the SD card from a dev PC, the SD card partition will be something like /dev/sda1. Whereas flashing the MMC from within Linux booted from the SD card will appear as /dev/mmcblk2 and the partition is /dev/mmcblk2p1. The script builds this up dynamically and takes the user supplied device name, e.g. /dev/sda or /dev/mmcblk2 and appends a 1 to the end. This only works for the case when flashing the SD card from the PC but when flashing the MMC from the device itself off the SD card it should append a p1.

Since fixing the script I am now able to boot from the MMC and into Linux.

1 Like

Awesome! @dcrutchley