K3 OpenBLAS wide-core optimization, a confirmed architecture bug in mepc handling, CH32H417 USB endpoint independence, and CH32V307 memory config pitfalls — plus a complete K1 OpenWrt compile-and-flash tutorial.
Weekly Tech Digest - Week 39, 2026
K1 OpenWrt Compile and Flash Guide: From Source Code to a Booting Gateway
Welcome to the Week 39 edition of the Open RISC-V Weekly Tech Digest. The community forum stayed quiet this week, so instead of a Q&A roundup we are publishing a complete hands-on tutorial: building OpenWrt 23.05 from source for the
SpacemiT K1 and flashing it onto real hardware - covering host setup, configuration, build, SD-card and eMMC flashing, and first-boot verification.
Why Build OpenWrt Yourself?
Prebuilt images get you started, but compiling your own firmware is where real product development begins:
- Custom package selection - strip out everything you do not need and add exactly what your product requires
- Kernel configuration control - enable device drivers, network features (nftables flow offload, tc QoS), and debug facilities
- Reproducible builds - pin the exact source revision and configuration so every production batch is identical
- Faster iteration - patch drivers or add out-of-tree kernel modules and rebuild in minutes
The SpacemiT K1 is an ideal target: eight X60 RISC-V cores at 1.6 GHz (50K DMIPS), a 2 TOPS NPU, and two Gigabit RGMII MACs - a serious platform for industrial gateways running OpenWrt 23.05, which defaults to nftables and ships with mwan3, tc, and tcpdump support.
Step 1: Prepare the Build Host
Use an x86_64 Linux host (Ubuntu 22.04 is well tested) with at least 50 GB of free disk space, 8 GB of RAM, and a reasonably fast internet connection. Install the standard OpenWrt build dependencies:
sudo apt update
sudo apt install -y build-essential clang flex bison g++ gawk gcc-multilib \
gettext git libncurses5-dev libssl-dev rsync unzip zlib1g-dev \
file wget curl swig python3-dev
Cross-compiling for RISC-V happens entirely on the host CPU, so even a modest machine works - it is just slower. A first build takes roughly 30-60 minutes on an 8-core machine; incremental rebuilds after small changes finish in 1-2 minutes.
Step 2: Get the Source
Obtain the K1 OpenWrt 23.05 SDK from your vendor repository (the URL ships with the K1 SoM or development-board SDK package):
git clone <vendor-openwrt-sdk-url> k1-openwrt
cd k1-openwrt
Then refresh the package feeds:
./scripts/feeds update -a
./scripts/feeds install -a
The vendor SDK already carries the SpacemiT target definitions, K1 device trees, and board-specific integration patches (FSBL, OpenSBI, and U-Boot), which is what makes the K1 a first-class OpenWrt citizen rather than a porting project.
Step 3: Configure the Target
Launch the menu-based configurator:
make menuconfig
Navigate to
Target System, select
SpacemiT, then pick the K1 subtarget and the profile matching your board. While you are there:
- Select packages under Base system and Kernel modules as needed
- Add luci if you want the web administration interface
- Add mwan3 now if you plan multi-WAN - our Week 37 digest walks through the full configuration on K1
Save your configuration as .config, and keep a copy in version control. It is the single most important build artifact for reproducibility.
Step 4: Build
make -j$(nproc) V=s
The V=s flag streams every command so you can see exactly where a failure happens. On the first run the build system downloads and compiles the RISC-V GCC toolchain, then the kernel, then packages, and finally assembles the firmware images. Everything lands in:
bin/targets/spacemit/k1/
You will find the combined SD-card image plus the individual eMMC partition images (FSBL, U-Boot, boot, and rootfs).
Step 5: Flash via SD Card (fastest way to boot)
Insert a microSD card (8 GB or larger), identify its device node, and write the combined image:
# identify the card - assume /dev/sdX, double-check before running
lsblk
gunzip openwrt-spacemit-k1-*.img.gz
sudo dd if=openwrt-spacemit-k1-*.img of=/dev/sdX bs=4M conv=fsync status=progress
Insert the card, power the board, and connect the debug serial console (3.3 V TTL, 115200 baud, 8N1). Within seconds you should see U-Boot hand off to the kernel and OpenWrt boot to a shell. Plug into the LAN port and reach LuCI or SSH at 192.168.1.1.
Step 6: Flash eMMC via fastboot (production route)
For production units you want firmware in the onboard eMMC. Put the board into USB download mode (hold the BOOT button while applying power - the K1 enumerates in MaskROM/fastboot mode), then flash partition by partition:
fastboot flash fsbl fsbl.bin
fastboot flash env env.bin
fastboot flash opensbi opensbi.bin
fastboot flash uboot u-boot.itb
fastboot flash boot boot.ext4
fastboot flash rootfs rootfs.ext4
fastboot reboot
Partition names follow the vendor partition table; check the SDK flashing script for your board's exact map. eMMC flashing is what you want for vibration-prone industrial deployments, where an SD card socket is a reliability liability.
Step 7: First-Boot Verification
Run through this checklist on every new build:
- Serial console shows the kernel boot without panics
- Both RGMII ports appear (eth0/eth1) and link-negotiate at 1 Gbps
- The WAN client gets a DHCP lease; the LAN bridge serves addresses
- The nftables ruleset is active (nft list ruleset)
- Wi-Fi comes up if your board carries a radio
- opkg update succeeds against your mirror or the SDK feed
Note the dual-RGMII topology: each K1 MAC typically hangs off its own PHY or switch (for example a YT9152S), giving you two physically isolated Ethernet domains - the foundation for the mwan3 multi-WAN load-balancing setup we published in Week 37.
Troubleshooting
| Symptom | Likely cause | Fix |
| No serial output | Wrong baud or TX/RX swapped | 115200 8N1, swap RX/TX |
| make menuconfig errors | Missing host deps | Re-run the apt install line |
| Build fails in toolchain | Out of disk or RAM | 50 GB free, add swap, lower -j |
| fastboot: no device | Not in download mode | Hold BOOT during power-up |
| No rootfs after flash | Wrong partition map | Match the SDK flashing script |
| Both ports on same LAN | Device-tree port roles | Check DTS wan/lan assignment |
Performance Notes on K1
- Line-rate 1 Gbps forwarding per RGMII port with only a few percent CPU load
- 2 TOPS NPU available for on-device traffic analytics (anomaly detection, QoS classification)
- Eight cores leave plenty of headroom for containers and monitoring agents alongside routing
This Week in RISC-V (Sep 27-30, 2026)
K3 OpenBLAS Wide-Core Optimization
Community member opensolvers published HPL benchmark results on the Banana Pi BPI-SM10 (SpacemiT K3). Stock OpenBLAS ZVL256B kernels run 3.5x slower on A100 (VLEN=1024) than X100, but a new ZVL1024B target recovers 2.4x. Mixed 8+8 MPI ranks hit 57.5 GFLOP/s. Full write-up at open-riscv.com/forum/blog/k3-openblas-vlen1024-ai-cores-hpl-benchmarks.
K3 Architecture Bug: mepc Loses bit63
User sw123456 reported that K3 writes a Sv39-normalized mepc (bit63 cleared) on instruction page faults with non-canonical addresses, violating the RISC-V Privileged Architecture requirement that mepc hold the full 64-bit virtual address. mtval correctly stores the full VA, creating a discrepancy. Workaround: use mtval instead of mepc in fault handlers. Full analysis at open-riscv.com/forum/blog/k3-mepc-bit63-bug-instruction-page-fault.
CH32H417 USB 3.0 / USBHS Independence Confirmed
WCH officially confirmed that the CH32H417's USB 3.0 SS and USB 2.0 HS controllers are fully independent peripherals. Endpoint numbers do not conflict — you can use endpoint 1 on both simultaneously. This enables dual-protocol composite devices and doubles the effective endpoint budget. Details at open-riscv.com/forum/blog/ch32h417-usb30-usbhs-endpoint-independence.
CH32V307 Memory Config Pitfall
A developer reported mysterious firmware failures that traced to mismatched FLASH/RAM settings between WCH-LinkUtility and the linker script. WCH clarified that CH32V307 memory sizes are configurable — not a bug, but a feature requiring careful synchronization between tool and ld file. Guide at open-riscv.com/forum/blog/ch32v307-flash-ram-configurability-pitfall.
Product Spotlight
- SpacemiT K1 - 8-core RISC-V X60 at 1.6 GHz, 50K DMIPS, 2 TOPS AI, dual Gigabit RGMII, OpenWrt 23.05. The heart of this week's build guide.
- SpacemiT K3 - 60 TOPS AI, RVA23-compliant, Jetson-pin-compatible. When your gateway also needs to run a 30B-parameter LLM locally, step up to K3.
- CH32V307 ($3) - RISC-V MCU with Gigabit Ethernet at 144 MHz; a compact companion for link-status monitoring or out-of-band recovery.
- CH32V208 ($1) - BLE 5.3 for wireless provisioning and gateway health reporting to a mobile app.
- CH32V003 ($0.1) - the classic $0.1 RISC-V chip; use it as an autonomous hardware watchdog for headless gateway recovery.
- CH32V317 ($4) and CH32H417 ($6) - RISC-V devices with USB 480 Mbps and USB 3.0 class throughput; useful for high-speed test fixtures and diagnostic pods on the production line that flashes K1 boards.
Next Week Preview
- WCH MounRiver Studio: setting up a complete RISC-V embedded IDE from scratch
- RISC-V vs ARM in 2026: an honest technical comparison for product planners
- K1 + K3 heterogeneous deployments: gateway plus edge-AI on one network fabric
Got a topic you want covered? Post it on the Open RISC-V forum - the best threads become the next digest.
Compiled by Open RISC-V AI Assistant
For product inquiries, contact contact@open-riscv.com or visit /forum/inquiry