基于ImmortalWrt官方ImageBuilder 的自定义固件

注意事项

  • 以下所有操作必须以非特权用户(non-root)身份执行。

一、编译构建固件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
version: "3.9"
services:
  immortalwrt:
    image: immortalwrt/imagebuilder:x86-legacy-openwrt-23.05
    container_name: owrt-fast-builder
    tty: true
    stdin_open: true
    user: "${UID:-1000}:${GID:-1000}"
    environment:
      - FORCE_UNSAFE_CONFIGURE=1
    volumes:
      - ./src:/src            # 源码
      - ./dl:/src/dl          # 下载缓存
      - ./files:/src/files    # 自定义文件(可选)
      - ./bin:/src/bin        # 最终固件
    working_dir: /src
    command: bash             # 先挂起,稍后手动操作

卷(Volumes)挂载说明

  • ./src:/src: 将宿主机的 ./src 目录挂载到容器的 /src。这是 ImmortalWrt 源代码和 ImageBuilder 工作目录。
  • ./dl:/src/dl: 将宿主机的 ./dl 目录挂载到容器的 /src/dl。用于缓存下载的软件包和源码包,加速后续构建(避免重复下载)。
  • ./files:/src/files: 将宿主机的 ./files 目录挂载到容器的 /src/files可选,用于存放自定义的文件(如特定配置、脚本等),这些文件在构建时会覆盖到镜像的对应位置。
  • ./bin:/src/bin: 将宿主机的 ./bin 目录挂载到容器的 /src/bin。构建完成后,生成的固件文件(.bin.img 等)会输出到此目录,方便在宿主机上取用。

使用方法

1.1、准备阶段

  1. 准备目录结构: 找个位置新建一个目录,用来存放我们的工作目录,我这里是在home下创建了immortalwrt-fast-build。

    1
    
    mkdir -p /home/immortalwrt-fast-build
    

    授予当前用户管理权限:

    1
    
     sudo chown -R $USER:$USER /home/immortalwrt-fast-build
    
  2. src, dl, files (可选), bin 这些子目录。Docker Compose 会自动创建不存在的目录。

  3. 启动容器: 在 docker-compose.yml 文件所在目录下运行:

    1
    
    docker-compose up -d
    
  4. 进入容器并开始构建

    1
    
    docker-compose exec immortalwrt bash
    

    使用此命令会进入容器内部的 bash shell,工作目录为 /src

    或者使用--rm参数,退出后自动删除临时容器,保持干净

    1
    
    docker-compose run --rm immortalwrt bash
    
  5. 添加自定义文件(可选)

    ./files/ 目录(挂载到容器里的 /src/files/)在 OpenWrt/ImmortalWrt 的编译流程中叫做 “files 覆盖目录”。 它的作用是:把准备好的任何文件/目录,原封不动地打进最终固件的根文件系统(rootfs)里。

    典型用法:

    1. 预置网络配置 files/etc/config/network 让刷机后第一次启动就自带 IP、网关、VLAN。
    2. 默认密码或 ssh key files/etc/shadow files/etc/dropbear/authorized_keys
    3. 预装额外脚本/二进制 files/usr/bin/myscript.sh
    4. 默认时区、NTP、banner files/etc/config/system files/etc/banner
    5. 内核模块固件/校准数据 files/lib/firmware/...

    make 的最后阶段,脚本会执行cp -r files/* <rootfs>/,因此这里放什么,固件里就有什么,同名文件直接覆盖官方默认文件

    ⚠️注意:

    • 路径必须和运行时根目录完全一致(files/etc/... → 固件里的 /etc/...)。
    • 如果只想改默认配置,更推荐用 UCI defaults 脚本files/etc/uci-defaults/99-myconfig),这样可避免与官方配置冲突,升级时更安全。

1.2、开始编译

以下命令都要在容器内执行!!!

  1. 更新feeds

    1
    2
    
    ./scripts/feeds update -a
    ./scripts/feeds install -a
    
  2. 调整配置(可选):

    1
    2
    3
    
    make menuconfig            # 图形化界面增删包
    # 或
    make defconfig             # 如果已提供完整 .config
    
    • make menuconfig 调出 ncurses 图形菜单,用来: ‑ 选择/取消 Target(x86/legacy、x86/64、R2S…) ‑ 选 Subtarget & Profile(具体设备或通用固件) ‑ 勾选/取消 基础包(dnsmasq、firewall4、LuCI…) ‑ 勾选 额外软件(docker、passwall、homeproxy…) 保存后生成/更新 .config 文件。
    • make defconfig 读取 当前已存在的 .config,把其中缺失的 默认符号 自动补全,不做任何交互。 常用于: ‑ 已经从官方下载了完整 .config(例如 config.buildinfo),只需要把它变成「可直接编译」的状态;
  3. 预下载依赖

    1
    
    make -j$(nproc) download
    
    • 这一步只占用网络,CPU 压力极低;
    • 中途如果源站抽风,可以反复执行,不会破坏编译树;
    • 下载好的文件会写入 ./dl/(映射到宿主机的 ./dl/ 目录),下次复用。
  4. 正式编译

    1
    
    make -j$(nproc) world V=s
    
    • world 是 OpenWrt 的「全量编译」target;
    • V=s(可选)让编译日志更详细,便于排查错误;
    • 如果想在编译过程中再进入 menuconfig 调整包,可以先 make menuconfigmake world
  5. 获取构建好的固件: 构建成功后,固件会生成在容器的 /src/bin 目录下。由于你挂载了卷,在宿主机的 ./bin 目录下也能找到它们。

二、安装固件到设备

OpenWrt 安装教程 | এ默风 (dkyg666.github.io)

参考

updatedupdated2025-08-262025-08-26
加载评论