OpenWrt官方开发工具的使用

 

编译环境配置及其他参考相关说明

  • 参考借鉴:使用ImageBuilder | 使用​SDK开发工具包 | 系统构建的软件依赖

  • SDK与Buildroot系统具有相同的软件依赖:sudo apt update && sudo apt install build-essential clang flex bison g++ gawk gcc-multilib g++-multilib gettext git libncurses5-dev libssl-dev python3-setuptools rsync swig unzip zlib1g-dev file wget zstd

  • 在SDK中默认包含所有,需从 menuconfig 中进入 Global Build Settings 中取消选择以下选项:

    Select all target specific packages by default
    Select all kernel module packages by default
    Select all userspace packages by default

使用Image Builder构建系统镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# 优缺点:可以安装 repositories.conf 源中有的官方及非官方软件包,但无法编译只有源码的包

# 下载解压Image Builder工具包后进入目录
wget https://downloads.openwrt.org/releases/24.10.2/targets/x86/64/openwrt-imagebuilder-24.10.2-x86-64.Linux-x86_64.tar.zst
tar -I zstd -xvf openwrt-imagebuilder-24.10.2-x86-64.Linux-x86_64.tar.zst
mv openwrt-imagebuilder-24.10.2-x86-64.Linux-x86_64 imagebuilder
cd imagebuilder

# 查看当前硬件支持列表和默认包含的软件包
leux@Debian:~/imagebuilder$ make info
Current Target: "x86/64"
Current Architecture: "x86_64"
Current Revision: "r28739-d9340319c6"
Default Packages: base-files ca-bundle dropbear fstools libc libgcc libustream-mbedtls logd mtd netifd uci uclient-fetch urandom-seed urngd partx-utils mkf2fs e2fsprogs kmod-button-hotplug grub2-bios-setup procd-ujail dnsmasq firewall4 nftables kmod-nft-offload odhcp6c odhcpd-ipv6only ppp ppp-mod-pppoe opkg
Available Profiles:

generic:
Generic x86/64
Packages: kmod-amazon-ena kmod-amd-xgbe kmod-bnx2 kmod-dwmac-intel kmod-e1000e kmod-e1000 kmod-forcedeth kmod-fs-vfat kmod-igb kmod-igc kmod-ixgbe kmod-r8169 kmod-tg3 kmod-drm-i915
hasImageMetadata: 0
leux@Debian:~/imagebuilder$

# make image 命令会创建一个只包含基本依赖软件包的最小化镜像,这个命令可以通过下面几个传递过去的变量控制生成镜像
# PROFILE:指定要编译的目标镜像的配置,FILES:要包含进去的自定义文件的目录,PACKAGES:要嵌入镜像的包文件的列表
make image PROFILE=generic FILES=files/ PACKAGES=" \
kmod-usb2 kmod-usb3 kmod-usb-ohci kmod-usb-uhci \
kmod-usb-storage-extras kmod-fs-ext4 kmod-fs-vfat \
kmod-iwlwifi iwlwifi-firmware-ax101 kmod-mt7916-firmware \
wpad-openssl usbutils pciutils curl wget htop \
luci luci-ssl luci-proto-ncm luci-proto-mbim luci-proto-qmi \
luci-i18n-base-zh-cn luci-app-firewall luci-i18n-firewall-zh-cn \
luci-app-package-manager luci-i18n-package-manager-zh-cn"

# 固件构建完成后把 bin/targets/x86/64/openwrt-24.10.2-x86-64-generic-ext4-combined-efi.img.gz 解压后的img文件刷入即可


# 可用选择更换软件源为国内源
sed -i 's/downloads.openwrt.org/mirrors.ustc.edu.cn\/openwrt/g' repositories.conf

# 当前对于AX201的支持安装 iwlwifi-firmware-ax201 不起作用,得安装 iwlwifi-firmware-ax101 才行,解包可知它们两个的内容
iwlwifi-firmware-ax101_20241110-r2_x86_64.ipk\data.tar.gz\data.tar\lib\firmware\iwlwifi-so-a0-hr-b0-89.ucode
iwlwifi-firmware-ax201_20241110-r2_x86_64.ipk\data.tar.gz\data.tar\lib\firmware\iwlwifi-QuZ-a0-hr-b0-77.ucode

# 增加引导分区大小可以消除如下警告,但也可能会导致VMware esxi虚拟化用户在升级系统后遇到虚拟磁盘分区损坏问题。仅为了消除警告而破坏向后兼容性并不可取
# /home/leux/imagebuilder/staging_dir/host/bin/grub-bios-setup: warning: Your BIOS Boot Partition is under 1 MiB, please increase its size..
# 既可使用命令 sed -i 's/256/1024/g' target/linux/x86/image/Makefile 修改,也可手动修改如下 256 数值大小
47 PADDING="1" SIGNATURE="$(IMG_PART_SIGNATURE)" \
48 $(if $(filter $(1),efi),GUID="$(IMG_PART_DISKGUID)") $(SCRIPT_DIR)/gen_image_generic.sh \
49 $@ \
50 $(CONFIG_TARGET_KERNEL_PARTSIZE) $@.boot \
51 $(CONFIG_TARGET_ROOTFS_PARTSIZE) $(IMAGE_ROOTFS) \
52 256
53 endef

