{"id":49665159,"url":"https://github.com/christitustech/uboot-orangepi-rk3399","last_synced_at":"2026-05-06T15:08:09.622Z","repository":{"id":351182457,"uuid":"1209906616","full_name":"ChrisTitusTech/uboot-orangepi-rk3399","owner":"ChrisTitusTech","description":null,"archived":false,"fork":false,"pushed_at":"2026-04-14T00:14:31.000Z","size":2741,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-14T00:36:43.250Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ChrisTitusTech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-13T22:44:56.000Z","updated_at":"2026-04-14T00:14:35.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ChrisTitusTech/uboot-orangepi-rk3399","commit_stats":null,"previous_names":["christitustech/uboot-orangepi-rk3399"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/ChrisTitusTech/uboot-orangepi-rk3399","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChrisTitusTech%2Fuboot-orangepi-rk3399","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChrisTitusTech%2Fuboot-orangepi-rk3399/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChrisTitusTech%2Fuboot-orangepi-rk3399/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChrisTitusTech%2Fuboot-orangepi-rk3399/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ChrisTitusTech","download_url":"https://codeload.github.com/ChrisTitusTech/uboot-orangepi-rk3399/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChrisTitusTech%2Fuboot-orangepi-rk3399/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32699328,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-06T08:33:17.875Z","status":"ssl_error","status_checked_at":"2026-05-06T08:33:17.221Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-06T15:08:08.701Z","updated_at":"2026-05-06T15:08:09.616Z","avatar_url":"https://github.com/ChrisTitusTech.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# uboot-orangepi-800\n\nU-Boot 2022.04 bootloader package for the **Orange Pi 800** (Rockchip RK3399). Pre-built binaries sourced from Manjaro ARM 22.07. These were rebuilt based on this source, with a new dts and dtb as of 26.04.13 for use with arch linux arm. \n\nThis package provides everything needed to boot: the bootloader images, a baseline `extlinux.conf`, and the `rk3399-orangepi-800.dtb` device tree (not included in the stock `linux-aarch64` package).\n\n---\n\n## Requirements\n\n- An SD card (8GB or larger recommended)\n- A host machine running Linux\n- `parted`, `mkfs.fat`, `mkfs.ext4`, `bsdtar` (`libarchive`), `dd`, `blkid`\n- The `uboot-orangepi-800` package built locally (see below)\n\n---\n\n# Automatic Install Scripts\n\nHost machine with sdcard (8gb): *Note: Find sdX with `lsblk` and replace in the commands below.*\n\n```\ngit clone https://github.com/ChrisTitusTech/uboot-orangepi-rk3399\ncd uboot-orangepi-rk3399\nsudo ./install_sdcard.sh /dev/sdX\n```\n\nOn Orange Pi 800 after first boot:\n\n```\nsudo ./install_emmc.sh\n```\n\n# MANUAL BUILD INSTRUCTIONS\n\nNo cross-compiler needed — ships pre-built binaries. The package targets `aarch64` but contains no compiled code, so build it on any Linux host with `--ignorearch`:\n\n```bash\ngit clone https://github.com/ChrisTitusTech/uboot-orangepi-rk3399\ncd uboot-orangepi-rk3399\nCARCH=aarch64 makepkg --ignorearch\n```\n\nThis produces `uboot-orangepi-800-2022.04-1-aarch64.pkg.tar.zst` in the current directory. The `CARCH=aarch64` prefix ensures the package is tagged for the correct architecture regardless of the build host. Keep it there for the steps below.\n\n\u003e **Note**: `makepkg` is an Arch Linux tool. On non-Arch hosts, install it via your distro or use an Arch Linux container. Alternatively, on the OPi 800 itself after first boot you can run `makepkg` natively without `--ignorearch`.\n\n---\n\n## Install Arch Linux ARM on an SD Card\n\nReplace **`sdX`** with your SD card device (e.g. `sdb`). Run all commands as **root**.\n\n### Step 1 — Partition the SD card\n\n\u003e The boot partition must start at sector **62500** (~30 MB from the start) to leave room for the U-Boot images written directly to the raw device.\n\n```bash\nparted -s /dev/sdX mklabel gpt\nparted -s /dev/sdX mkpart boot fat32 62500s 1GiB\nparted -s /dev/sdX set 1 boot on\nparted -s /dev/sdX mkpart root ext4 1GiB 100%\n```\n\n### Step 2 — Format and mount\n\n```bash\nmkfs.fat -F32 -n BOOT /dev/sdX1\nmkfs.ext4 -L ROOT /dev/sdX2\nmkdir -p boot root\nmount /dev/sdX1 boot\nmount /dev/sdX2 root\n```\n\n### Step 3 — Extract the Arch Linux ARM root filesystem\n\n```bash\nwget https://archlinuxarm.org/os/ArchLinuxARM-aarch64-latest.tar.gz\nbsdtar -xpf ArchLinuxARM-aarch64-latest.tar.gz -C root\nmv root/boot/* boot/\n```\n\n### Step 4 — Install bootloader files and configure boot\n\nExtract the package onto the boot partition (installs `idbloader.img`, `u-boot.itb`, DTB, and `extlinux.conf`):\n\n```bash\nbsdtar -xf uboot-orangepi-800-*.pkg.tar.zst -C boot --strip-components=1 boot/\n```\n\nPatch `extlinux.conf` with the real root `PARTUUID`:\n\n```bash\nROOT_PARTUUID=$(blkid -s PARTUUID -o value /dev/sdX2)\nsed -i \"s|root=/dev/mmcblk1p2|root=PARTUUID=${ROOT_PARTUUID}|\" boot/extlinux/extlinux.conf\n```\n\nSet up `/etc/fstab`:\n\n```bash\nBOOT_UUID=$(blkid -s UUID -o value /dev/sdX1)\nROOT_UUID=$(blkid -s UUID -o value /dev/sdX2)\nprintf \"UUID=%s\\t/boot\\tvfat\\tdefaults\\t0 2\\nUUID=%s\\t/\\text4\\tdefaults\\t0 1\\n\" \\\n  \"$BOOT_UUID\" \"$ROOT_UUID\" \u003e\u003e root/etc/fstab\n```\n\n### Step 5 — Flash U-Boot to the SD card\n\n```bash\ndd if=boot/idbloader.img of=/dev/sdX seek=64    conv=notrunc,fsync\ndd if=boot/u-boot.itb    of=/dev/sdX seek=16384 conv=notrunc,fsync\n```\n\n### Step 6 — Copy package and unmount\n\n```bash\nmkdir -p root/home/alarm\ncp uboot-orangepi-800-*.pkg.tar.zst root/home/alarm/\nsync\numount boot root\n```\n\n---\n\n## First Boot\n\n1. Insert the SD card into the Orange Pi 800.\n2. Connect an Ethernet cable.\n3. Apply 5V USB-C power.\n\nU-Boot finds `extlinux/extlinux.conf` on the boot partition and loads the kernel automatically.\n\nLog in via SSH (use your router's DHCP table to find the IP) or serial console (**ttyS2, 1500000 baud, 8N1**):\n\n| Account | Username | Password |\n|---|---|---|\n| User | `alarm` | `alarm` |\n| Root | `root` | `root` |\n\n---\n\n## Post-Boot Setup\n\nInitialize pacman and register the package so future upgrades reflash U-Boot automatically:\n\n```bash\npacman-key --init\npacman-key --populate archlinuxarm\npacman -Sy --noconfirm --needed archlinuxarm-keyring\npacman-key --populate archlinuxarm\npacman -U /home/alarm/uboot-orangepi-800-*.pkg.tar.zst\n```\n\nThe `.install` hook will offer to reflash U-Boot to `/dev/mmcblk1` on install and upgrade.\n\n---\n\n## Optional: Copy Installation to eMMC\n\nOnce the system is running from the SD card, you can migrate it to the on-board 64 GB eMMC (`/dev/mmcblk0`) and expand the root partition to fill it. Run all commands as **root** while booted from the SD card.\n\n\u003e **Note**: This will erase everything currently on the eMMC (including any factory Android/OrangePi OS image).\n\n### Step 1 — Install rsync\n\n```bash\npacman -S rsync\n```\n\n### Step 2 — Partition the eMMC\n\n```bash\nparted -s /dev/mmcblk0 mklabel gpt\nparted -s /dev/mmcblk0 mkpart boot fat32 62500s 1GiB\nparted -s /dev/mmcblk0 set 1 boot on\nparted -s /dev/mmcblk0 mkpart root ext4 1GiB 100%\n```\n\n### Step 3 — Format\n\n```bash\nmkfs.fat -F32 -n BOOT /dev/mmcblk0p1\nmkfs.ext4 -L ROOT /dev/mmcblk0p2\n```\n\n### Step 4 — Mount eMMC partitions\n\n```bash\nmkdir -p /mnt/emmc/{boot,root}\nmount /dev/mmcblk0p1 /mnt/emmc/boot\nmount /dev/mmcblk0p2 /mnt/emmc/root\n```\n\n### Step 5 — Copy boot partition\n\n```bash\ncp -a /boot/. /mnt/emmc/boot/\n```\n\n### Step 6 — Copy root filesystem\n\nThe `--one-file-system` flag keeps rsync from crossing into `/boot` (FAT) or any other mounted filesystems:\n\n```bash\nrsync -aAX --one-file-system \\\n  --exclude=/proc --exclude=/sys --exclude=/dev \\\n  --exclude=/run  --exclude=/tmp --exclude=/mnt \\\n  / /mnt/emmc/root/\n```\n\n### Step 7 — Flash U-Boot to eMMC\n\n```bash\ndd if=/boot/idbloader.img of=/dev/mmcblk0 seek=64    conv=notrunc,fsync\ndd if=/boot/u-boot.itb    of=/dev/mmcblk0 seek=16384 conv=notrunc,fsync\n```\n\n### Step 8 — Update extlinux.conf to point at the eMMC root\n\n```bash\nEMMC_ROOT_PARTUUID=$(blkid -s PARTUUID -o value /dev/mmcblk0p2)\nsed -i \"s|root=PARTUUID=[^ ]*|root=PARTUUID=${EMMC_ROOT_PARTUUID}|\" \\\n  /mnt/emmc/boot/extlinux/extlinux.conf\n```\n\n### Step 9 — Update /etc/fstab on the eMMC root\n\n```bash\nEMMC_BOOT_UUID=$(blkid -s UUID -o value /dev/mmcblk0p1)\nEMMC_ROOT_UUID=$(blkid -s UUID -o value /dev/mmcblk0p2)\nprintf \"UUID=%s\\t/boot\\tvfat\\tdefaults\\t0 2\\nUUID=%s\\t/\\text4\\tdefaults\\t0 1\\n\" \\\n  \"$EMMC_BOOT_UUID\" \"$EMMC_ROOT_UUID\" \u003e /mnt/emmc/root/etc/fstab\n```\n\n### Step 10 — Unmount and reboot\n\n```bash\nsync\numount /mnt/emmc/boot /mnt/emmc/root\nreboot\n```\n\nAfter reboot, U-Boot will find the eMMC bootloader first (eMMC is `mmcblk0`, the primary boot device) and load the kernel from the eMMC boot partition. The SD card can be removed once the eMMC boot is confirmed working.\n\n---\n\n## Notes on Hardware Support\n\nThe bundled `rk3399-orangepi-800.dtb` is sourced from Manjaro ARM 22.07. Hardware support status based on the OPi 800 schematic (V1.8, 2022-11-08):\n\n| Hardware | Chip | Works with bundled DTB |\n|---|---|---|\n| PMIC | RK808-D | ✅ Yes (required for boot) |\n| RAM (4GB LPDDR4) | 4× LPDDR4 BGA200 | ✅ Yes |\n| eMMC (64GB) | eMMC 5.0 BGA169 | ✅ Yes |\n| SD card | TF-CKT01-009D | ✅ Yes |\n| Ethernet | YT8531C (Motorcomm 1GbE) | ✅ Yes |\n| HDMI output | RK3399 internal | ⚠️ Partial |\n| USB 2.0 / USB 3.0 | RK3399 TypeC PHY | ⚠️ Partial |\n| WiFi / Bluetooth | AP6256 (BCM43456 via SDIO+UART) | ❌ No — needs vendor kernel + firmware |\n| Audio | ES8316 codec (I2C1 + I2S0) | ❌ No — needs vendor kernel |\n| Speaker amp | XPT8871 (GPIO-controlled) | ❌ No — needs vendor kernel |\n| Keyboard MCU | HT68FB571 (USB HID via USB0) | ❌ No — needs vendor kernel |\n| VGA output | CH7517 eDP-to-VGA bridge | ❌ No — no mainline driver |\n| RTC | BL5372 (I2C) | ❌ No — needs DTS node |\n| 26-pin GPIO header | I2C / SPI / UART / PWM / GPIO | ⚠️ Partial |\n\nFor WiFi, the AP6256 uses the standard `brcmfmac` driver but requires firmware from the `linux-firmware` package and proper DTS SDIO/GPIO nodes.\n\nFor full hardware support, you must build the OrangePi vendor kernel from source — no AUR package exists:\n\n- Repository: [orangepi-xunlong/linux-orangepi](https://github.com/orangepi-xunlong/linux-orangepi)\n- Branch: `orange-pi-5.10-rk3399`\n\nAfter installing a custom kernel, U-Boot picks up the new kernel and DTB from `/boot` automatically via `extlinux/extlinux.conf`.\n\n---\n\n## Troubleshooting\n\n### No Ethernet\n\nThe board boots and HDMI/keyboard work, but Ethernet has no link.\n\n**1. Check if the interface appears (note: it may be named `end0`, not `eth0`):**\n```bash\nip link\n```\n\n**2. Check kernel messages for GMAC/PHY errors:**\n```bash\ndmesg | grep -iE 'eth|gmac|phy|motorcomm|yt8|stmmac|dwmac'\n```\n\n**Known failure: `stmmac_hw_setup: DMA engine initialization failed`**\n\nThis is caused by a PHY driver chain failure:\n\n1. The YT8531C PHY attaches as **`[unbound]` → Generic PHY** because the `motorcomm` kernel module is not loaded.\n2. The Generic PHY does not handle the YT8531C's reset GPIO, so the PHY never provides the required 125 MHz RGMII clock to the GMAC.\n3. Without that clock, the GMAC DMA reset times out → `Failed to reset the dma` → `DMA engine initialization failed` → `Hw setup failed`.\n\n**Root cause:** The `motorcomm` module must be loaded *before* the `dwmac-rk` GMAC driver probes the PHY bus at boot. If Generic PHY claims the YT8531C first, loading `motorcomm` later won't rebind it — and `ip link set end0 up` will return `RTNETLINK answers: connection timed out` because the GMAC DMA is still waiting for the RGMII clock that Generic PHY never provides.\n\n**Step 1 — make motorcomm load at boot (before GMAC probes):**\n```bash\necho \"motorcomm\" | sudo tee /etc/modules-load.d/motorcomm.conf\nreboot\n```\n\n**Step 2 — after reboot, confirm motorcomm bound the PHY (not Generic PHY):**\n```bash\ndmesg | grep -iE 'motorcomm|Generic PHY|stmmac_hw_setup|Failed to reset'\n```\nYou should see `motorcomm` in the PHY driver line and no `DMA engine initialization failed`.\n\n**Step 3 — the interface is named `end0`, not `eth0`**\n\nThe kernel renames `eth0` to `end0` via systemd predictable network naming. This is normal, but ALARM's per-interface `dhcpcd@eth0.service` won't apply to `end0`, so the interface stays down even after motorcomm fixes the PHY.\n\nEnable dhcpcd globally so it handles whatever name the interface gets:\n```bash\nsystemctl enable --now dhcpcd.service\n```\n\nOr bring it up manually for immediate access:\n```bash\nip link set end0 up\ndhcpcd end0\n```\n\n**Immediate fix without reboot — manually rebind the PHY (if you cannot reboot):**\n```bash\necho \"stmmac-0:00\" \u003e /sys/bus/mdio_bus/drivers/\"Generic PHY\"/unbind\necho \"stmmac-0:00\" \u003e /sys/bus/mdio_bus/drivers/motorcomm/bind\nip link set end0 up\ndhcpcd end0\n```\n\n**Check if the Motorcomm PHY driver is available:**\n```bash\nmodinfo motorcomm 2\u003e/dev/null || echo \"module not found\"\n```\n\nIf `modinfo motorcomm` returns \"Module not found\", the mainline `linux-aarch64` kernel was built without it and the vendor kernel is required (see Hardware Support table above).\n\n**Summary of causes:**\n\n| Cause | Symptom | Fix |\n|---|---|---|\n| `motorcomm` not loaded at boot | `PHY driver [Generic PHY]`, `Failed to reset the dma`, `connection timed out` | `echo motorcomm \u003e /etc/modules-load.d/motorcomm.conf` + reboot |\n| `dhcpcd@eth0.service` active but interface is `end0` | motorcomm loads fine, DMA OK, but no IP address | `systemctl enable --now dhcpcd.service` |\n| PHY driver missing from kernel | `modinfo motorcomm` → \"Module not found\" | Needs vendor kernel |\n| DTB/mainline GMAC clock mismatch | `dwmac-rk` probe fails entirely in `dmesg` | Needs vendor kernel |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchristitustech%2Fuboot-orangepi-rk3399","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchristitustech%2Fuboot-orangepi-rk3399","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchristitustech%2Fuboot-orangepi-rk3399/lists"}