← Retour aux projets
9front
#9front ARM64 — Orange Pi 4 Pro
Porting 9front to the Orange Pi 4 Pro (Allwinner A733).
#Quick Start
make help # show available targets make kernel # build kernel (boots QEMU, compiles, extracts) make sdcard # build bootable SD card image
Flash to SD card:
sudo dd if=images/orangepi4pro/sdcard.img of=/dev/sdX bs=1M status=progress
#Build Targets
| Target | Description |
|---|---|
make portdisk |
Pack port/a733/ into FAT image for QEMU transfer |
make kernel |
Build kernel inside 9front QEMU (automated) |
make sdcard |
Build bootable SD card image (64MB) |
make boot |
Boot 9front QEMU (snapshot mode) |
make dev |
Boot QEMU with port disk attached (interactive) |
make serial-start |
Start tmux + picocom serial capture |
make serial-fresh |
Truncate the serial log, then start capture |
make serial-stop |
Stop tmux + picocom serial capture |
make serial-status |
Show serial capture status |
make serial-tail |
Tail the current serial log |
make serial-attach |
Attach to the serial tmux session |
make clean |
Remove build artifacts |
#SD Card Image Layout
| Offset | Content |
|---|---|
| 8 KiB | boot0 — Allwinner SPL (loads U-Boot) |
| 16.8 MiB | boot_package — U-Boot + monitor + SCP firmware |
| 32 MiB | FAT32 partition — 9a733.u (kernel) + boot.scr |
#Target Hardware
| SoC | Allwinner A733 (sun60iw2) |
| CPU | 8-core ARM64 — 4× Cortex-A76 + 4× Cortex-A55 |
| RAM | 2/4/8/16 GB LPDDR |
| Storage | eMMC, SD, PCIe (NVMe), USB 3.0 |
| Network | GbE (Synopsys GMAC), WiFi (AIC8800) |
| Display | HDMI, eDP, DSI, LVDS |
| Console | UART0 at 0x02500000 (ttyS0, 115200) |
#Port Files
port/a733/ ├── NOTES.md # Hardware addresses, design decisions ├── a733 # Kernel config ├── bootargs.c # Local DTB/bootargs handling override ├── clock.c # Local ARM generic-timer override for bring-up sequencing ├── dat.h # Data structures (from arm64/) ├── fns.h # Function declarations and local wrapper prototypes ├── gic.c # Local GICv3 mapping/bring-up override ├── io.h # I/O and interrupt definitions ├── l.s # Early boot assembly + UART breadcrumbs/wrappers ├── lcd.c # Display init (WIP — inherits U-Boot framebuffer) ├── main.c # Local early init override and bootstrap ordering ├── mem.c # Local temporary MMU/map setup override ├── mem.h # Memory map + A733 peripheral addresses ├── mkfile # Build rules for local overrides ├── page.c # Local page allocator instrumentation ├── pciaw.c # PCIe host controller stub ├── proc.c # Local scheduler/process instrumentation ├── screen.c # Framebuffer console (WIP) ├── screen.h # Screen declarations ├── trap.c # Local trap/syscall/fault instrumentation ├── uartaw.c # Allwinner UART driver (8250-compat, MMIO) └── userinit.c # Local first-process instrumentation
Shared arm64 code still reused from sys/src/9/arm64/ where not locally overridden:
cache.v8.s, fpu.c, mmu.c, sysreg.c
#Development Workflow
- Edit files in
port/a733/on the host make portdisk— packs into FAT imagemake dev— boots QEMU with port disk attached- Inside 9front:
dossrv -f /dev/sdG0/data portdisk mount -c /srv/portdisk /n/port dircp /n/port/a733 /sys/src/9/a733 cd /sys/src/9/a733 && mk
- Or:
make kernelto automate steps 2–4 + extract
#Prerequisites
- QEMU (
qemu-system-aarch64) - mtools (
mcopy,mformat,mdir) - expect (
expect) - mkimage (
u-boot-tools) - tmux + picocom (for
make serial-*hardware logs) - qemu-user-static (for building vendor U-Boot boot blobs)
- ARM cross-compiler (
gcc-arm-linux-gnueabi, for vendor U-Boot only)
Pinned hardware bootstrap blobs are kept under bootstrap/orangepi4pro/.
Generated outputs stay in images/<board>/.
#Peripheral Status
| Peripheral | Driver | Status |
|---|---|---|
| GICv3 | gic.c |
✅ Local mapping/bring-up override |
| ARM Timer | clock.c |
✅ Local generic-timer override; IRQ timing still under bring-up |
| UART (serial) | uartaw.c |
✅ Written and used for breadcrumbs |
| Trap/syscall path | trap.c |
🔧 Instrumented for pid1 fault/syscall debugging |
| Scheduler/process path | proc.c + userinit.c |
🔧 Instrumented through first runnable process |
| PCIe | pciaw.c |
🔧 Stub (DesignWare init needed) |
| Framebuffer | screen.c + lcd.c |
🔧 Written, not yet in config |
| NVMe | port/sdnvme.c |
⏳ Needs PCIe |
| USB XHCI | port/usbxhci.c |
⏳ Needs testing |
| Ethernet | — | 🆕 Not started (Synopsys GMAC) |
| SD/eMMC | — | 🆕 Not started (Allwinner MMC) |
#Current Bring-up Status
- Raw boot chain is working: Boot0 → ATF → U-Boot →
boot.scr - U-Boot accepts the Linux
Imagewrapper and DTB and reachesStarting kernel ... - The kernel now gets past the MMU transition, high-virtual handoff,
main(),pageinit(), scheduler handoff,proc0(),init0(), and the firsttouser()edge - Latest captured breadcrumbs/log end after resolving pid1's first user stack write fault:
...STZ5567890rspciaw...1234tuiI...JUvwxy[]...}kl...mnoABCDEFGHIpq pid1 fault[0] ... far 0x3ffffefe90 write pid1 fault[0] resolved pid1 ureg preexit pc 0x10034 ... psr 0x80
- Current work is focused on the first EL0 fault-return/syscall path for pid1, not boot media, DTB loading, serial capture, or the initial MMU enable
Detailed notes are in docs/BRINGUP-STATUS.md.
#Serial Monitoring
Default serial capture settings:
- device:
/dev/ttyUSB0 - baud:
115200 - tmux session:
serial - log:
/workspace/tmp/serial-boot.log
Use make serial-fresh, make serial-start, make serial-status, make serial-tail, make serial-attach, and make serial-stop.
#Repository Layout Convention
vendors/<name>/— checked-out upstream source trees and submodulesbootstrap/<board>/— checked-in board bootstrap binaries needed for hardware bring-upimages/<board>/— board-specific generated images and emulator/runtime assetsport/a733/— kernel port sources
#Vendor Resources
- BSP: orangepi-xunlong/orangepi-build → local checkout at
vendors/orangepi-build/ - U-Boot fork:
v2018.05-sun60iw2branch on gitee - Board config:
orangepi4pro.conf→sun60iw2family - DTB:
allwinner/sun60i-a733-orangepi-4-pro.dtb