用OpenWrt SDK构建外部软件包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 优缺点:可以编译只有源码的包,但无法构建出系统镜像

# 下载解压OpenWrt SDK工具包后进入目录
wget https://mirrors.ustc.edu.cn/openwrt/releases/24.10.2/targets/x86/64/openwrt-sdk-24.10.2-x86-64_gcc-13.3.0_musl.Linux-x86_64.tar.zst
tar -I zstd -xvf openwrt-sdk-24.10.2-x86-64_gcc-13.3.0_musl.Linux-x86_64.tar.zst
mv openwrt-sdk-24.10.2-x86-64_gcc-13.3.0_musl.Linux-x86_64 openwrt-sdk
cd openwrt-sdk

# 以编译软件包Qmodem为例,先添加及更新源
echo 'src-git qmodem https://github.com/FUjr/QModem.git;main' >> feeds.conf.default
./scripts/feeds update -a
./scripts/feeds install -a

# 在菜单中选中要编译的包后再通过命令编译构建,完成后生成的在 bin/ 目录下
make menuconfig
make package/feeds/qmodem/luci-app-qmodem/compile V=s
make package/feeds/qmodem/quectel_MHI/compile V=s

# 相关命令介绍
make package/example/download # 下载源码
make package/example/prepare # 解压源码和应用补丁(含上面下载命令)
make package/example/compile # 编译源码(含上面两个命令)
make package/example/clean # 清理源码
make package/index # 构建存储库索引来使输出目录可用作本地的opkg源

用OpenWrt Toolchain 编译源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 优缺点:仅可交叉编译出C源码的库或二进制可执行文件

# 下载解压OpenWrt Toolchain工具链后进入目录
wget https://mirrors.ustc.edu.cn/openwrt/releases/24.10.2/targets/x86/64/openwrt-toolchain-24.10.2-x86-64_gcc-13.3.0_musl.Linux-x86_64.tar.zst
tar -I zstd -xvf openwrt-toolchain-24.10.2-x86-64_gcc-13.3.0_musl.Linux-x86_64.tar.zst
mv openwrt-toolchain-24.10.2-x86-64_gcc-13.3.0_musl.Linux-x86_64 openwrt-toolchain
cd openwrt-toolchain

# 设置环境变量,STAGING_DIR变量不设置老是显示警告很烦
export STAGING_DIR=/home/leux/openwrt-toolchain
export PATH=$PATH:/home/leux/openwrt-toolchain/toolchain-x86_64_gcc-13.3.0_musl/bin

# 以编译某个lvgl程序为例
git clone https://github.com/zzzz0317/xgp-v3-screen/
cd xgp-v3-screen/src/
git clone --depth 1 -b release/v9.3 https://github.com/lvgl/lvgl.git lvgl
cmake -DCMAKE_C_COMPILER=x86_64-openwrt-linux-musl-gcc -DCMAKE_CXX_COMPILER=x86_64-openwrt-linux-musl-g++
make -j$(nproc)

# 查看最后生成的可执行文件相关信息
leux@Debian:~/xgp-v3-screen/src/bin$ file zz_xgp_screen
zz_xgp_screen: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86_64.so.1, with debug_info, not stripped

OpenWrt系统编译中的目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
bin/				# 编译完成后ipk和image文件存放在此
dl/ # 下载的软件包存放在此目录
feeds/ # 根据 feeds.conf.default 获取的扩展包源码
package/ # OpenWrt系统中自带的最基础的包源码
package/feeds/ # 软连接指向 feeds/ 中对应位置

# build_dir/ 中存放解包后的源代码和编译它们的位置
build_dir/host/ # 存放host中会用到工具解包后的源代码
build_dir/hostpkg/ # 存放一些解包的源码和编译完成的软件
build_dir/target-*/ # 存放编译OpenWrt系统实际的包和内核
build_dir/toolchain-*/ # 存放交叉编译器和相关库解包后的源码

# staging_dir/ 中是存放编译后用来打包、组装固件的文件
staging_dir/host/ # 上面 build_dir/host/ 中编译后会安装到此
staging_dir/target-*/ # 包含编译后OpenWrt的相关包和内核及安装信息
staging_dir/toolchain-*/ # 上面构建完成后的C交叉编译器和相关C库

通过OpenWrt SDK编译内核为例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# 本例目的为【康耐信N100/N150四网卡i226版本】驱动ITE IT8613E芯片和可看风扇转速,编译安装后还需安装 lm-sensors 通过命令 sensors 查看

# 该内核源码包的目录结构如下:
openwrt-sdk/package/it87/
├── Makefile
└── src
├── compat.h
├── it87.c
└── Makefile

