# eMMC Multi-Boot Setup — Orange Pi 3B **Status:** Procedural reference. Last verified: 2026-06-02 (discussion with Jez). ## Goal Boot multiple ARM64 OSes from the OPi 3B's onboard 256GB eMMC, with a u-boot boot menu (`extlinux.conf`) appearing at power-on. No SD card needed after setup. **Planned OSes:** Orange Pi OS (Arch), Armbian, NixOS SPI NOR flash was erased via maskrom and is unused going forward. ## Boot Chain (after SPI erase) ``` BootROM → SPI (empty, skip) → microSD (if inserted) → eMMC boot partition → extlinux.conf → menu → kernel ``` If microSD **is** inserted and has a valid bootloader, it takes priority over eMMC. Useful as a lifeboat/rescue path — if eMMC boot breaks, pop in the SD card and you're back. ## Partition Layout Proposed new partition schema: ``` mmcblk1 (256GB eMMC) ├── mmcblk1boot0 (hardware boot partition — u-boot SPL + proper) ├── mmcblk1boot1 (unused mirror) └── mmcblk1 ├── mmcblk1p1 FAT32 1GB /boot (extlinux.conf, kernels, DTBs — shared) ├── mmcblk1p2 ext4 85GB root_opios (Orange Pi OS Arch) ├── mmcblk1p3 ext4 85GB root_armbian (Armbian) └── mmcblk1p4 ext4 ~84GB root_nixos (NixOS) ``` ### Why a dedicated FAT32 boot partition? u-boot reads `extlinux.conf` from a FAT, ext4, or btrfs partition. FAT32 is the most universally supported across distro kernel packages. A shared `/boot` means all three OSes drop their kernels and DTBs into one place, and a single `extlinux.conf` controls the menu. 1GB gives headroom for multiple kernel versions across all three OSes. ## Step 1: Clone SD → eMMC Move Orange Pi OS from the microSD card to eMMC and leave two more root paritions ready for other operating systems later. ### 1.1 — Identify devices Run on the running Orange Pi OS (booted from SD): ```bash lsblk mount | grep mmcblk ``` Expected: - `mmcblk0` = SD card (current boot device) - `mmcblk1` = eMMC (target boot device) Actual: - `mmcblk0` = eMMC (target boot device) - `mmcblk1` = SD card (current boot device) Ground truth state with only OPi OS on SD card: ```bash [jez@Rocky ~]$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS mtdblock0 31:0 0 16M 0 disk mmcblk0 179:0 0 233G 0 disk mmcblk0boot0 179:32 0 4M 1 disk mmcblk0boot1 179:64 0 4M 1 disk mmcblk1 179:96 0 238.4G 0 disk ├─mmcblk1p1 179:97 0 213.6M 0 part /boot └─mmcblk1p2 179:98 0 238.2G 0 part / zram0 254:0 0 0B 0 disk ``` ### 1.2 — Wipe eMMC partition table **Destroys everything on eMMC.** Skip if eMMC is already empty. ```bash sudo sgdisk --zap-all /dev/mmcblk0 sudo blkdiscard /dev/mmcblk0 # optional ``` ### 1.3 — Partition eMMC ```bash sudo gdisk /dev/mmcblk0 ``` In `gdisk` interactive mode: ``` o (new GPT) n 1 default +1G ef00 name=boot n 2 default +85G 8300 name=root_opios n 3 default +85G 8300 name=root_armbian n 4 default default 8300 name=root_nixos w (write, confirm 'y') ``` ### 1.4 — Create filesystems ```bash sudo mkfs.vfat -F 32 -n BOOT /dev/mmcblk0p1 sudo mkfs.ext4 -L root_opios /dev/mmcblk0p2 sudo mkfs.ext4 -L root_armbian /dev/mmcblk0p3 sudo mkfs.ext4 -L root_nixos /dev/mmcblk0p4 ``` ### 1.5 — Mount and rsync the live rootfs ```bash sudo mkdir -p /mnt/root_opios sudo mount /dev/mmcblk0p2 /mnt/root_opios sudo mkdir -p /mnt/root_opios/boot sudo mount /dev/mmcblk0p1 /mnt/root_opios/boot sudo rsync -axHAWX --info=progress2 / /mnt/root_opios/ sudo rsync -aHAWX /boot/ /mnt/root_opios/boot/ # /boot is a separate partition, -x skips it ``` Flags: archive, stay-on-filesystem (critical — skips /proc, /sys, /dev), preserve hardlinks/ACLs/xattrs, copy whole files (faster locally). The second rsync handles the separate /boot partition that -x deliberately avoids. ### 1.6 — Bind mount virtual filesystems ```bash sudo mkdir -p /mnt/root_opios/{proc,sys,dev,run,tmp} sudo mount --bind /proc /mnt/root_opios/proc sudo mount --bind /sys /mnt/root_opios/sys sudo mount --bind /dev /mnt/root_opios/dev sudo mount --bind /run /mnt/root_opios/run ``` ### 1.7 — Update fstab ```bash sudo blkid /dev/mmcblk0p1 /dev/mmcblk0p2 ``` Edit `/mnt/root_opios/etc/fstab`. Replace old SD card references with: ``` UUID= /boot vfat defaults,noatime 0 2 UUID= / ext4 defaults,noatime 0 1 ``` ### 1.8 — Write extlinux.conf ```bash uname -r find /mnt/root_opios/boot -name "*.dtb" | grep orangepi-3b ``` Create `/mnt/root_opios/boot/extlinux/extlinux.conf`: ``` TIMEOUT 10 DEFAULT orangepi-os LABEL orangepi-os MENU LABEL Orange Pi OS LINUX /vmlinuz- INITRD /initrd.img- FDT /dtbs/rockchip/rk3566-orangepi-3b.dtb APPEND root=UUID= rootwait console=ttyS2,115200 console=tty1 ``` ### 1.9 — Install u-boot to eMMC hardware boot partition First check if Orange Pi OS ships u-boot binaries: ```bash find / -name "idbloader.img" -o -name "u-boot.itb" -o -name "*loader*" 2>/dev/null ``` If files exist at known paths, use them. If not, extract from SD card. The idbloader starts at sector 64 of the SD card (sectors 0-33 hold the GPT), so skip there: ```bash sudo dd if=/dev/mmcblk1 of=idbloader.img bs=512 skip=64 count=16320 sudo dd if=/dev/mmcblk1 of=u-boot.itb bs=512 skip=16384 count=8192 ``` Write to eMMC hardware boot partition: ```bash echo 0 | sudo tee /sys/block/mmcblk0/force_ro sudo mmc bootpart enable 1 1 /dev/mmcblk0 sudo dd if=idbloader.img of=/dev/mmcblk0boot0 bs=512 seek=64 sudo dd if=u-boot.itb of=/dev/mmcblk0boot0 bs=512 seek=16384 sudo sync ``` ### 1.10 — Clean up and test ```bash sudo umount /mnt/root_opios/boot sudo umount /mnt/root_opios/proc /mnt/root_opios/sys /mnt/root_opios/dev /mnt/root_opios/run sudo umount /mnt/root_opios sudo sync sudo poweroff ``` Remove SD card. Power on. u-boot logo → boot menu → Orange Pi OS from eMMC. ### Troubleshooting | Symptom | Likely cause | Fix | |---------|-------------|-----| | u-boot logo, then blank screen | EDID/HDMI handshake | Add `video=HDMI-A-1:1920x1080@60e` to APPEND line | | "No bootable device" | u-boot not written to eMMC boot part | Re-do step 1.9 | | Kernel panic: can't find root | Wrong UUID in extlinux.conf | Boot from SD, mount eMMC, fix UUID | | Nothing on screen at all | SPI flash interference? HDMI? | Re-check SPI erase, try different monitor | ## Step 2: Install Armbian (To be documented — Armbian rootfs goes into root_armbian, kernel+DTB added to shared /boot, next LABEL added to extlinux.conf.) ## Step 3: Install NixOS (To be documented — NixOS rootfs goes into root_nixos. Likely the trickiest since NixOS generates its own /boot structure.) ## Reference - Rockchip boot flow: - U-boot extlinux format: - OPi 3B bring-up: `docs/initial-bringup.md` - Storage architecture: `docs/storage-architecture.md`