上一次似乎说想用 MT7620A 的路由器来演示更进一步的 ImageBuilder 用法。不过呢,我改主意了。虽然我现在手里有三个 MT7620A 的路由器吧。
至于为什么改主意……OpenWrt 官方的 Designated Driver(16.x)版仍然没有正式发布,然而只有这个版本才添加了对极 1s 等国产智能路由器的官方支持。
所以嘛,我们跳过这一步,直接来搞 BuildRoot。
lean 称他的固件为【4MB 的奇迹】,我们就来重演一次他的奇迹好了。
TL-WR703N Original version
前两天翻数码之家,发现有人卖路由器,极 1s 只要 50 块钱。卖家还有一个不太正常的 WR703N,据说搜不到无线而且有线插上不是 192.168.1.0/24,20 块钱出。因为早就想要一个 WR703N,于是就果断打包入手了。
到手之后极 1s 没怎么折腾就拿去用了(话说居然还有 900 多天才过保,不亏)。既然没过保就不瞎折腾了,插到网内让它安静的提供一下 OpenVPN 服务就行。
这台 WR703N 真的好小,比银行卡的一半稍大一点。直接挂在钥匙上都不是很违和。
稍微玩了一小会儿。跟卖家说的一样棘手,插上电源之后,看指示灯闪烁的状态,似乎正常启动到了 OpenWrt。然而捅了半天菊花试图恢复出厂设置,无效。这就很尴尬了。进 U-Boot 也分配不到 IP。
上网查过,发现 TP 原装的 U-Boot 并没有自动设置 IP 之类。意思是说,固件挂了,如果没有办法接 TTL 的话,这东西就是一板砖。尼玛。
拆壳,焊 TTL。(从网上借的图,自己的焊盘狗带了一个来不及重拍了。侵删)
焊点是真 TM 小,倒是难不倒我。有一个迷的问题是 GND 并没有跟各个接口的外壳相连,所以不得不去板子上找一个。
用控制台看了半天固件的默认设置,发现 WIFI 默认被禁用,以太网端口搞了一个特别诡异的配置:固定 IP 192.168.0.100 网关 192.168.0.1……于是把自己电脑 IP 改成 192.168.0.1,顺利访问到路由器的 LuCI 界面。
然后就是刷掉固件解锁 U-Boot,刷 Breed,备份 ART,为后面作死做好准备。
- 解锁了 U-Boot 分区的固件可以在【这里】下载。
- Breed 可以在【这里】下载。如何刷入请见贴内教程,其实也就是一个
mtd -r write /tmp/breed-ar9331.bin u-boot
而已。
- 我的 ART 可以在【这里】下载。
Breed 界面是这个样子的,可以看到这台设备并没有进行硬件改动,仍然是出厂时的 32MB RAM + 4MB Flash 搭配。
拆 TTL 线的时候就比较悲剧……焊点小也就算了,还特么特别容易掉。虽然我小心小心再小心不过还是手抖毁掉了一个焊盘。不过无所谓了。
搞定之后,我刷的是 lean 定制的自带 ShadowSocksR 和 AdBlock Plus 并优化了 Dnsmasq 的固件,可以在【这里】下载。
Challenge
lean 的固件用起来还不错,可以十分愉悦的完成透明代理任务,不过 AdBlock 我反正是没看见……
路由器上有一个 USB 接口,lean 的固件并没有集成任何 USB 相关支持,却加入了一些我觉得并没有什么用的中文翻译、UPNP、动态 DNS 之类的功能。
由于这个路由器非常非常小,小到挂在钥匙上都不太违和,我计划中的使用方式大概是这样:用移动电源给树莓派供电,树莓派某一个 USB 口连接路由器供电口,路由器的 USB 口连接手机,手机打开 USB 网络共享。这样其他设备连接到路由器提供的网络就可以通过手机上网了。
通过搜索得知:
- WR703N 的 USB 控制器为 EHCI 类型,需要安装模块 kmod-usb2 打开支持。
- 手机通过 USB 共享网络使用了 RNDIS。OpenWrt 官方通过模块 kmod-usb-net-rndis 提供了全面支持。
看似并不难的样子。本来计划使用 ImageBuilder 完成映像定制,不过……
- Flash 空间只有 4MB,裁剪的粒度可能比软件包还要小,甚至可能细化到内核的某一个功能特性(事实上也确实如此)
- ShadowSocksR 没有提供上一次搞透明代理那样的第三方软件源(虽然可以配置本地源,所以这其实不算是个什么靠谱的理由)
- 既然有这么个作死的机会,不如……
我们来试试 BuildRoot 吧。
BuildRoot - Preparation
首先,根据官方的 BuildRoot 教程,我们需要准备以下环境。
- 靠谱的网络。最好挂好了 VPN 或者配置好了 ShadowSocks 透明代理,或者使用前面提到过的 ProxyChains。
- Linux 或者 Mac OS X。重点是 Case-Sensetive Filesystem……所以 Cygwin 不行。
- ToolChains。第一次执行 make 时会检查工具链,如下。
全都准备好之后,我们就可以开始了。
首先,从 OpenWrt 官方获取源代码。我们这次的定制使用 2016/05/27 的 Trunk 版本。
如果需要稳定版,可以加上对应的版本号:
需要注意的是目前 Chaos Calmer 分支下的稳定版是 15.05.1。
等待一会儿 git clone 完成,cd 进入 trunk 目录。
输入命令
之后,我们就看到了配置菜单。
我们发现,这个菜单中包含的项目并不全,甚至连最重要的 LuCI 都没有。在开始前,我们还需要更新 Feeds。
更新 Feeds 之后再查看菜单,LuCI 等项目就出现了。
我们此时可以测试一下工具链是否正常,方法当然是 Fire。
目前 Target System 已经是我们要的 Atheros AR7xxx/AR9xxx。修改下面的 Target Profile 为 WR703N:
返回,保存。
退出,开始编译:
其中 V=99 代表显示所有信息。-j 代表允许并行任务(后面可以加一个数字代表线程数,不加代表不限制)
一次完整的编译,从整个 gcc g++ 到内核再到各种软件包都会从源代码编译出来……简直可怕……
根据网络状况、电脑配置、之前编译结果不同,整个编译过程,短的大概几分钟,长的可能会有几个小时,我们可以开始等了。这个过程中需要保持网络畅通,同时 CPU 也会狂烧……
一觉醒来,发现编译失败了 :) 各种重试中。
如果总是失败,可以试着改用参数
禁用并行操作,这样可能可以避免由于依赖关系(后面编译的代码依赖前面编译出来的目标文件)未满足产生的错误。
另外一般情况下失败也不需要 make clean,重新 make 即可。程序会自动从上次中断的地方继续。
重试了好几次之后终于编译成功。
我们已经可以看到生成的 factory 和 sysupgrade 文件,这说明我们的工具链可以正常工作。
可以试着刷一下,看看新的固件是不是可以正常工作。
可以顺利通过 SSH 登录到路由器。版本是 Designated Driver r49377,内核版本 4.1.23。
启动日志如下:
这样我们初步的准备就算是完成了,我们可以开始下一步工作了。
BuildRoot - Customization
我们上一步使用默认设置编译的固件实在是功能贫乏,因此我们需要增加最基本的功能以保证正常的使用。
同时为了缩小体积我们需要删除不会用到的部分。固件默认包含的功能中 IPv6 、opkg 包管理器以及其他很多功能都是我们不需要的。我们将在下面的流程中把它们逐个找出来并移除。
打开 make menuconfig 准备设置。
首先,LuCI 当然是重点。选中 LuCI - Collections - luci。当前面的选项变为 <*> 时代表已经正确选中。
选中 luci 将会同时选中相关的一系列包。我们在 LuCI - Modules 中选中 Minify Lua Sources 压缩 Lua 脚本以增大固件中的可用空间。
选择主题。一般只需要默认的 luci-theme-bootstrap 就可以了。如果剩余空间足够大,也可以体验一下全新的 Material 风格主题。
LuCI 的定制就算完成,下面我们开始从头看每一个选项。
首先是 Global 部分。这里我们可以对整个编译流程进行控制,也可以对内核支持的功能进行简单的定制。
由于 Flash 的可用空间实在是太小,我们尽量关掉下面与调试信息相关的选项:
- Crash Logging
- Support for paging of anonymous memory (swap)
- Compile the kernel with symbol table information
- Compile the kernel with debug information
同时打开下面的选项以裁剪固件大小。选中下面两个选项相当于彻底断绝了在路由器上通过包管理器安装软件的可能性(需要就重新编译嘛 2333)。
- Remove ipkg/opkg status data files in final images
- Strip unnecessary exports from the kernel image
- Strip unnecessary functions from libraries
另外,为减小体积我们需要移除 IPv6 相关支持。在这里关闭 IPv6 支持标记,以便删除 IPv6 相关的模块。
- Enable IPv6 support in packages
全局定制完成后,我们看后面的选项。
- Advanced configuration options (for developers)
- Build the OpenWrt Image Builder
- Build the OpenWrt SDK
- Package the OpenWrt-based Toolchain
这四个选项是为开发者准备的。Advanced configuration options 中可以给工具链指定更多参数,另外的三个则是生成 SDK 和 ImageBuilder 以及打包自带工具链,我们不用管。
Image Configuration 中可以指定一些其他选项,比如 Init 脚本和包管理器相关信息。
我们在这里去掉 Feeds 以减少空间:
- Separate feed repositories
之后是 Base System 部分,这里是系统核心支持相关的部分。
删除 opkg【就几百 KB 空间还装什么软件,包管理器删掉】。
WR703N 总共只有一个以太网口,交换机配置工具也可以删掉。
这里就完成了。
下面几个选项都是酱油。
- Administration 页中我们并没有什么用得上的,跳过。
- Boot Loaders 我们直接用已经刷好的 Breed,跳过。
- Development 页面……我们路由器上并没有空间放 gcc 和 gdb。跳过。
- Extra Packages 是空的,不用管了。
- Firmware 并不用选,跳过。
Kernel Modules 我们就要仔细选择了。
我们在这里需要做的事情是添加 USB RNDIS 设备支持以便可以正确实现通过 USB 线共享网络。
进入 USB Support 页面,可以看到官方已经帮我们选中了 kmod-usb-ohci 和 kmod-usb2。
我们选中 kmod-usb-net 和下面的 kmod-usb-net-rndis:
这里就结束了。
为了减小空间,我们还要去掉 MAC80211 的调试信息部分。进入 Wireless Drivers 页面:
进入 kmod-mac80211,关闭 DebugFS 支持。
内核部分的定制就完成了。
【在 15.05.1 中关闭 IPv6 还需要在这里手动去除一部分模块的支持,不过最新的 Trunk 似乎已经通过一个选项帮我们完成了所有任务】
后面又是几个酱油选项:
- Languages 页上……我们的路由器上并没有空间运行 PHP 或者 Node.js,跳过。
- Libraries 页不太需要我们自己管,选中某一个功能时系统会自动在这里选中依赖的库。跳过。
- LuCI 上面选过了。
- Mail 页有一些邮件工具,我们用不上,跳过。
- Multimedia 页有一些 mjpg-streamer 之类的,挂摄像头监控用。我们也用不上,跳过。
Network 页上我们去掉 odhcpd 就行,因为它的功能我们直接用 dnsmasq 提供了。
这里还有一个 uclient-fetch 我们应该用不上,也顺便删掉吧。
这样 Network 部分就完成了。
后面两个酱油:
- Sound 不用多解释了吧。话说里面居然有了 mpg123……简直感人……不过我们这里还是用不上,跳过。
- Utilities 实用工具,目前我们不是很用得上,跳过。有需要的话可以自己挑。
最后因为上面我们关掉了 MAC80211 的 DebugFS 支持,我们还需要回到 Global 中关掉 Debug Filesystem。
至此配置全部完成。保存,可以开始准备编译了。
第二次编译很快,不到三分钟我们就得到了 bin 文件。
可以看到,虽然添加了 LuCI 和 RNDIS 支持,但由于我们选用正确的选项进行精简,得到的 Bin 文件反而还小了 100 多 KB。
刷上。成功启动,并且看到了 LuCI 界面。
测一下 RNDIS 支持是否正常。
定制成功 :)
BuildRoot - Add ShadowSocksR
前面我们已经顺利的完成了定制,现在我们需要增加 ShadowSocksR 透明代理支持。
ShadowSocksR 的源代码可以在【这里】 找到。
首先,git clone。
然后 make menuconfig。
按照作者的说明,我们需要进行下面这些操作:
- 选中 shadowsocks-libev-gfwlist-4M
- 安装完整版的 dnsmasq(dnsmasq-full)
- 打开 wget 的 -T 选项支持
首先选中 Network 页中的 shadowsocks-libev-gfwlist-4M。
回到 Base System,我们可以看到 dnsmasq-full 已经被自动选中。我们在这里去掉精简版的 dnsmasq,同时去除完整版的 DNSSEC、权威 DNS、ConnTrack 支持这三个特性,只保留 IPset。
选中上面的 busybox,对 busybox 进行定制。
选中 Networking Utilities,在下面找到 wget,然后选中 -T Timeout 支持。同时我们也可以顺便关闭一些 IPv6 支持相关的选项。
完成之后保存,编译即可。我们看到这次编译后报的体积比之前增大了大约 400KB,不过还没有超出大小。
编译成功之后刷进去看看吧。
顺利启动,RNDIS 也可以正常工作。
ShadowSocksR 顺利加载。顺便 ShadowSocksR 的作者好像在这里填了一个可以随便用的 ShadowSocks 服务器账号,真是 233333
Watchdog 顺利启动。实测上 Google 也没有问题了。
那么我们本次定制就顺利完成了。感觉好像不会有下次了吧 23333 说不定呢。
Comments