# 最终编译后的包位于:openwrt-sdk/bin/targets/x86/64/packages/kmod-it87_6.6.93.2025.09.08-r2_x86_64.ipk
make package/it87/compile V=s

# 下载支持ITE IT8613E芯片的内核源码
cd openwrt-sdk/package/it87/src/
wget https://github.com/a1wong/it87/raw/master/it87.c
wget https://github.com/a1wong/it87/raw/master/compat.h

# 如下为 openwrt-sdk/package/it87/src/Makefile 中的内容
ccflags-y += -Wno-error=implicit-fallthrough
obj-m += it87.o


# 如下为 openwrt-sdk/package/it87/Makefile 中的内容
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
include $(INCLUDE_DIR)/package.mk

PKG_NAME:=it87
PKG_VERSION:=2025.09.08
PKG_RELEASE:=2

# CATEGORY 在顶级菜单中的【My Apps】栏中显示。SUBMENU 在【Kernel modules】栏中的【Other modules】栏中显示
define KernelPackage/it87
# CATEGORY:=My Apps
SUBMENU:=Other modules
TITLE:=IT8613E monitoring support
FILES:=$(PKG_BUILD_DIR)/it87.ko
AUTOLOAD:=$(call AutoLoad,90,it87)
endef

define KernelPackage/it87/description
Kernel module for it87 thermal and voltage monitor chip
endef

# Makefile中命令行开头必须用Tab键,否则报:Makefile:40: *** missing separator. Stop.
MAKE_OPTS:= \
ARCH="$(LINUX_KARCH)" \
CROSS_COMPILE="$(TARGET_CROSS)" \
CXXFLAGS="$(TARGET_CXXFLAGS)" \
M="$(PKG_BUILD_DIR)" \
$(EXTRA_KCONFIG)

define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef

define Build/Compile
$(MAKE) -C "$(LINUX_DIR)" \
$(MAKE_OPTS) \
modules
endef

$(eval $(call KernelPackage,it87))

为已有的OpenWrt包搭建软件源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 搭建OpenWrt软件源过程中定会遇到如下几个文件,这里解释下它们的作用:
Packages # 搭建 OpenWrt 系统软件源过程中必须的包索引文件,内含软件包相关信息
Packages.gz # 源中可只需要 Packages.gz 即可,文件 Packages 生成 gz 后也可删除
Packages.sig # 在 /etc/opkg.conf 中注释 option check_signature 便可不用 Packages.sig

# 后面的 Packages 生成方法来自脚本:/home/leux/openwrt-sdk/scripts/ipkg-make-index.sh
# 以为本目录下的某个IPK包创建软件源所需的文件为例,如下几行为获取包的文件名,大小,哈希值
pkg=`find ./ -name '*.ipk' | sort`
FILE_NAME=`echo $pkg | sed -e 's/^\.\///g'`
FILE_SIZE=$(stat -L -c%s $pkg)
SHA256SUM=`sha256sum $pkg | awk '{ print $1 }'`

# 读取IPK包中control文件的内容并组合上面获取到的信息生成 Packages 文件
tar -xzOf $pkg ./control.tar.gz | tar xzOf - ./control | sed -e "s/^Description:/Filename: $FILE_NAME\\
Size: $FILE_SIZE\\
SHA256sum: $SHA256SUM\\
Description:/" | sed '/Source:/d;/SourceName:/d;/SourceDateEpoch:/d' >> Packages

# 在 Packages 文件末尾添加空行来分割多个包之间的信息
echo "" >> Packages

# 压缩生成 Packages.gz 文件
gzip -9c Packages > Packages.gz


# 关于 Packages.sig 的生成,复制一份私钥命名为 key-build 并放到SDK的根目录下,在编译完成后执行 make package/index 命令的时候,签名会自动生成
# 下面的 usign 工具既可使用SDK中提供的,也可手动编译来获取:git clone https://github.com/openwrt/usign && cd usign/ && cmake . && make

# 第一步:生成一对公钥和私钥,公钥用于路由对签名文件进行校验,私钥用于我们生成签名文件
/home/leux/openwrt-sdk/staging_dir/host/bin/usign -G -s secret.key -p public.key

# 第二步:利用生成的私钥和 Packages 文件生成 Packages.sig
/home/leux/openwrt-sdk/staging_dir/host/bin/usign -S -m Packages -s secret.key -x Packages.sig

# 第三步:把上面生成的公钥上传到路由器上并执行如下命令新增我们生成的公钥
opkg-key add public.key


# 最后将自己搭建的源添加到路由器的opkg中即可使用,文件 Packages.* 和相关包都在网站源的根路径下
# 因为 https://github.com/simonsmh/openwrt-dist/raw/packages/x86/64/Packages.gz 是可以访问到的,所以Github也是能作为软件源的,可通过分支名来指定架构路径
echo "src/gz example_test https://github.com/simonsmh/openwrt-dist/raw/packages/x86/64/" >> /etc/opkg/customfeeds.conf