如何编译DD-WRT

时间:2021-06-17 17:00:56

http://www.dd-wrt.com/phpBB2/


我这两天在折腾DD-WRT(哦,搞错了,是DD-WRT这两天在折腾我),看了看http://www.dd-wrt.com/wiki/index.php/Development上面的说明,照着做了,编译没通过,而且发现DD-WRT中原来自带的一些脚本已经很老了,没有多想,于是又在其论坛上查找,发现http://www.dd-wrt.com/phpBB2/viewtopic.php?t=28348上面讲解得很详细,但一路走下来还是碰到了几个问题,最终解决,于是我在这里叙述下自己一路怎么走下来的,作为总结,权当翻译和补充好了,希望能给自己和需要了解这方面问题的朋友带来一些帮助。

 

我这里用的目标板是

Chip : Broadcom 5354

SDRAM: 16M

Flash: 4M

Bootloader需自备。

我的编译平台是Debian 2.6.18-6-686,欲编译 kernel v24。

 

具体步骤如下:

1.  安装编译环境:sudo apt-get install gcc g++ binutils patch bzip2 flex bison make gettext unzip zlib1g-dev libc6 libncurses5-dev libstdc++5 automake automake1.7 automake1.9 openssl。

2.  建立一个工作目录:mkdir ~/dd-wrt,然后在此目录下放置和编译,cd ~/dd-wrt。

3.  获取ToolChain并将其解压到工作目录:wget http://www.dd-wrt.com/dd-wrtv2/downloads/others/sourcecode/toolchains/toolchains.x86.debian.sp1.tar.bz2 。拿下来之后tar -jxvf toolchains.x86.debian.sp1.tar.bz2。

4.  获取源代码:若要拿下一份完整的,可以这样做,svn co http://svn.dd-wrt.com/DD-WRT ./DD-WRT或者svn co svn://svn.dd-wrt.com/DD-WRT ./DD-WRT。由于带宽问题,恐怕需要很长时间,我上次是在下班后让它自己慢慢拿的,第二天早上过来看,已经好了。若确定只编译某一个kernel,也可以只拿需要的一部分,可以这样做,
mkdir ./DD-WRT
cd DD-WRT/
svn co -N svn://svn.dd-wrt.com/DD-WRT
svn co svn://svn.dd-wrt.com/DD-WRT/tools
svn co svn://svn.dd-wrt.com/DD-WRT/opt
cd src/
svn co -N svn://svn.dd-wrt.com/DD-WRT/src
svn co svn://svn.dd-wrt.com/DD-WRT/src/include.bcm
svn co svn://svn.dd-wrt.com/DD-WRT/src/include.v23
svn co svn://svn.dd-wrt.com/DD-WRT/src/include.v24
svn co svn://svn.dd-wrt.com/DD-WRT/src/led
svn co svn://svn.dd-wrt.com/DD-WRT/src/ses
svn co svn://svn.dd-wrt.com/DD-WRT/src/shared
svn co svn://svn.dd-wrt.com/DD-WRT/src/router
svn co svn://svn.dd-wrt.com/DD-WRT/src/squashfs-tools
svn co svn://svn.dd-wrt.com/DD-WRT/src/switch
svn co svn://svn.dd-wrt.com/DD-WRT/src/tools
svn co svn://svn.dd-wrt.com/DD-WRT/src/wl
这样下来,若在DD-WRT/和DD-WRT/src/下面未发现Makefile,需要做,cp ./DD-WRT/DD-WRT/Makefile ./DD-WRT/
cp ./DD-WRT/src/Makefile ./DD-WRT/src/

5.  修改几个文件:
vi DD-WRT/src/router/rules/dropbear.mk在第一行和第二行之间添加zlib && make。
vi DD-WRT/src/router/rules/openvpn.mk在第一行和第二行之间添加cd openssl && make。
vi DD-WRT/src/router/rules/tcpdump.mk在第一行和第二行之间添加cd libpcap && make。
由于libpcap_noring的Makefile牢固地绑定了linux.v23分枝,所以可能需要做,vi DD-WRT/src/router/libpcap_noring/Makefile换第53行CCOPT = $(COPTS) -fomit-frame-pointer -fpic -fPIC -I../../brcm/linux.v23/linux/include为CCOPT = $(COPTS) -fomit-frame-pointer -fpic -fPIC -I$(LINUXDIR)/include。
在编译SNMP的时候,可能遇到不能创建临时文件夹的问题,所以可能需要做vi DD-WRT/src/router/snmp/configure换第2325行(umask 077 && mkdir $tmp)为(umask 077 && mkdir -p $tmp)。
在编译使用于本地环境的工具mksquashfs-lzma时,可能遇到
g++ mksquashfs.o read_fs.o sort.o -L./lzma/C/7zip/Compress/LZMA_Lib -llzma -lpthread -o mksquashfs-lzma
/usr/bin/ld: skipping incompatible ./lzma/C/7zip/Compress/LZMA_Lib/liblzma.a when searching for -llzma
/usr/bin/ld: cannot find -llzma
collect2: ld returned 1 exit status
make: *** [mksquashfs-lzma] Error 1
的问题,此时需要做,vi DD-WRT/src/squashfs-tools/lzma/C/7zip/Compress/LZMA_Lib/Makefile换第2行CXX = g++ -O3  -funroll-loops -mtune=opteron -march=opteron -mfpmath=sse -m3dnow -msse2 -mmmx -msse -msse3 -m64 -O3 -Wall -finline-functions为CXX = g++ -03 -funroll-loops -03 -Wall。即便编译通过,最后生成的工具在执行时可能出现故障,所以还需要做,vi DD-WRT/src/squashfs-tools/Makefile换第2行CFLAGS := -I$(INCLUDEDIR) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -funroll-loops -mtune=opteron -march=opteron -mfpmath=sse -m3dnow -msse2 -m64 -O3 -D_LZMA_PARAMS为CFLAGS := -I$(INCLUDEDIR) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -O2 -D_LZMA_PARAMS。

