[U-Boot] sunxi board: why MMC dev are swapped ?

Hans de Goede hdegoede at redhat.com
Sat Nov 12 11:22:37 CET 2016


Hi,

On 11-11-16 19:33, Mylene Josserand wrote:
> Hi everyone,
>
>
> I am currently using FEL and Fastboot to flash a sunxi-device with SPL and u-boot.
>
>
> In my board, I have two MMC devices: a MMC slot and an eMMC.
>
> My use-case is to flash an empty device. I want to use FEL to boot a u-boot and then, use fastboot to flash u-boot into eMMC.
>
> When I am using an u-boot via FEL, the eMMC is configured as MMC1. To be able to flash u-boot on it, I need to set CONFIG_FASTBOOT_FLASH_MMC_DEV to 1. Thanks to that, the flashboot command is working fine.
> But when I am booting on my fresh u-boot from eMMC, it is now configured as MMC0 and not MMC1 anymore.
>
> It produces some problems in my case as I configured the CONFIG_FASTBOOT_FLASH_MMC_DEV to 1 so I can not use fastboot anymore to flash the eMMC (as, now, fastboot is trying to flash u-boot on my MMC slot and not my eMMC). This is clearly not what I wanted to. I would like to use fastboot to flash the same MMC device: eMMC.
>
> This issue is located in this part of the code:
> http://git.denx.de/?p=u-boot.git;a=blob;f=board/sunxi/board.c;h=53656383d512199338dcdc1d4fdc4f7f939c9b61;hb=HEAD#l377
>
> Do you know why sunxi boards have this behavior ? Why this MMC device's swap is implemented ?

Most boards with emmc can boot from either the external mmc slot (sdc0 / port F)
or the emmc (sdc2 / port C).

Depending on the boot source, we map these as follows in u-boot:

Boot source sdc2:

MMC0: sdc2
MMC1: sdc0

Other boot source (including sdc0):

MMC0: sdc0
MMC1: sdc2

There are a number of reasons for this:

1) The loading of u-boot proper (the 3th boot stage) by the SPL (the 2nd boot stage,
with the SoCs BootROM being the 1st stage), the SPL mmc code used to always load from
MMC0, I believe this has been fixed now, so this is mainly historical.

2) The standard bootscripts from u-boot/include/config_distro_bootcmd.h start by
looking for extlinux/extlinux.conf / boot.scr in MMC0, clearly if we booted from sdc2,
the first place to look for these files should be sdc2, and not some random non-bootable
sdcard in the external slot. As is explained in the comment above the code for this you
already found.

I would certainly welcome some patches where some early init code would set a bootdev
environment variable and modify the boot_targets env variable to do the swapping there,
but include/config_distro_bootcmd.h does not make this easy. The best solution I can come
up with would be something like the attached patch.

I'm not 100% sure that the "if test ${bootdev} = sdc2;" bit will work, as I'm not sure
if the u-boot build-in "test" command supports comparing strings. Other then that
you would need to add some code to set bootdev in the env based on the return value
of readb(SPL_ADDR + 0x28), or maybe a more generic helper function using the standardized
return value from spl_boot_device(), as that may be useful for other boards too.

Once you're setting bootdev in the environement correctly, my patch should do the
trick to try and boot from sdc2 first when booting from the eMMC with the swapping
code you pointed out removed.

Then we can simply always map the devices as:

MMC0: sdc0
MMC1: sdc2

and we would still try to load extlinux/extlinux.conf from sdc2 first if that is the
boot source.

If you can get this to work then I would be happy to merge this, note the
include/config_distro_bootcmd.h bit should be submitted upstream as a separate
patch.

Regards,

Hans

-------------- next part --------------
diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h
index 9ecaf38..44047cf 100644
--- a/include/config_distro_bootcmd.h
+++ b/include/config_distro_bootcmd.h
@@ -314,6 +314,10 @@
 #define BOOTENV_BOOT_TARGETS \
 	"boot_targets=" BOOT_TARGET_DEVICES(BOOTENV_DEV_NAME) "\0"
 
+#ifndef BOOTENV_BOOTCMD_PRE_BOOT
+#define BOOTENV_BOOTCMD_PRE_BOOT
+#endif
+
 #define BOOTENV_DEV(devtypeu, devtypel, instance) \
 	BOOTENV_DEV_##devtypeu(devtypeu, devtypel, instance)
 #define BOOTENV \
@@ -384,7 +388,9 @@
 	\
 	BOOT_TARGET_DEVICES(BOOTENV_DEV)                                  \
 	\
-	"distro_bootcmd=" BOOTENV_SET_SCSI_NEED_INIT                      \
+	"distro_bootcmd="                                                 \
+		BOOTENV_SET_SCSI_NEED_INIT                                \
+		BOOTENV_BOOTCMD_PRE_BOOT                                  \
 		"for target in ${boot_targets}; do "                      \
 			"run bootcmd_${target}; "                         \
 		"done\0"
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 8363414..b0e6a2a 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -448,6 +448,24 @@ extern int soft_i2c_gpio_scl;
 	func(PXE, pxe, na) \
 	func(DHCP, dhcp, na)
 
+#if CONFIG_MMC_SUNXI_SLOT_EXTRA == 2
+
+#define BOOT_TARGET_DEVICES_MMC_SWAP(func) \
+	func(FEL, fel, na) \
+	BOOT_TARGET_DEVICES_MMC_EXTRA(func) \
+	BOOT_TARGET_DEVICES_MMC(func) \
+	BOOT_TARGET_DEVICES_SCSI(func) \
+	BOOT_TARGET_DEVICES_USB(func) \
+	func(PXE, pxe, na) \
+	func(DHCP, dhcp, na)
+
+#define BOOTENV_BOOTCMD_PRE_BOOT \
+	"if test ${bootdev} = sdc2; then " \
+	"	boot_targets=" BOOT_TARGET_DEVICES_MMC_SWAP(BOOTENV_DEV_NAME) "; " \
+	"fi; "
+
+#endif
+
 #ifdef CONFIG_OLD_SUNXI_KERNEL_COMPAT
 #define BOOTCMD_SUNXI_COMPAT \
 	"bootcmd_sunxi_compat=" \


More information about the U-Boot mailing list