add eMMC multi-boot guide: 3-OS layout, Step 1 walkthrough
This commit is contained in:
parent
384917e12e
commit
af398bafb5
1 changed files with 203 additions and 0 deletions
203
docs/emmc-multiboot.md
Normal file
203
docs/emmc-multiboot.md
Normal file
|
|
@ -0,0 +1,203 @@
|
||||||
|
# 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
|
||||||
|
|
||||||
|
```
|
||||||
|
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 root1 (Orange Pi OS Arch)
|
||||||
|
├── mmcblk1p3 ext4 85GB root2 (Armbian)
|
||||||
|
├── mmcblk1p4 ext4 ~84GB root3 (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 (Orange Pi OS, leaves root2/root3 ready)
|
||||||
|
|
||||||
|
### 1.1 — Identify devices
|
||||||
|
|
||||||
|
Run on the running Orange Pi OS (booted from SD):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
lsblk
|
||||||
|
mount | grep mmcblk
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: `mmcblk0` = SD card (boot device), `mmcblk1` = eMMC (target).
|
||||||
|
|
||||||
|
### 1.2 — Wipe eMMC partition table
|
||||||
|
|
||||||
|
**Destroys everything on eMMC.** Skip if eMMC is already empty.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo sgdisk --zap-all /dev/mmcblk1
|
||||||
|
sudo blkdiscard /dev/mmcblk1 # optional
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.3 — Partition eMMC
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo gdisk /dev/mmcblk1
|
||||||
|
```
|
||||||
|
|
||||||
|
In `gdisk` interactive mode:
|
||||||
|
|
||||||
|
```
|
||||||
|
o (new GPT)
|
||||||
|
n 1 default +1G ef00 name=boot
|
||||||
|
n 2 default +85G 8300 name=root1
|
||||||
|
n 3 default +85G 8300 name=root2
|
||||||
|
n 4 default default 8300 name=root3
|
||||||
|
w (write, confirm 'y')
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.4 — Create filesystems
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo mkfs.vfat -F 32 -n BOOT /dev/mmcblk1p1
|
||||||
|
sudo mkfs.ext4 -L root1 /dev/mmcblk1p2
|
||||||
|
sudo mkfs.ext4 -L root2 /dev/mmcblk1p3
|
||||||
|
sudo mkfs.ext4 -L root3 /dev/mmcblk1p4
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.5 — Mount and rsync the live rootfs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo mkdir -p /mnt/root1
|
||||||
|
sudo mount /dev/mmcblk1p2 /mnt/root1
|
||||||
|
sudo mkdir -p /mnt/root1/boot
|
||||||
|
sudo mount /dev/mmcblk1p1 /mnt/root1/boot
|
||||||
|
|
||||||
|
sudo rsync -axHAWX --info=progress2 / /mnt/root1/
|
||||||
|
```
|
||||||
|
|
||||||
|
Flags: archive, stay-on-filesystem (critical — skips /proc, /sys, /dev), preserve
|
||||||
|
hardlinks/ACLs/xattrs, copy whole files (faster locally).
|
||||||
|
|
||||||
|
### 1.6 — Bind mount virtual filesystems
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo mkdir -p /mnt/root1/{proc,sys,dev,run,tmp}
|
||||||
|
sudo mount --bind /proc /mnt/root1/proc
|
||||||
|
sudo mount --bind /sys /mnt/root1/sys
|
||||||
|
sudo mount --bind /dev /mnt/root1/dev
|
||||||
|
sudo mount --bind /run /mnt/root1/run
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.7 — Update fstab
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo blkid /dev/mmcblk1p1 /dev/mmcblk1p2
|
||||||
|
```
|
||||||
|
|
||||||
|
Edit `/mnt/root1/etc/fstab`. Replace old SD card references with:
|
||||||
|
|
||||||
|
```
|
||||||
|
UUID=<boot-UUID> /boot vfat defaults,noatime 0 2
|
||||||
|
UUID=<root1-UUID> / ext4 defaults,noatime 0 1
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.8 — Write extlinux.conf
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uname -r
|
||||||
|
find /mnt/root1/boot -name "*.dtb" | grep orangepi-3b
|
||||||
|
```
|
||||||
|
|
||||||
|
Create `/mnt/root1/boot/extlinux/extlinux.conf`:
|
||||||
|
|
||||||
|
```
|
||||||
|
TIMEOUT 10
|
||||||
|
DEFAULT orangepi-os
|
||||||
|
|
||||||
|
LABEL orangepi-os
|
||||||
|
MENU LABEL Orange Pi OS
|
||||||
|
LINUX /vmlinuz-<kernel-version>
|
||||||
|
INITRD /initrd.img-<kernel-version>
|
||||||
|
FDT /dtbs/rockchip/rk3566-orangepi-3b.dtb
|
||||||
|
APPEND root=UUID=<root1-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:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo dd if=/dev/mmcblk0 of=idbloader.img bs=512 count=16384
|
||||||
|
sudo dd if=/dev/mmcblk0 of=u-boot.itb bs=512 skip=16384 count=8192
|
||||||
|
```
|
||||||
|
|
||||||
|
Write to eMMC hardware boot partition:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo 0 | sudo tee /sys/block/mmcblk1/force_ro
|
||||||
|
sudo mmc bootpart enable 1 1 /dev/mmcblk1
|
||||||
|
sudo dd if=idbloader.img of=/dev/mmcblk1boot0 bs=512 seek=64
|
||||||
|
sudo dd if=u-boot.itb of=/dev/mmcblk1boot0 bs=512 seek=16384
|
||||||
|
sudo sync
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.10 — Clean up and test
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo umount /mnt/root1/boot
|
||||||
|
sudo umount /mnt/root1/proc /mnt/root1/sys /mnt/root1/dev /mnt/root1/run
|
||||||
|
sudo umount /mnt/root1
|
||||||
|
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 root2, kernel+DTB added to shared /boot, next LABEL added to extlinux.conf.)
|
||||||
|
|
||||||
|
## Step 3: Install NixOS
|
||||||
|
|
||||||
|
(To be documented — NixOS rootfs goes into root3. Likely the trickiest since NixOS generates its own /boot structure.)
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
- Rockchip boot flow: <https://opensource.rock-chips.com/wiki_Boot_option>
|
||||||
|
- U-boot extlinux format: <https://docs.u-boot.org/en/stable/develop/distro.html>
|
||||||
|
- OPi 3B bring-up: `docs/initial-bringup.md`
|
||||||
|
- Storage architecture: `docs/storage-architecture.md`
|
||||||
Loading…
Add table
Add a link
Reference in a new issue