自制 DD-WRT 固件笔记 (1)
这实在不属于 Wireless Series, 显然是个技术活…
去年年初有篇 说说 OpenWRT,
但好像不到二月份这只 wr841n v5 就变砖了, 也没好意思去再修.
(刷回原厂固件时, 误刷了带 u-boot 的版本, 不断重启)
最近买了 usb-ttl 线, 于是就救回来了. (没细节? )
面对路由器的灯, 找到 J2, 从上往下是 Vcc, GND, RX, TX,
可以参考 TP-Link TL-WR841ND
(反正找对 GND 就好办, 至少不会烧?)
注意固件的大小, 必须是 3932160 bytes.
setenv serverip 192.168.1.2
printenv
tftpboot 0x80000000 841.bin
erase 0x9f020000 +0x3c0000
cp.b 0x80000000 0x9f020000 0x3c0000
bootm 0x9f020000
tftp server 推荐使用 tftpd-hpa,
只是要注意它的 root 目录在 /var/lib/tftpboot.
(于是这路由器就变成 dd-wrt 了)
—
dd-wrt. 整体很好.
但有些功能没有, 有些功能却在浪费空间.
于是就想到移花接木.
把 wr1043n 的固件解压, 把有用的东西拿来. 这个步骤处处是坑…
—
因为这个步骤是个坑, 所以编译就不是坑…
如何取得 dd-wrt 的 kernel source, 写在这里是因为它很大, 1 G 不到.
如果网速慢的话最好赶紧放弃…
这个文件里面有大量的路由器信息.
注意这一句: return ROUTER_BOARD_PB42, 这说明这个路由器对应的是 pb42 目录下的源码.
svn co svn://svn.dd-wrt.com/DD-WRT/src/linux/pb42/linux-2.6.34.6
还有工具链.
current-toolchains.tar.bz2, 很大 (300M+), 因为什么平台的都有…
注意这个工具链是 64bit 用的. 不行的话还是用 kernel.org 的吧.
kernel.org 现成的工具链(Cross-compiler binaries)更小更新更好使, 但这次还是求稳用了 ddwrt 提供的那个.
如果你有幸能下完的话, 只要保留 toolchain-mips_gcc-4.3.3+cs_uClibc-0.9.30.1 一个目录即可
(注意看 uname -a, 或者 zcat kernel | strings 也可以, 怎么得到 kernel 见下)
—
把大件说完了. 下面踩坑
从这里取得 firmware-utils.
svn co svn://svn.openwrt.org/openwrt/trunk/tools/firmware-utils
src 目录里有 mktplinkfw.c, 别高兴太早, 要这样编译…
gcc -o mktplinkfw md5.c mktplinkfw.c
(可能会碰到 bswap_32 什么的问题, 偶使用了一个错误的 bswap_32 的实现… )
正确的实现(放那堆 define 后面即可):
static inline unsigned short bswap_16(unsigned short x) {
return (x>>8) | (x<<8);
}
static inline unsigned int bswap_32(unsigned int x) {
return (bswap_16(x&0xffff)<<16) | (bswap_16(x>>16));
}
喜出望外, mktplinkfw 有这两个参数.
-i file inspect given firmware file file
-x extract kernel and rootfs while inspecting (requires -i)
于是原来的 firmware 就这么被分解了.
—
rootfs 是 squashfs 3.0 + lzma & big endian 的格式. 需要解开.
svn co svn://svn.dd-wrt.com/DD-WRT/src/squashfs-tools
32bit 的机器肯定是不能编译的… 要改 CFLAGS, 藏的都挺隐蔽的(可以看官方教程).
Makefile 也要大修(缩进有问题, 就这样吧).
all: mksquashfs-lzma unsquashfs-lzma
unsquashfs-lzma: unsquashfs.o
$(CXX) unsquashfs.o -L$(LZMAPATH) -llzma -lpthread -o $@
好不容易解开了…
—
删除文件的过程应该没人愿意听.
radius, pptp, sputnik, bird, chilli 什么的都删掉. 想删别的… 先搜索再删?
—
从这里开始请勿模仿…
把 wr1043n 固件里的 radvd, ipv6.ko, sit.ko 搬过来, 重新打包.
因为没有使用 root 权限, 所以打包的时候加上了 -all-root 参数.
mksquashfs-lzma squashfs-root ROOTFS -noappend -be -all-root
然后生成固件. 话说偶为什么知道要这么做呢? 看 Makefile.
mktplinkfw -B TL-WR841NDv5 -N DD-WRT -V 24 -k KERNEL -r ROOTFS -o 841.bin
(注意!!! 这个命令是错的!!! DONT USE THIS COMMAND!!!)
为什么是个错的呢. mktplinkfw -i (原固件)便知.
Kernel load address : 0×80002000 (OpenWrt default: 0×80060000)
Kernel entry point : 0×80002000 (OpenWrt default: 0×80060000)
这么重要的参数居然是错的…
正确的命令不能漏下它们:
mktplinkfw -B TL-WR841NDv5 -N DD-WRT -V 24 -k KERNEL -r ROOTFS -E 0x80002000 -L 0x80002000 -o 841.bin
To be continued…
ps:
0x3C0000 的固件空间内究竟能塞下多少东西呢…
ps2:
rg100a 比较容易改而且 flash 容量也大. 这东西也早就变成商业化产品并提供特殊服务了. 实话说这东西加上改造成本就不合适了.
是的, 在如此小的固件内集成 openvpn 确实是没有问题的, 甚至 ipv6+openvpn 都是可能的(但没有实际测试).
openwrt 因为 ath9k 不好使(历史印象)等原因偶不愿意再测试了.
ps3:
Wireless Series 最近应该也会做补充, 敬请期待.