Skip to content

On a Quest to find Sanbot's deepest secrets – Part 4 (Getting U-boot to work)

In part 3 of this quest we discovered the environment variables needed to build U-Boot. Interestingly, they turned out to be remarkably similar to the variables used for the Banana Pi M3.

However, our custom-compiled U-Boot still didn't detect the eMMC memory, which meant we couldn't yet load any custom OS. But guess what? After digging around for a while I finally found some clues and got it working!

The goal of running Ubuntu Touch is getting closer and closer. I can't wait…

Legal note

This research was conducted on hardware legally owned by the author. All analysis is performed for the purposes of interoperability, repair, and educational research.

No proprietary firmware or copyrighted software is redistributed on this site.

Some backstory

In part 1 we attempted to run a custom-compiled U-Boot using configuration values we guessed from the Banana Pi M3, which is quite similar to this board. Both use the same SoC, regulators, and memory configuration, so it seemed like a reasonable starting point.

Unfortunately we got stuck when trying to detect the MMC device:

=> mmc list
=> mmc dev 1
Card did not respond to voltage select! : -110

After searching around for this error, I eventually stumbled upon a blog post on the Armbian forum. That thread referenced a pull request in the Armbian build system.

Following that rabbit hole led me to a patch related to the sunxi_mmc_can_calibrate function.

sunxi_mmc_can_calibrate

In newer releases of U-Boot, the function sunxi_mmc_can_calibrate was introduced. Its job is to automatically calibrate MMC controller timings.

However, the U-Boot team never added an entry for the Allwinner A83T, meaning the calibration logic simply fails by default on this SoC. As a result, the mmc dev command fails because the handshake never completes, the calibration function returns false, preventing the controller from initializing correctly.

The fix turned out to be surprisingly simple: add support for the A83T in the sunxi_mmc_can_calibrate logic.

With this small patch:

From 335c35e6f56b87397d5b6ba74d7676e37269636b Mon Sep 17 00:00:00 2001
From: leo <leo@localhost.localdomain>
Date: Sun, 15 Sep 2024 10:50:38 +0300
Subject: [PATCH 1/2] Add MACH_SUN8I_A83T to can calibrate

Add the A83T processor to the sunxi_mmc_can_calibrate
logic function for proper configuration.

---
 drivers/mmc/sunxi_mmc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index 9534f9ac35..9493bd8639 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -62,6 +62,7 @@ static bool sunxi_mmc_can_calibrate(void)
           IS_ENABLED(CONFIG_MACH_SUN50I_H5) ||
           IS_ENABLED(CONFIG_SUN50I_GEN_H6) ||
           IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2) ||
+          IS_ENABLED(CONFIG_MACH_SUN8I_A83T) ||
           IS_ENABLED(CONFIG_MACH_SUN8I_R40);
 }

-- 
2.35.3

…the MMC controller finally came to life:

=> mmc list
mmc@1c0f000: 0
mmc@1c10000: 2
mmc@1c11000: 1
=> mmc dev 1
switch to partitions #0, OK
mmc1(part 0) is current device
=> mmc info  
Device: mmc@1c11000
Manufacturer ID: 11
OEM: 0
Name: 016G70 
Bus Speed: 52000000
Mode: MMC High Speed (52MHz)
Rd Block Len: 512
MMC version 5.0
High Capacity: Yes
Capacity: 14.7 GiB
Bus Width: 8-bit
Erase Group Size: 512 KiB
HC WP Group Size: 4 MiB
User Capacity: 14.7 GiB WRREL
Boot Capacity: 4 MiB ENH
RPMB Capacity: 4 MiB ENH
Boot area 0 is not write protected
Boot area 1 is not write protected
=> mmc part

Partition Map for mmc device 1  --   Partition Type: DOS

Part    Start Sector    Num Sectors     UUID            Type
  1     5382144         25493504        00000000-01     0b Boot
  2     73728           65536           00000000-02     06
  3     1               5242880         00000000-03     05 Extd
  5     139264          32768           00000000-05     83
  6     172032          32768           00000000-06     83
  7     204800          4194304         00000000-07     83
  8     4399104         65536           00000000-08     83
  9     4464640         32768           00000000-09     83
 10     4497408         65536           00000000-0a     83
 11     4562944         524288          00000000-0b     83
 12     5087232         32768           00000000-0c     83
 13     5120000         32768           00000000-0d     83
 14     5152768         1024            00000000-0e     83
 15     5153792         31744           00000000-0f     83
 16     5185536         163840          00000000-10     83
 17     5349376         32768           00000000-11     83
=> 

Finally! With working MMC access we can now explore the Sanbot's internal storage directly from U-Boot, opening the door for booting our own operating system.

The source code for this modified U-Boot can be found on GitHub: opendutchsolutions/u-boot-sanbot