准备
环境配置
我使用的是WSL(Windows Subsystem for Linux 2),具体配置如下:
root@User: cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.4 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.4 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
配置依赖
方法1:
通过 APT 设置依赖项1,若依赖更新太慢,可换替换为阿里云的Ubuntu源2
sudo apt update -y
sudo apt full-upgrade -y
sudo apt install -y ack antlr3 asciidoc autoconf automake autopoint binutils bison build-essential \
bzip2 ccache clang cmake cpio curl device-tree-compiler ecj fastjar flex gawk gettext gcc-multilib \
g++-multilib git gnutls-dev gperf haveged help2man intltool lib32gcc-s1 libc6-dev-i386 libelf-dev \
libglib2.0-dev libgmp3-dev libltdl-dev libmpc-dev libmpfr-dev libncurses5-dev libncursesw5 \
libncursesw5-dev libpython3-dev libreadline-dev libssl-dev libtool lld llvm lrzsz mkisofs msmtp \
nano ninja-build p7zip p7zip-full patch pkgconf python2.7 python3 python3-pip python3-ply \
python3-docutils python3-pyelftools qemu-utils re2c rsync scons squashfs-tools subversion swig \
texinfo uglifyjs upx-ucl unzip vim wget xmlto xxd zlib1g-dev
#sudo apt install -y ack antlr3 asciidoc autoconf automake autopoint binutils bison build-essential \
#bzip2 ccache cmake cpio curl device-tree-compiler ecj fastjar flex gawk gettext gcc-multilib g++-multilib \
#git gperf haveged help2man intltool lib32gcc1 libc6-dev-i386 libelf-dev libglib2.0-dev libgmp3-dev libltdl-dev \
#libmpc-dev libmpfr-dev libncurses5-dev libncursesw5 libncursesw5-dev libreadline-dev libssl-dev libtool lrzsz \
#mkisofs msmtp nano ninja-build p7zip p7zip-full patch pkgconf python2.7 python3 python3-pip python3-ply \
#python-docutils python3-pyelftools qemu-utils re2c rsync scons squashfs-tools subversion swig texinfo uglifyjs upx-ucl unzip \
#libz-dev git-core upx vim wget xmlto xxd zlib1g-dev
方法2:
sudo bash -c 'bash <(curl -s https://build-scripts.immortalwrt.org/init_build_environment.sh)'
删除Windows文件夹
使用WSL编译OpenWrt时,驱动器上的 PATH 或工作文件夹中不得有空格3。但默认情况下,在 WSL 环境中也有 Windows 文件夹,下面的这些文件夹在路径中具有空格:
> echo ${PATH}
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/wsl/lib:/mnt/c/Windows/System32:/mnt/c/Windows:/mnt/c/Windows/System32/wbem:/mnt/c/Windows/System32/WindowsPowerShell/v1.0/:/mnt/c/Windows/System32/OpenSSH/:/mnt/c/Program Files/dotnet/:/mnt/c/Program Files (x86)/GnuPG/bin:/mnt/c/Program Files (x86)/dotnet/:/mnt/c/Program Files/WireGuard/:/mnt/c/Program Files/Git/cmd:/mnt/c/Program Files (x86)/AOMEI/AOMEI Backupper/6.5.1:/mnt/c/Program Files (x86)/Bitvise SSH Client:/mnt/c/WINDOWS/system32:/mnt/c/WINDOWS:/mnt/c/WINDOWS/System32/Wbem:/mnt/c/WINDOWS/System32/WindowsPowerShell/v1.0/:/mnt/c/WINDOWS/System32/OpenSSH/:/mnt/c/Users/Bas Mevissen/AppData/Local/Microsoft/WindowsApps:/mnt/c/Users/Bas Mevissen/.dotnet/tools
在WSL的/etc/wsl.conf
中加入以下内容,以便 Linux 发行版的 PATH 环境变量中没有 Windows 路径元素
sudo tee -a /etc/wsl.conf << EOF > /dev/null
[interop]
appendWindowsPath = false
EOF
exit
重启以应用更改
wsl --shutdown
在 Linux 环境中,通过以下命令验证 PATH 环境变量中是否未显示任何 Windows 路径元素。
echo ${PATH}
建立非root用户
为了能够成功编译,需要使用非root用户进行编译。因此,需要建立非root用户,比如:openwrt。
adduser openwrt
usermod -a -G sudo openwrt
su openwrt
编译OpenWrt
获取源码
使用openwrt用户,在/home/openwrt
执行以下命令获取ImmortalWrt的源码
openwrt@User:~$ #git clone https://github.com/padavanonly/immortalwrt
上方的版本为旧版
openwrt@User:~$ git clone https://github.com/immortalwrt/immortalwrt.git immortalwrt
Cloning into 'immortalwrt'...
remote: Enumerating objects: 17533, done.
remote: Counting objects: 100% (1151/1151), done.
remote: Compressing objects: 100% (784/784), done.
remote: Total 17533 (delta 320), reused 997 (delta 239), pack-reused 16382
Receiving objects: 100% (17533/17533), 43.47 MiB | 1.21 MiB/s, done.
Resolving deltas: 100% (4188/4188), done.
Updating files: 100% (13346/13346), done.
进入源码目录
cd immortalwrt
添加第三方feeds源
进入 feeds.conf.default
文件
vi feeds.conf.default
按i进行编辑,插入下列内容
src-git kenzok https://github.com/kenzok8/openwrt-packages
src-git small https://github.com/kenzok8/small
编辑完成后按Esc退出编辑模式,输入 :wq
,保存并退出编辑界面。
执行下列代码来获取在 feeds.conf
/ feeds.conf.default
中罗列的所有最新版软件包定义:
./scripts/feeds update -a
运行下列代码,将获取的所有软件包安装到 package/feeds/ 中:
./scripts/feeds install -a
添加自定义软件包(不建议)
执行下列代码,新增自定义脚本4:
vi diy-script.sh
按i进行编辑,加入diy-script.sh中的内容:
#!/bin/bash
# 修改默认IP
#sed -i 's/192.168.1.1/10.0.0.1/g' package/base-files/files/bin/config_generate
#sed -i 's/192.168/10.0/g' package/base-files/files/bin/config_generate
# 修改默认SSID
sed -i 's/ImmortalWrt/OpenWrt/g' package/network/config/wifi-scripts/files/lib/wifi/mac80211.sh
###Start 这一条适用于 https://github.com/coolsnowwolf 发布的源码(只是sh文件的路径不同)
#sed -i 's/OpenWrt/PandoraBox/g' package/kernel/mac80211/files/lib/wifi/mac80211.sh
###End
# 增设WiFi密码
sed -i 's/encryption=none/encryption=psk-mixed\n set wireless.default_radio${devidx}.key=openwrt\n set wireless.default_radio${devidx}.ieee80211r=1\n set wireless.default_radio${devidx}.ft_over_ds=0\n set wireless.default_radio${devidx}.ft_psk_generate_local=1\n/g' package/kernel/mac80211/files/lib/wifi/mac80211.sh
#上面的“mac80211.sh”路径替换为其实际所在的路径
# 更改默认 Shell 为 zsh
# sed -i 's/\/bin\/ash/\/usr\/bin\/zsh/g' package/base-files/files/etc/passwd
# TTYD 免登录
# sed -i 's|/bin/login|/bin/login -f root|g' feeds/packages/utils/ttyd/files/ttyd.config
# Git稀疏克隆,只克隆指定目录到本地
function git_sparse_clone() {
branch="$1" repourl="$2" && shift 2
git clone --depth=1 -b $branch --single-branch --filter=blob:none --sparse $repourl
repodir=$(echo $repourl | awk -F '/' '{print $(NF)}')
cd $repodir && git sparse-checkout set $@
mv -f $@ ../package
cd .. && rm -rf $repodir
}
# 添加额外插件
git clone --depth=1 https://github.com/kongfl888/luci-app-adguardhome package/luci-app-adguardhome
git clone --depth=1 https://github.com/ilxp/luci-app-ikoolproxy package/luci-app-ikoolproxy
git clone --depth=1 https://github.com/esirplayground/luci-app-poweroff package/luci-app-poweroff
git clone --depth=1 https://github.com/destan19/OpenAppFilter package/OpenAppFilter
git_sparse_clone main https://github.com/Lienol/openwrt-package luci-app-filebrowser luci-app-ssr-mudb-server
# 科学上网插件
git clone --depth=1 -b main https://github.com/fw876/helloworld package/luci-app-ssr-plus
git clone --depth=1 https://github.com/xiaorouji/openwrt-passwall-packages package/openwrt-passwall
git clone --depth=1 https://github.com/xiaorouji/openwrt-passwall2 package/luci-app-passwall2
# Themes
git clone --depth=1 https://github.com/kiddin9/luci-theme-edge package/luci-theme-edge
git clone --depth=1 https://github.com/xiaoqingfengATGH/luci-theme-infinityfreedom package/luci-theme-infinityfreedom
git_sparse_clone main https://github.com/haiibo/packages luci-theme-atmaterial_new luci-theme-opentomato luci-theme-netgear
# 更改 Argon 主题背景
#cp -f $GITHUB_WORKSPACE/images/bg1.jpg package/luci-theme-argon/htdocs/luci-static/argon/img/bg1.jpg
# 晶晨宝盒
git_sparse_clone main https://github.com/ophub/luci-app-amlogic luci-app-amlogic
sed -i "s|firmware_repo.*|firmware_repo 'https://github.com/haiibo/OpenWrt'|g" package/luci-app-amlogic/root/etc/config/amlogic
# sed -i "s|kernel_path.*|kernel_path 'https://github.com/ophub/kernel'|g" package/luci-app-amlogic/root/etc/config/amlogic
sed -i "s|ARMv8|ARMv8_PLUS|g" package/luci-app-amlogic/root/etc/config/amlogic
# MosDNS
git clone --depth=1 https://github.com/sbwml/luci-app-mosdns package/luci-app-mosdns
# DDNS.to
git_sparse_clone main https://github.com/linkease/nas-packages-luci luci/luci-app-ddnsto
git_sparse_clone master https://github.com/linkease/nas-packages network/services/ddnsto
# iStore
git_sparse_clone main https://github.com/linkease/istore-ui app-store-ui
git_sparse_clone main https://github.com/linkease/istore luci
# 在线用户
#git_sparse_clone main https://github.com/haiibo/packages luci-app-onliner
#sed -i '$i uci set nlbwmon.@nlbwmon[0].refresh_interval=2s' package/lean/default-settings/files/zzz-default-settings
#sed -i '$i uci commit nlbwmon' package/lean/default-settings/files/zzz-default-settings
#chmod 755 package/luci-app-onliner/root/usr/share/onliner/setnlbw.sh
# 修改 Makefile
find package/*/ -maxdepth 2 -path "*/Makefile" | xargs -i sed -i 's/..\/..\/luci.mk/$(TOPDIR)\/feeds\/luci\/luci.mk/g' {}
find package/*/ -maxdepth 2 -path "*/Makefile" | xargs -i sed -i 's/..\/..\/lang\/golang\/golang-package.mk/$(TOPDIR)\/feeds\/packages\/lang\/golang\/golang-package.mk/g' {}
find package/*/ -maxdepth 2 -path "*/Makefile" | xargs -i sed -i 's/PKG_SOURCE_URL:=@GHREPO/PKG_SOURCE_URL:=https:\/\/github.com/g' {}
find package/*/ -maxdepth 2 -path "*/Makefile" | xargs -i sed -i 's/PKG_SOURCE_URL:=@GHCODELOAD/PKG_SOURCE_URL:=https:\/\/codeload.github.com/g' {}
# 取消主题默认设置
#find package/luci-theme-*/* -type f -name '*luci-theme-*' -print -exec sed -i '/set luci.main.mediaurlbase/d' {} \;
# 调整 V2ray服务器 到 VPN 菜单
sed -i 's/services/vpn/g' feeds/luci/applications/luci-app-v2ray-server/luasrc/controller/*.lua
sed -i 's/services/vpn/g' feeds/luci/applications/luci-app-v2ray-server/luasrc/model/cbi/v2ray_server/*.lua
sed -i 's/services/vpn/g' feeds/luci/applications/luci-app-v2ray-server/luasrc/view/v2ray_server/*.htm
./scripts/feeds update -a
./scripts/feeds install -a
保存并退出编辑界面,运行下列命令来执行上述的脚本:
sh diy-script.sh
设置编译配置文件
运行下列代码,进入工具软件、目标系统和固件包的首选配置页面。
make menuconfig
图形配置界面介绍5
OpenWrt Configuration【OpenWrt配置】
Target System (x86) —> 目标系统(x86)
Subtarget (x86_64) —> 子目标(x86_64)
Target Profile (Generic) —>目标配置文件(通用)
Target Images —> 保存目标镜像的格式
Enable experimental features by default —> 默认情况下启用实验功能
Global build settings —> 全局构建设置
Advanced configuration options (for developers) ---- 高级配置选项(适用于开发人员)
Build the OpenWrt Image Builder 构建OpenWrt图像生成器
Build the OpenWrt SDK构建OpenWrt SDK
Package the OpenWrt-based Toolchain打包基于OpenWrt的工具链
Image configuration —>图像配置
Base system —> 基本系统
Administration —> 管理
Boot Loaders —>引导加载程序
Development —> 开发
Extra packages —> 额外包
Firmware —>固件
Fonts —>字体
Kernel modules —> 内核模块
Languages —>语言
Libraries —> 图书馆
LuCI —> LuCI 软件包(在这里面设置软件、主题、翻译)
Mail —>邮件
Multimedia —>多媒体
Network —>网络(设置SFTP)
Sound —> 声音
Utilities —>实用程序
Xorg —>Xorg
下载dl(依赖)库
#下载dl库(国内请尽量全局科学上网)
make -j6 download V=s
# j6 代表CPU线程数 6=6线程
运行下列命令检查下载不完整的文件(<1k的文件属于下载不完整)
find dl -size -1024c -exec ls -l {} ;
如果存在可使用find dl -size -1024c -exec rm -f {} ;
命令将它们删除,然后重新执行make download
下载并反复检查,确认所有文件完整可大大提高编译成功率。
运行 make 编译固件
make -j6 V=s
# -j1:单线程编译。首次建议单线程编译,方便查看错误日志。
# V=s:输出详细日志,编译失败时用于找错。
编译完成后输出路径:bin/targets
在uboot下刷factory文件,在固件升级页面刷sysupgrade文件
编译注意事项
如果需要重新配置
rm -rf ./tmp && rm -rf .config
make menuconfig
make -j(((((nproc) + 1)) V=s) #(多线程编译失败后自动进入单线程编译,失败则输出详细日志)
编译更换其它CPU架构的固件(建议操作)
# 清除旧的编译产物
make clean
在源码有大规模更新或者内核更新后执行上述命令,以保证编译质量。此操作会删除/bin和/build_dir目录中的文件。
#清除旧的编译产物、交叉编译工具及工具链等目录
make dirclean
更换架构编译前必须执行上述命令。此操作会删除/bin
和/build_dir
目录的中的文件(make clean)以及/staging_dir
、/toolchain
、/tmp
和/logs
中的文件
#清除 OpenWrt 源码以外的文件(可选)
make distclean
除非是做开发,并打算 push 到 GitHub 这样的远程仓库,否则几乎用不到上述命令。此操作相当于make dirclean外加删除/dl、/feeds目录和.config文件。
#还原 OpenWrt 源码到初始状态(可选)
git clean -xdf
如果把源码改坏了,或者长时间没有进行编译时使用上述命令。
#清除临时文件
rm -rf tmp
删除执行make menuconfig后产生的一些临时文件,包括一些软件包的检索信息,删除后会重新加载package目录下的软件包。若不删除会导致一些新加入的软件包不显示。
#删除编译配置文件
rm -f .config
在不删除的情况下,如果取消选择某些组件它的依赖组件不会自动取消,所以在需要调整组件时执行上述命令。
固件使用问题
更换软件源
在国内可能会无法正常使用原始的软件源,因此我这边更换为上海交大的镜像:
将 /etc/opkg/distfeeds.conf
中的原始路径(https://downloads.immortalwrt.org/snapshots)更换为:https://mirrors.sjtug.sjtu.edu.cn/immortalwrt/releases/23.05.2
并且注释掉 /etc/opkg.conf
中的 option check_signature
,如下:
dest root /
dest ram /tmp
lists_dir ext /var/opkg-lists
option overlay_root /overlay
#option check_signature
# 不注释掉会导致无法更新软件源:opkg update更新时会提示 Signature check failed
更新软件列表报错
执行 opkg update
命令失败,提示代码 6
在编译时,勿选Network—File-Transfer下的“wget-nossl”,否则更新软件源时会报错:代码6。
简单的解决办法是先卸载“wget-nossl”,之后方可使用opkg update更新软件列表。
软件安装提示错误
opkg install安装插件时,出现类似错误:
* pkg_hash_check_unresolved: cannot find dependency kernel (= 6.1.82~26969dda3c21194ea658cd7cbb8399e9-r1) for kmod-cryptodev
内核包用snapshot源码编译的固件,会因为个人编译后的指纹与官方不符而无法安装,需要替换为官方指纹。强制安装就算装上了也容易出稀奇古怪的问题,最好自己编译时加进去6。
修改方法如下
vi /usr/lib/opkg/status
在 vi 的 normal 模式下替换a60e1decc7262b7aff1e5f054fe9598f 为官方指纹e1dd7676581672f6f0bdb1363506dee1
先输入英文小写冒号:
%s/a60e1decc7262b7aff1e5f054fe9598f/e1dd7676581672f6f0bdb1363506dee1/g
按回车,完成替换操作。
新增的管理包不显示在服务里
登录 SSH,输入以下命令:
rm /tmp/luci-indexcache
输入重启命令即可:
reboot
开启IPv6中继
如果wan口(wan6口)能够直接获取到公网号段的IPv6,电脑直连上级路由设备,看看能否获取到IPv6地址,并且能够访问纯IPv6网站(访问6.ipw.cn,得到的IPv6地址和理论本机IPv6地址一致)则可以通过以下设置,来实现路由器下的设备均能够分配到IPv6地址。
配置WAN6
在“网络-接口-WAN6(如果没有的话手动添加一个)“中编辑:
常规设置:
- 协议:DHCPv6 客户端
- 设备:wan
防火墙设置:
- 加入“wan”防火墙
DHCP 服务器:
常规设置:
- 勾选“忽略此接口”
IPv6设置:
- 勾选“指定的主接口”(将此接口设为 RA 和 DHCPv6 中继及 NDP 代理的主接口)
- RA 服务:中继模式
- DHCPv6 服务:已禁用(也行)
- NDP 代理:中继模式
- 勾选“学习路由”
- 其他的保持默认
- 保存
配置LAN
在“网络-接口-LAN“中编辑:
常规设置:
- 协议:静态地址
- 设备:br-lan
DHCP 服务器:
IPv6设置:
- RA 服务:中继模式
- DHCPv6 服务:已禁用(也行)
- NDP 代理:中继模式
- 勾选“学习路由”
- 其他的保持默认
- 保存
重启测试
“保存并应用”,等待路由器更新后,重启OpenWrt或将接入路由器的设备断开网络连接再重连,即可获得公网IPv6地址。
在IPv6地址查询 | IP查询(ipw.cn)中测试是否支持IPv6。
注意
如果在使用OpenClash等代理插件时,需要在插件中一同配置DHCPv6和DNS,一般设置为“解析DHCPv6”但“不代理”。不设置的话可能无法正常访问IPv6网站。
- padavanonly/immortalwrt (github.com) ↩︎
- ubuntu镜像_ubuntu下载地址_ubuntu安装教程-阿里巴巴开源镜像站 (aliyun.com) ↩︎
- [OpenWrt Wiki] Build system setup WSL ↩︎
- haiibo/OpenWrt: 基于 Lean 源码编译的 OpenWrt 固件——适配X86、R2C、R2S、R4S、R4SE、R5C、R5S、香橙派 R1 Plus、树莓派3B、树莓派4B、R66S、R68S、M68S、H28K、H66K、H68K、H88K、H69K、E25、N1、S905x3、S922x、HK1、X96max、微加云、贝壳云、我家云、章鱼星球等 (github.com) ↩︎
- OpenWrt介绍及编译基础教程_openwrt编译-CSDN博客 ↩︎
- opkg install错误解决寻解-OPENWRT专版-恩山无线论坛 (right.com.cn) ↩︎
DHCPv6 服务选择“已禁用”可能会导致无法正常访问GitHub,建议按照图中参数设置