December 25, 2021

Orange Pi 4 (Rockchip 3399) Flashing Debian to eMMC

My card with eMMC has Android on the eMMC. It would be nice to flash Debian there instead. In particular, it would be nice to have a U-Boot there that I can customize by getting to its console prompt.

I had success! See the end of this rather long writeup.

You might think it would be as simple as using "dd" to copy the SD card image to eMMC, but you would be wrong.

Online searches yielded a vast amount of misinformation, but it was a good learning experience to sort through some of it. In particular I learned things about eMMC that I never knew, but skip to the end of this page to learn what actually worked.

The following link describes a process that uses "maskrom" (which is no doubt the boot rom in the SoC). You force the device to run the maskrom by shorting some pads, then you can use a USB cable and a utility to write an image. No doubt this will work, but there ought to be a way to do it from a Debian image running from the SD card. (And there is, keep reading ...)

Debian "mmc" devices

The mount command shows these:
/dev/mmcblk0p1 on / type ext4 (rw,noatime,nodiratime,errors=remount-ro,commit=600)
/dev/mmcblk0p1 on /var/log.hdd type ext4 (rw,noatime,nodiratime,errors=remount-ro,commit=600)
A look into the device directory shows this:
root@orangepi4:~# ls -l /dev | grep mmc
brw-rw----  1 root disk    179, 128 Dec 25 05:45 mmcblk0
brw-rw----  1 root disk    179, 129 Dec 25 05:45 mmcblk0p1
brw-rw----  1 root disk    179,   0 Dec 25 05:45 mmcblk1
brw-rw----  1 root disk    179,  32 Dec 25 05:45 mmcblk1boot0
brw-rw----  1 root disk    179,  64 Dec 25 05:45 mmcblk1boot1
brw-rw----  1 root disk    179,  96 Dec 25 05:45 mmcblk1rpmb
I can run fdisk on mmcblk0 and there is one partition.
I cannot run fdisk on mmcblk1 (which is apparently the on board eMMC)

I will note that there is a utility: /usr/bin/mmc. Just typing "mmc" gives a long usage message and "man mmc" exists.

Some information about how the eMMC is set up can be found here:

At least in part this has to do with what the ROM in the RockChip SoC expects.

Further investigations

The eMMC chip used on the board is a Samsung KLMAG1JETD-B04-1, which is a 16G device supporting the eMMC 5.1 specification. Much to my surprise, the chip itself supports the partitioning into a pair of boot areas and a "user" area. The strange device /dev/mmtblk1rpmb is also supported by the device and is a secure area protected by a sha256 key. Here "rpmb" stands for "replay protected memory block". The sizes of the two boot blocks is 4M each on this device, and I can easily confirm this by doing a "dd" command to /dev/null. Attempting to read the rpmb block gives an IO error, which I suppose makes sense. Attempting a transfer of indefinite length from the mmcblk1 block (presumably the user partition) gives an unexpected exception and hangs the system.

I quickly tried a couple of quick things with /dev/mmtblk1. Running fdisk on it reports that it does not contain a partition table. Attempting to mount it declares that there is no valid superblock or recognizable filesystem.

To my surprise I find that the two 4M boot0 and boot1 blocks contain nothing but zeros! Looking at strings in the "user" partition confirms that U-Boot lives there. Perhaps we should boot Android again from eMMC and see what we can learn in that way.

The view from Android