6.  调整源代码,编译本地工具和确定编译对象:我在这里综合了本文开始处提到的两份参考资料,改写了脚本,命名为ready_ddwrt.sh,内容如下:
#!/bin/sh
#
# 标题: ready_ddwrt.sh
#
# 此脚本目的在于为编译做准备
#
MINPARAMS=1
if [ $# -lt "$MINPARAMS" ]
then
echo usage:
echo    ready_ddwrt.sh [ddwrt_base_path]
echo
echo i.e.:
echo ready_ddwrt.sh /home/tomlee/DD-WRT_081113/DD-WRT
echo
exit 1
fi

ME=`whoami`
DDROOT=$1

echo I am $ME
echo DD-WRT is at $DDROOT

echo ................................................................
echo creating some symlinks
echo ................................................................
# 连接自己选定要编译的kernel
ln -s $DDROOT/src/linux/brcm/linux.v24_2 $DDROOT/src/linux/linux
echo done

#Next some tools from the DD-WRT source need to be recompiled to our native environment.
echo ................................................................
echo "re-building some tools"
echo ................................................................
cd $DDROOT

#Under DD_WRT/src/router/tools, do the following
#Code:
cd src/router/tools/
rm jsformat
make jsformat
cd -

#Under DD-WRT/src/squashfs-tools, do the following
#Code:
cd src/squashfs-tools/
rm mksquashfs-lzma
make
cp mksquashfs-lzma ../linux/brcm/linux.v24_2/scripts/squashfs
cd -

#Under DD-WRT/tools, do the following
#Code:
cd tools/
rm ./strip
gcc strip.c -o ./strip
rm ./write3
gcc write3.c -o ./write3
rm ./write4
gcc write4.c -o ./write4
rm ./webcomp
gcc -o webcomp -DUEMF -DWEBS -DLINUX webcomp.c
cd -

# make bb_mkdep
#cd src/router/busybox/scripts
#rm bb_mkdep
#make bb_mkdep
#cd ../../../..

echo done

7.  建立编译环境,提供ToolChain和目标文件放置处的链结:我在这里同样结合了提到的两份参考资料,改写了脚本,命名为read_ddwrt_root.sh,内容如下:
#!/bin/sh
#
# 标题: ready_ddwrt_root.sh
#
# 此脚本的目的在于提供ToolChain和目标文件放置处的链结

MINPARAMS=2
if [ $# -lt "$MINPARAMS" ]
then
echo
echo This script needs root access.
echo
echo usage:
echo    ready_ddwrt_root.sh [ddwrt_base_path] [toolchain_base_path]
echo
echo i.e.:
echo    ready_ddwrt_root.sh /home/tomlee/DD-WRT_081113/DD-WRT /home/tomlee/DD-WRT_081113/toolchains
echo
exit 1
fi

ME=`whoami`
DDROOT=$1
TCHAIN=$2

echo I am $ME
echo DD-WRT is at $DDROOT
echo mipsl-uclibc-x toolchain is at $TCHAIN

echo ................................................................
echo creating some symlinks
echo ................................................................
# 在源代码中可能引用到多个ToolChain,可能由于历史问题造成,其实就用到两份
mkdir -p /opt
rm /opt/3.3.4
rm /opt/3.3.6
rm /opt/3.4.4
rm /opt/3.4.6
rm /opt/4.1.0
ln -s $TCHAIN/3.4.6-uclibc-0.9.28 /opt/3.3.4
ln -s $TCHAIN/3.4.6-uclibc-0.9.28 /opt/3.3.6
ln -s $TCHAIN/3.4.6-uclibc-0.9.28 /opt/3.4.4
ln -s $TCHAIN/3.4.6-uclibc-0.9.28 /opt/3.4.6
ln -s $TCHAIN/4.1.0-uclibc-0.9.28 /opt/4.1.0
rm /GruppenLW
# 最终目标文件放这里
ln -s $DDROOT/image /GruppenLW

echo All done!

至此,准备工作完毕,接下来就是编译了。参考源代码DD-WRT/opt/下面的多个脚本可以发现DD-WRT可生成多种模式的目标文件,且不需要自己手动配置,ls DD-WRT/src/router/.config*,看到的就是原来就准备好的一些配置文件。

我在准备编译的是v24 std 模式,参考其他脚本,自己改写一个,命名为install_std.v24_2.sh,内容如下:
#!/bin/sh
cd ../src/router
cp .config_openvpn.v24 .config
cp ../linux/linux/.config_std ../linux/linux/.config

export MYPATH=$PATH
export PATH=/opt/3.4.6/bin:$MYPATH

make rflow

export PATH=/opt/4.1.0/bin:$MYPATH

make configure

rm -rf mipsel-uclibc/install
make rc-clean
make services-clean
make shared-clean
make httpd-clean
rm busybox/busybox
rm busybox/applets/busybox.o
cd ..
make
cd ../opt
mkdir ../src/router/mipsel-uclibc/target/etc/config
./sstrip/sstrip ../src/router/mipsel-uclibc/target/bin/*
./sstrip/sstrip ../src/router/mipsel-uclibc/target/sbin/rc
./sstrip/sstrip ../src/router/mipsel-uclibc/target/usr/sbin/*

cp ./bin/ipkg ../src/router/mipsel-uclibc/target/bin

cp ./libgcc/* ../src/router/mipsel-uclibc/target/lib
cd ../src/router/mipsel-uclibc/target/lib
ln -s libgcc_s.so.1 libgcc_s.so
cd ../../../../../opt
cp ./etc/preinit ../src/router/mipsel-uclibc/target/etc
cp ./etc/postinit ../src/router/mipsel-uclibc/target/etc
cp ./etc/ipkg.conf ../src/router/mipsel-uclibc/target/etc
cp ./etc/config/* ../src/router/mipsel-uclibc/target/etc/config
cp ./usr/lib/smb.conf ../src/router/mipsel-uclibc/target/usr/lib
cd ../src/router/mipsel-uclibc/target/www

ln -s ../tmp/smbshare smb

cd ../../../../../opt


./strip_libs.sh


../src/linux/brcm/linux.v24_2/scripts/squashfs/mksquashfs-lzma ../src/router/mipsel-uclibc/target target.squashfs -noappend -root-owned –le

./loader-0.02/lzma e ../src/linux/brcm/linux.v24_2/arch/mips/bcm947xx/compressed/piggy vmlinuz
./loader-0.02/lzma e ../src/linux/brcm/linux.v24_2/arch/mips/bcm947xx/compressed/piggy vmlinuzmicro

../tools/trx -o dd-wrt.v24_2.trx ./loader-0.02/loader.gz ../src/router/mipsel-uclibc/vmlinuz target.squashfs

cp dd-wrt.v24_2.trx /GruppenLW/dd-wrt.v24_std_generic.bin

echo All done!

好了,下面要做的事情就是执行这三个脚本,然后等待目标文件被生成:

./ready_ddwrt.sh

./ready_ddwrt_root.sh(这个需要root权限来执行)

cd DD-WRT/opt/

./install_std.v24_2.sh

 

编译结束后,我们可以从/GruppenLW/中取出目标文件,若目标板已经有bootloader并支持tftp的话,也可以直接yuzhu@debian:/GruppenLW$ tftp -i 192.168.1.xxx(目标班子的LAN IP)put xxx.bin(目标文件)

延伸:等待板子起来后,可通过console登录,登录名:root,登录密码:admin。或许会发现WAN口拿不到IP,只有出的数据包,此时可能需要配置板子的VLAN,root@DD-WRT:~# ifconfig查看WAN口所在VLAN,然后执行:

root@DD-WRT:~# nvram set vlanx(WAN口所在VLAN)ports="x x"(具体需参考板子,我这里是4 5)

root@DD-WRT:~# nvram commit

root@DD-WRT:~# reboot

结束:感谢我们老大在此期间给予的极度宽容和巨大帮助,也感谢其他直接或间接给予我支持和帮助的朋友们。

相关资料:

http://svn.dd-wrt.com:8000/dd-wrt

http://www.dd-wrt.com/wiki/index.php/Development

http://www.dd-wrt.com/phpBB2

http://www.dd-wrt.com/phpBB2/viewtopic.php?t=28348

http://svn.dd-wrt.com:8000/dd-wrt/ticket/589

http://www.dd-wrt.com/phpBB2/viewtopic.php?t=28348&postdays=0&postorder=asc&start=45