Use the official Image Builder (IB) to build a customized OpenWrt image:PACKAGES= select packages,FILES= inject overlay,PROFILE= set device, artifact comes with sha256. All FILES= semantic assertions come from upstream include/rootfs.mk and IB target/imagebuilder/files/Makefile walkthrough (baseline see Offline Baseline).
Determine Task Type
- IB direct output: official ToH lists the device, use official IB to produce sysupgrade/factory image → this Skill.
- ophub repack: Amlogic/box (N1 etc.) write eMMC → this Skill only handles producing
rootfs.tar.gz, repack handed over toopenwrt-amlogic-remake。 - runtime configuration only: device already running, just change UCI/init.d/mount → do not build image, hand over to
openwrt-uci-defaults/openwrt-procd-init/openwrt-storage-mount。
Prerequisites / Preflight
# 1. 平台:IB 官方发布为 Linux-x86_64;macOS/Windows 用 Docker 内 Linux
uname -m # 期望 x86_64
make --version >/dev/null && echo make-ok
# 2. 磁盘:IB 解压 + 下载缓存 + 产物,预留 ≥5GB
df -h .
3. Tool: .tar.zst extraction requires zstd (OpenWrt 24.10+ IB is .tar.zst, older versions .tar.xz)
command -v curl tar make sha256sum zstd || true
4. Download domain reachable (IB pulls ipk per repositories.conf at runtime)curl -fsI https://downloads.openwrt.org/releases/ >/dev/null && echo net-ok
缺 `zstd` 时:`sudo apt-get install -y zstd`(Ubuntu)。
**Offline Baseline**:OpenWrt **25.12.5**(IB 行为走读上游 `include/rootfs.mk`、`target/imagebuilder/files/Makefile`,日期 2026-09-02,不自动更新)。之后版本的语义变化以官方源为准。
## Mandatory Device Contracts
构建前确认并记录,**不确定禁止编造**:
- 目标设备型号 + OpenWrt `PROFILE` 名——以目标版本 IB 目录下 `make info` 输出为唯一权威。PROFILE 对不上设备就是错镜像;
- OpenWrt 版本与 target 路径(如 `x86/64`、`ramips/mt7621`、`armsr/64`)——下载站路径恒为 `arch/subarch`;
- 产物形态:sysupgrade / factory / combined(-efi) / rootfs.tar.gz(下游用途决定);
- 若走 ophub 重打包:目标 board 型号由 remake 链确认,本 Skill 不猜。
设备不在 ToH、或 IB 无对应 PROFILE → 停下路由 `openwrt-amlogic-remake` 或查官方 ToH,不要"挑个相近的 PROFILE 试试"。
## Capability Boundaries + Hand-off
边界:本 Skill 只管"官方 IB 构建镜像"这一段;设备端刷写/重打包、运行时配置、发布门禁均不在内:
| 下一步 | Skill |
|---|---|
| 拿 rootfs.tar.gz 重打包盒子 eMMC 镜像(N1/Amlogic) | `openwrt-amlogic-remake` |
| init.d 脚本怎么写(rc.common/START=/STOP=) | `openwrt-procd-init` |
| uci-defaults 首启配置语义与幂等规范 | `openwrt-uci-defaults` |
| 磁盘挂载/USB 存储配置进镜像 | `openwrt-storage-mount` |
| 产物命名/校验和/发布门禁 | `fw-release-gate` |
| 刷写后变砖/串口救援 | `openwrt-serial-recovery` |
## Workflow
### 1. 下载并缓存 Image Builder
```bash
VER=25.12.5; TARGET_PATH=x86/64 # 按实际设备改
BASE="https://downloads.openwrt.org/releases/${VER}/targets/${TARGET_PATH}/openwrt-imagebuilder-${VER}-${TARGET_PATH//\//-}.Linux-x86_64"
mkdir -p ib-cache && cd ib-cache
curl -fsSL --retry 3 -o ib.tar.zst "${BASE}.tar.zst" \
|| { curl -fsSL --retry 3 -o ib.tar.xz "${BASE}.tar.xz"; DECOMP=(-J); }
mkdir -p "openwrt-imagebuilder-${VER}" && tar ${DECOMP:-(--zstd)} -xf ib.tar.* -C "openwrt-imagebuilder-${VER}" --strip-components=1
cd "openwrt-imagebuilder-${VER}"
(production template build-template.sh:72-99: try .tar.zstfirst, fall back to .tar.xzon 404; IB directory cached and reused by version.)
2. Verify PROFILE empirically
make info # 列出 Current Target / Available Profiles / 每个 Profile 的 Packages
Expected output contains the target device entry; compare the device model given by the user with the SupportedDevices field. Stop if not found (see Contracts).
3. Assemble PACKAGES (three-layer stacking pattern)
Production template (build-template.sh:167-176) splits packages into three layers of text files, concatenated after removing comments:
COMMON_PKGS=$(grep -v '^#' packages.common.txt | tr '\n' ' ') # 全设备通用
TIER_PKGS=$(grep -v '^#' packages.tier-pro.txt | tr '\n' ' ') # 档位/场景层
ARCH_PKGS=$(grep -v '^#' arch/packages.txt | tr '\n' ' ') # 架构专属层
PACKAGES="${COMMON_PKGS} ${TIER_PKGS} ${ARCH_PKGS}"
Syntax (IB Makefile image help text and BUILD_PACKAGES filter logic, L143-147):PACKAGES="pkg-a pkg-b" append;PACKAGES="-pkg-c" from the default setremove pkg-c. First make manifest dry-run the manifest and then produce the image.
4. Prepare FILES= overlay
The overlay is "a directory tree laid out by rootfs-relative paths", its actual appearance (tinynas-files/):
files/
├── etc/init.d/tinynas-boot # procd 脚本:#!/bin/sh /etc/rc.common + START=
├── etc/uci-defaults/50-tinynas # 首启幂等配置,末行 exit 0
├── etc/config/samba4 # UCI 配置
├── etc/hotplug.d/block/50-disk # 热插拔脚本
├── usr/bin/tinynas-machine-id # 可执行工具
└── www/index.html # LuCI 之外的自有页面
Injection semantics (authoritative basis rootfs.mk:71-74 prepare_rootfs + rules.mk:475-488 file_copy) — see details item by item files-injection-semantics:
- overlay-style merge, not whole-package replacement:
file_copycopies the overlaycponto the already-installed rootfs. Files at the same path are overwritten; existing files not touched by the overlayare kept as-is; - delete same-named symlinks first: before merging, first clear symlinks on paths in the rootfs that will be overwritten (
rules.mk:480-486), to avoid cp following the link and writing through; - init.d scriptsdo not manually place
/etc/rc.d/:prepare_rootfsfor those with#!/bin/sh /etc/rc.commonshebang/etc/init.d/*automatically executesenableto generate enable links; only those listed inDISABLED_SERVICESaredisable(rootfs.mk:104-113); - permission bits are preserved: files under init.d/cgi-bin/usr/bin/hotplug.d missing
+xin the image will also be missing (cp -asemantics); uci-defaults is sourced by sh, does not need +x.
5. Build and collect
rm -rf files && mkdir -p files && cp -a /path/to/your-overlay/. files/
make image \
PROFILE="<profile-from-make-info>" \
PACKAGES="${PACKAGES}" \
FILES="$(pwd)/files"
# 可选:BIN_DIR= 输出目录 EXTRA_IMAGE_NAME= 名字后缀
# DISABLED_SERVICES="svc1 svc2" ROOTFS_PARTSIZE=<MB>
How parameters are passed: IB image target first _check_profile verifies PROFILE (nonexistent directly errors out), then FILES→USER_FILES、PACKAGES→USER_PACKAGES passes in prepare_rootfs(IB Makefile L354-364, L282). The flow is package_install (opkg --offline-root install packages) → prepare_rootfs (overlay merge + postinst replay + init.d enable) → build_image → sha256 checksum (L176-187).
Collect and verify (production template build-template.sh:187-229):
OUT=bin/targets/<arch>/<subarch>
for f in "${OUT}"/*.img.gz "${OUT}"/*-sysupgrade.bin "${OUT}"/*-factory.bin "${OUT}"/*rootfs.tar.gz; do
[ -f "$f" ] || continue
cp "$f" dist/ && (cd dist && sha256sum "$(basename "$f")" > "$(basename "$f").sha256")
done
Artifact naming should include a kind suffix (sysupgrade/factory/combined/combined-efi/rootfs); for release gating see fw-release-gate。
Validation Gates
make infocan list the target PROFILE (otherwise stop at step 2);make manifest PROFILE=... PACKAGES=...dry-run the package list to confirm no dependency conflicts and no unexpected removals;make imageexit code 0, andnopostinst script ... has failedlines — a failed postinst replay will fail the build (rootfs.mk:86-94);- artifacts exist and
sha256sum -cpasses; - use
unsquashfs -lor unpack the rootfs for spot checks: overlaid files are in place,/etc/rc.d/the enable links in it are generated by IB and there are no manual leftovers; - build success ≠ hardware usable: before real-device flash validation, label all conclusions as
Build Verification Only; flash validation and in-loop testing are handed over tofw-hil-testing。
Pitfalls
- Do nottreat FILES as a "full rootfs replacement" — it is an overlay-style merge; trying to "shrink the rootfs" with a trimmed-down files/ directory will not delete any existing files.
- Do notmanually place
/etc/rc.d/Sxx*links in the overlay — IB will automatically recreate them by enabling per init.d + rc.common, so manual placement is redundant and will be rejected by the lint gate (the production templatebuild-template.sh:155-157explicitly prohibits it). - Do notassume that "feeding rootfs.tar.gz to IB will produce an image" — the input to the official IB is
repositories.confprovided by ipk(opkg --offline-rootpackage installation, IB Makefile L93-97); rootfs.tar.gz is only theCONFIG_TARGET_ROOTFS_TARGZwhen the target hasartifact(image.mk:372-376), and what ophub repacking consumes is armsr'sarmv8 generic rootfs.tar.gz(ophub README, baselinec593d56)。 - Do notfabricate PROFILE/device compatibility names — only recognize
make info。 - Do notignore overlay permission bits and script conventions: init.d missing a
rc.commonshebang orSTART=, or uci-defaults missing aexit 0on the last line will all be blocked by the gate (build-template.sh:148-165)。 - Do notexpect IB to directly produce a box eMMC image beyond rootfs.tar.gz — that is the job of the remake chain.
On-Demand Resources
- files-injection-semantics: FILES=/prepare_rootfs item-by-item semantics, for reading when designing the overlay or troubleshooting "files didn't get in / services didn't auto-start".
- packages-layering: three-layer package stacking and
-pkgremoval, for reading when organizing large PACKAGES lists. - reproducible-build: SOURCE_DATE_EPOCH and reproducible builds, for reading when producing verifiable images in CI.
Official Sources
- Image Builder User Guide
- OpenWrt official downloads (IB and images)
- OpenWrt Table of Hardware
- upstream include/rootfs.mk
- upstream target/imagebuilder files/Makefile
Privacy
This Skill only operates on the local build environment and official download sources; it does not collect or upload user data or credentials; do not put private signing keys or license files into an overlay that will be shared.