Booting android is as simple as removing the SD card with Debian and doing a reset. The view from here is quite different! Here is the output (in part) from mount:
rootfs on / type rootfs (ro,seclabel,size=1958908k,nr_inodes=489727)
/dev/block/dm-0 on /system type ext4 (ro,seclabel,relatime,data=ordered,inode_readahead_blks=8)
/dev/block/dm-1 on /vendor type ext4 (ro,seclabel,relatime,data=ordered,inode_readahead_blks=8)
/dev/block/mmcblk1p14 on /oem type ext4 (ro,seclabel,noatime,nodiratime,noauto_da_alloc,data=ordered)
/dev/block/mmcblk1p10 on /cache type ext4 (rw,seclabel,nosuid,nodev,noatime,nodiratime,discard,noauto_da_alloc,data=ordered)
/dev/block/mmcblk1p12 on /metadata type ext4 (rw,seclabel,nosuid,nodev,noatime,nodiratime,discard,noauto_da_alloc,data=ordered)
/dev/block/dm-2 on /data type f2fs (rw,lazytime,seclabel,nosuid,nodev,noatime,nodiratime,background_gc=on,discard,no_heap,user_xattr,inline_xattr,inline_data,inline_dentry,flush_merge,extent_cache,mode=adaptive,active_logs=6)
Looking at the devices in /dev/block, we see (in part):
brw------- 1 root   root   252,   0 2021-12-27 03:43 dm-0
brw------- 1 root   root   252,   1 2021-12-27 03:43 dm-1
brw------- 1 root   root   252,   2 2021-12-27 03:43 dm-2
brw------- 1 root   root   179,   0 2021-12-27 03:43 mmcblk1
brw------- 1 root   root   179,  32 2021-12-27 03:43 mmcblk1boot0
brw------- 1 root   root   179,  64 2021-12-27 03:43 mmcblk1boot1
brw------- 1 root   root   179,   1 2021-12-27 03:43 mmcblk1p1
brw------- 1 root   root   179,  10 2021-12-27 03:43 mmcblk1p10
brw------- 1 root   root   179,  11 2021-12-27 03:43 mmcblk1p11
brw------- 1 root   root   179,  12 2021-12-27 03:43 mmcblk1p12
brw------- 1 root   root   179,  13 2021-12-27 03:43 mmcblk1p13
brw------- 1 root   root   179,  14 2021-12-27 03:43 mmcblk1p14
brw-rw---- 1 system system 179,  15 2021-12-27 03:43 mmcblk1p15
brw------- 1 root   root   179,  16 2021-12-27 03:43 mmcblk1p16
brw------- 1 root   root   179,   2 2021-12-27 03:43 mmcblk1p2
brw------- 1 root   root   179,   3 2021-12-27 03:43 mmcblk1p3
brw------- 1 root   root   179,   4 2021-12-27 03:43 mmcblk1p4
brw------- 1 root   root   179,   5 2021-12-27 03:43 mmcblk1p5
brw------- 1 root   root   179,   6 2021-12-27 03:43 mmcblk1p6
brw------- 1 root   root   179,   7 2021-12-27 03:43 mmcblk1p7
brw------- 1 root   root   179,   8 2021-12-27 03:43 mmcblk1p8
brw------- 1 root   root   179,   9 2021-12-27 03:43 mmcblk1p9
brw------- 1 root   root   179,  96 2021-12-27 03:43 mmcblk1rpmb
It is interesting that the major and minor device numbers correspond to what is used by Debian. The "dm-0" devices are set up by LVM and "dm" stands for device mapper.

What does "binwalk" tell us

I am now back to running Debian from the SD card. Lots of things about android are unfamiliar to me (although it is linux of a certain sort). I use "dd" to pull the first 4G from /dev/mmcblk1:
dd if=/dev/mmcblk1 of=user.img count=xyz
binwalk user.img
There are lots of messages, here are some of the interesting ones:
8822596       0x869F44        ELF, 32-bit LSB shared object, ARM, version 1 (SYSV)
8982910       0x89117E        Copyright string: "Copyright2008Rockchip"
8983971       0x8915A3        Android bootimg, kernel size: 1634683904 bytes, kernel addr: 0x44462064, ramdisk size: 1919295572 bytes,
				ramdisk addr: 0x62206D6F, product name: "d FDT from resource image."
20973568      0x1400800       device tree image (dtb)
49619370      0x2F521AA       Boot section Start 0x422E1B37 End 0x37
54558328      0x3407E78       gzip compressed data, maximum compression, from Unix, last modified: 1970-01-01 00:00:00 (null date)
71303176      0x4400008       gzip compressed data, from Unix, last modified: 1970-01-01 00:00:00 (null date)
104857608     0x6400008       gzip compressed data, from Unix, last modified: 1970-01-01 00:00:00 (null date)
...
So no filesystem there, Android must have its own clever booting scheme and keeps things compressed on eMMC. All I really care about is knowing how to put my own U-Boot onto eMMC, and perhaps even Debian someday (or Armbian, or just about anything but Android).

Hey, what about the "nand-sata-install" script!

This is mentioned on page 89 of the user manual and may just be the ticket. Equally exciting is that it is present on my Debian system in /usr/sbin and is a bash script with the following comments:
# Tool to transfer the rootfs of an already running Orange Pi installation from SD card # to NAND, eMMC, SATA or USB storage. In case of eMMC it's also possible to transfer # the bootloader to eMMC in a single step so from then on running without SD card is # possible.
I give it a try and follow the instructions in the user manual. By golly! It worked!!

Best of all, I can now tap the space bar and get to the U-Boot console prompt!!

Now when I log into the "machine" I see:

ls -l /dev/*mmc*
brw-rw---- 1 root disk 179,  0 Dec 27 03:43 mmcblk1
brw-rw---- 1 root disk 179, 32 Dec 27 03:43 mmcblk1boot0
brw-rw---- 1 root disk 179, 64 Dec 27 03:43 mmcblk1boot1
brw-rw---- 1 root disk 179,  1 Dec 27 03:43 mmcblk1p1
brw-rw---- 1 root disk 179, 96 Dec 27 03:43 mmcblk1rpmb
The device mmcblk1 now holds a valid partition table, and fdisk shows me:
Disk mmcblk1: 14.6 GiB, 15634268160 bytes, 30535680 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xecb86bb3

Device     Boot Start      End  Sectors  Size Id Type
mmcblk1p1       32768 30230303 30197536 14.4G 83 Linux


Have any comments? Questions? Drop me a line!

Tom's electronics pages / tom@mmto.org