《智能路由器开发指南》——第2章 开发环境及编译分析 2.1 安装编译环境

    xiaoxiao2024-04-21  9

    本节书摘来自异步社区《智能路由器开发指南》一书中的第2章,第2.1节,作者 张永智,李章明,更多章节内容可以访问云栖社区“异步社区”公众号查看。

    第2章 开发环境及编译分析

    如果你想从事智能路由器OpenWrt开发,首先必须掌握如何编译OpenWrt。本章将从搭建环境,到编译代码,再到安装部署运行以及VirtualBox虚拟网络环境的搭建,一步一步地教你如何进入到OpenWrt大门。

    OpenWrt是一个针对嵌入式设备的Linux发行版。OpenWrt提供了非常方便的开发环境,使用流行的Linux操作系统Ubuntu即可搭建好编译环境。OpenWrt有非常多的平台适应性,可以运行在ARM/MIPS/X86平台上,因此我们的研发网络部署也可以在虚拟机VirtualBox上运行(这样可以降低研发中的硬件成本),待软件开发成熟后再在实际环境中进行运行。因此最后我们也会讲解VirtualBox的网络环境设置。

    2.1 安装编译环境

    2.1.1 Ubuntu安装

    首先安装Linux操作系统Ubuntu 14.4。个人机器多为Windows 操作系统,为了方便使用及节省硬件资源,我们采用虚拟机VirtualBox来安装编译软件环境。如果是实体机安装Linux操作系统,则可略过安装虚拟机这一步。硬件设备只需要一台连接互联网的计算机。软件从互联网下载。建议使用VirtualBox虚拟机来搭建编译环境及开发调试。

    下载和安装VirtualBox和ubuntu 14.04.3。下载地址分别为:

    http://download.virtualbox.org/virtualbox/5.0.0/VirtualBox-5.0.0-101573-Win.exehttp://releases.ubuntu.com/14.04/ubuntu-14.04.3-desktop-i386.iso

    VirtualBox是一个跨平台的虚拟化应用程序。这意味着什么?第一,是它可以安装在你已存在的Intel或AMD兼容的机器上,无论是它运行Windows、Mac、Linux还是Solaris操作系统。第二,它可以扩展你已存在的计算机系统的能力,你可以同时运行多个操作系统(在多个虚拟机内部),例如,可以在你的Mac机上运行Windows和Linux,在Linux服务器上运行Windows Server 2008,在Windows系统上运行Linux等等,这些都在你的VirtualBox应用程序中。你可以安装运行很多虚拟机器,唯一的限制是磁盘空间和内存。

    虚拟机软件VirtualBox完成安装后,在VirtualBox软件中新建计算机,并分配20GB左右的硬盘空间。然后在虚拟机中安装Ubuntu操作系统。Ubuntu操作系统及编译环境需要5GB左右硬盘空间,OpenWrt编译根据选择软件包的多少不同,编译所需空间大小不同。我这里编译完成需要7.1GB的硬盘空间,一般我们会同时编译至少两个版本进行,因此建议虚拟机预留20GB以上的磁盘空间。

    安装增强功能

    虚拟机和主机之间如何传递内容和文件?这就需要“安装增强功能”来在虚拟机和宿主机之间共享剪切板和共享文件目录。可在虚拟机软件上进行以下设置。

    依次单击“设备→安装增强功能”,安装完成后重启生效。依次单击“设备→共享文件夹”,进行共享文件夹设置,这样虚拟机将宿主机的文件目录挂载在自己的根目录下,两个机器可以相互传递文件。依次单击“设备→共享剪切板”,改为双向。这样虚拟机和宿主机之间就可以相互复制粘贴了。

    设置完成后在Ubuntu系统下进行自动挂载设置。在/etc/fstab增加如下一行:

      share      /mnt      vboxsf  rw 0    0

    这样宿主机的共享目录share就可以挂载在虚拟机的/mnt目录下,虚拟机和宿主机均可以对该目录进行操作。这个就可以将编译完成后的文件从虚拟机中传递出来。

    另外一种方式是通过telnet或SSH或串口来登录到Ubuntu上进行控制,使用FTP等工具来进行文件传输。

    2.1.2 安装编译工具

    Ubuntu采用APT(Advanced Packaging Tool)来管理软件包安装、更新、升级及删除等。APT系统的配置文件为/etc/apt/sources.list和/etc/apt/sources.list.d目录。sources.list文件格式如下:

    deb uri distribution [component1] [component2] [...]

    首先第一列为类型,可选类型为deb或deb-src,deb表示为二进制安装包;deb-src表示源代码包。第二列为URI地址,例如,为通过HTTP访问的统一资源定位符。第三列用于指定一个发布版,例如,为trusty表示14.4发布版。最后一列为各个组件标识。

    设置Ubuntu配置升级及更新路径的文件为/etc/apt/sources.list,修改为国内网易的镜像服务器,这样下载速度会比较快。为了防止修改错误,修改之前应事先进行备份,并增加以下内容(参考http://mirrors.163.com/.help/ubuntu.html)。

    deb http://mirrors.163.com/ubuntu/ trusty main restricted universe multiverse deb http://mirrors.163.com/ubuntu/ trusty-security main restricted universe multiverse deb http://mirrors.163.com/ubuntu/ trusty-updates main restricted universe multiverse deb http://mirrors.163.com/ubuntu/ trusty-proposed main restricted universe multiverse deb http://mirrors.163.com/ubuntu/ trusty-backports main restricted universe multiverse

    OpenWrt选择了一种自动化的方式来生成固件:编译环境检查、生成交叉编译链、下载代码包、打补丁、编译及生成固件,一切均从源代码开始,没有隐藏任何细节。我们先来安装代码管理工具Subversion及编译工具。首先输入以下命令进行更新:

    sudo apt-get update

    这条命令用于更新Ubuntu软件仓库中软件包的索引文件。软件仓库的地址是由/ etc/apt/sources.list文件指定的。更新之后安装编译工具,编译工具安装命令如下:

    sudo apt-get install subversion sudo apt-get install g++ flex patch sudo apt-get install libncurses5-dev zlib1g-dev sudo apt-get install git-core sudo apt-get install libssl-dev sudo apt-get install gawk sudo apt-get install xz-util

    (1)Subversion 是一个版本管理系统,可以跟踪文件和目录的历史信息,包含4个W(Who、When、Why和What),即谁做了修改、何时做了修改、为什么修改以及修改的内容。它像CVS一样保存数据源的单份复制,称为仓库,仓库包含了项目中文件的所有历史信息。

    Subversion允许对源代码进行并行修改及管理,知名的Apache社区就采用Subversion来管理代码,其中最重要的是代码管理客户端工具,缩写为svn。这里我们只用到其下载代码功能。

    Subversion采用集中式版本控制系统,其特点是其高可靠性,可用作一种有价值的数据安全的避风港;它的模型使用简单;它支持各种各样的用户和项目需求的能力,包括从小型单人到大型企业的管理需求,因此大多数软件研发公司均采用Subversion作为其代码管理工具。如果个人在Windows平台上使用,推荐采用“VisualSVN Server”作为服务器,其可视化安装及管理非常便于用户使用。

    (2)g++是GNU工程的C/C++编译工具,用于将C语言及C++语言编译为动态链接库或二进制可执行程序。它对代码进行预处理、编译、汇编和链接。通过命令选项可以控制整个编译过程。

    (3)FLEX(The Fast Lexical Analyzer)一个快速词法分析工具。

    (4)patch是将diff文件应用到原始文件的工具,用于在程序开发过程中提交代码,是应用差异文件的工具。这些差异文件由diff程序按行产生。

    (5)libncurses5-dev用于屏幕终端控制。这个包中包括运行那些使用ncurses编译的程序所必须的共享库,同样包含开发使用的头文件、静态库和开发使用的链接文件、文档等。

    (6)zlib1g-dev是压缩及解压缩开发库。包含头文件、静态库、开发示例和文档等。

    (7)git-core是设计用于大型工程的分布式版本管理工具,是另外一种代码管理工具软件。它的每一个仓库都完全保存了整个代码历史,可以脱离网络而使用,首先应用于Linux社区。这里用于下载一些以git管理的软件包。

    (8)libssl-dev 是openssl开发库,用于加密解密、计算哈希和数据签名等。

    (9)gawk是GNU工程实现的AWK语言工具,是文本模式扫描和处理的工具。

    (10)xz-util是xz格式的压缩工具集。它有非常高的压缩比率,并且更快更容易解压缩。

    2.1.3 下载代码

    OpenWrt社区同时使用Subversion和Git两种工具来管理代码。Subversion管理代码非常灵活,通常会创建tags、branches和trunk共3个目录管理代码。trunk目录用来保存开发的主线,一般最新的功能均在trunk目录提交。 branches目录存放分支,用于功能开发完成之后创建分支、修改BUG及发布版本使用,或者某些功能开发分支。tags目录保存标签复制,一个标签是一个项目在某一时间点的“快照”,用来给发布版本的代码创建快照,以便多数开发人员基于这个版本进行开发修改及测试使用,一般永远不再修改。

    OpenWrt也是采用了Subversion的推荐目录配置,除此之外还增加了docs、feeds和packages这3个目录,我们采用svn list命令来查看代码仓库共有6个目录。

    zhang@zhang-laptop:~$ svn list svn://svn.openwrt.org/openwrt/ branches/ docs/ feeds/ packages/ tags/ trunk/

    (1)分支(branches)用于功能开发完成之后创建分支、修改bug及发布版本使用,或者某些功能开发分支。OpenWrt社区每隔两年左右会创建一个分支用于发布特定版本,最新的代码线分支为chaos_calmer。社区在2015年9月12日发布了15.05版本,但未使用SVN创建标签。最近3个分支信息地址请参见表2-1。

    (2)docs保存文档,使用SVN来查看修改历史信息,得出最后修改时间为2007-10-24,现在OpenWrt已经不再使用这个目录。

    (3)feeds保存一些额外扩展的软件包,最后修改时间为2012-11-14,也逐渐不再使用,其中代码已转到使用Git仓库来管理。地址为https://github.com/openwrt 。

    (4)packages保存OpenWrt基础软件包,会被经常用到。最后修改时间为2015-06-01。

    (5)标签(tags)下为发布版本代码,最近稳定版本标签有backfire_10.03.1,attitude_adjustment_12.09。以后版本未创建标签。

    (6)主干(trunk)始终是最新的代码,OpenWrt社区将最新的代码线命名为“Designated Driver”。最新代码包含实验性质的代码,可能会碰到编译或运行的问题,建议新手不要采用。

    注:以上修改时间均为2015年10月12日查询得出,OpenWrt的外围代码已经逐渐转到github提供的Git托管空间上。

    我们选择“Chaos Calmer”的发布代码进行编译,因此使用目录“cc”下载代码。OpenWrt在2016年3月将代码库由Subversion彻底转换为GIT,因此我们使用git命令来下载代码,下载命令如下所示:

    git clone git://git.openwrt.org/15.05/openwrt.git cc

    2.1.4 配置及编译

    现在代码和编译环境准备好了,我们可以开始配置和编译了。我们进入代码目录cc下进行编译。通常分3步,第1步首先更新和安装所有可选的软件包。

    ./scripts/feeds update 更新最新的包定义

    ./scripts/feeds install -a 安装所有的包

    feeds命令将安装扩展代码包编译选项。如果不运行该命令,在menuconfig配置时将没有选择这些扩展包的机会。

    第2步进行编译配置。输入“make defconfig”,在这里会检查所需的编译工具是否齐备,并生成默认的编译配置文件“.config”。

    输入“make menuconfig”后系统将进入配置工具选项菜单来配置编译固件的内容,如图2-1所示。配置选项和Linux内核的编译配置非常相似,使用上下左右箭头按键来在编译选项菜单上导航。按Enter键进入子菜单,连续两次按下Esc键返回上一级菜单,输入问号键将获取帮助信息,顶层配置选项含义如表2-2所示。OpenWrt提供模块化选择编译,每一个模块通常都有3个选项[Y|N|M]可供选择,输入Y该模块将包含在固件中;输入M将作为一个模块来编译,可以后续再进行安装;输入N将不编译该模块。还有一些是单选选项菜单,按空格键进行选择,再次按空格键则取消选择。

    另外还有一些高级功能可以输入字符串进行配置。例如下载文件夹路径设置,可以不使用编译系统默认的源代码下载目录dl,输入系统路径“/opt/dl”来设置,这样在很多人使用同一服务器来编译代码时,不用多次下载相同的代码文件。

    为了便于开发及调试,我们选择x86平台进行编译,并选择自己所需要的软件包,例如网络开发中最常用的抓包工具TcpDump、代码调试工具GDB和Web管理界面luCI等。

    第3步,输入make命令就可以开始编译。编译时首先从Internet上下载软件模块代码,因为OpenWrt仅有编译及配置指令,各种依赖的代码包在上游网站及代码仓库里面。OpenWrt网站也有第三方的代码包镜像,在上游网站不可用时将使用OpenWrt自己的服务器地址,下载地址为http://downloads.openwrt.org/sources/ 。 根据下载速度和选择软件包的数量多少,编译所占时间不同,大约需要3小时以上。编译完成后的二进制安装文件在bin/x86下,各种可选软件安装包在packages目录下。

    make V=s 可以输出编译过程中每一步的执行动作,出错后显示详细的错误信息。

    make -j2 使用2个线程进行并行编译,这样编译速度将大大加快。

    编译过程首先检查编译环境,然后编译host工具,再编译编译工具链,最后编译目标平台的各个软件包。编译make进入各个模块进行编译时,首先下载代码压缩包,然后解压缩,并打补丁,再根据设置选项来生成Makefile,最后根据生成的Makefile进行编译和安装。在编译时需要连接互联网,因为OpenWrt采用补丁包方式来管理代码,第三方的代码不放在它自己的代码库中,仅在编译前从第三方服务器下载。

    编译过程如图2-2所示,我使用了两个进程来编译,除了下载之外花费3小时左右编译完成。

    ~/cc$ make -j2 make[1] world make[2] tools/install make[2] package/cleanup make[3] -C tools/patch compile make[3] -C tools/sstrip compile make[3] -C tools/make-ext4fs compile make[3] -C tools/firmware-utils compile make[3] -C tools/patch-image compile make[3] -C tools/flock compile make[3] -C tools/sstrip install make[3] -C tools/make-ext4fs install make[3] -C tools/firmware-utils install make[3] -C tools/patch-image install make[3] -C tools/flock install make[3] -C tools/patch install make[3] -C tools/sed compile make[3] -C tools/m4 compile make[3] -C tools/xz compile make[3] -C tools/yaffs2 compile make[3] -C tools/cmake compile make[3] -C tools/scons compile make[3] -C tools/lzma compile make[3] -C tools/sed install make[3] -C tools/m4 install make[3] -C tools/pkg-config compile make[3] -C tools/xz install make[3] -C tools/mkimage compile make[3] -C tools/yaffs2 install make[3] -C tools/scons install make[3] -C tools/lzma install make[3] -C tools/squashfs4 compile make[3] -C tools/autoconf compile make[3] -C tools/pkg-config install make[3] -C tools/mkimage install make[3] -C tools/squashfs4 install make[3] -C tools/autoconf install make[3] -C tools/automake compile make[3] -C tools/missing-macros compile make[3] -C tools/automake install make[3] -C tools/missing-macros install make[3] -C tools/libtool compile make[3] -C tools/libtool install make[3] -C tools/gmp compile make[3] -C tools/libelf compile make[3] -C tools/flex compile make[3] -C tools/mklibs compile make[3] -C tools/e2fsprogs compile make[3] -C tools/mm-macros compile make[3] -C tools/cmake install make[3] -C tools/gengetopt compile make[3] -C tools/patchelf compile make[3] -C tools/gmp install make[3] -C tools/libelf install make[3] -C tools/flex install make[3] -C tools/mklibs install make[3] -C tools/e2fsprogs install make[3] -C tools/mm-macros install make[3] -C tools/patchelf install make[3] -C tools/qemu compile make[3] -C tools/mpfr compile make[3] -C tools/bison compile make[3] -C tools/mtd-utils compile make[3] -C tools/gengetopt install make[3] -C tools/qemu install make[3] -C tools/mpfr install make[3] -C tools/mtd-utils install make[3] -C tools/mpc compile make[3] -C tools/mpc install make[3] -C tools/bison install make[3] -C tools/findutils compile make[3] -C tools/bc compile make[3] -C tools/bc install make[3] -C tools/findutils install make[3] -C tools/quilt compile make[3] -C tools/padjffs2 compile make[3] -C tools/padjffs2 install make[3] -C tools/quilt install make[2] toolchain/install make[3] -C toolchain/gdb prepare make[3] -C toolchain/binutils prepare make[3] -C toolchain/gcc/minimal prepare make[3] -C toolchain/kernel-headers prepare make[3] -C toolchain/uClibc/headers prepare make[3] -C toolchain/gcc/initial prepare make[3] -C toolchain/gdb compile make[3] -C toolchain/binutils compile make[3] -C toolchain/kernel-headers compile make[3] -C toolchain/uClibc prepare make[3] -C toolchain/gcc/final prepare make[3] -C toolchain/uClibc/utils prepare make[3] -C toolchain/binutils install make[3] -C toolchain/gcc/minimal compile make[3] -C toolchain/gdb install make[3] -C toolchain/gcc/minimal install make[3] -C toolchain/kernel-headers install make[3] -C toolchain/uClibc/headers compile make[3] -C toolchain/uClibc/headers install make[3] -C toolchain/gcc/initial compile make[3] -C toolchain/gcc/initial install make[3] -C toolchain/uClibc compile make[3] -C toolchain/uClibc install make[3] -C toolchain/gcc/final compile make[3] -C toolchain/gcc/final install make[3] -C toolchain/uClibc/utils compile make[3] -C toolchain/uClibc/utils install make[2] target/compile make[3] -C target/linux compile make[2] package/compile make[3] -C package/system/opkg host-compile make[3] -C package/libs/toolchain compile make[3] -C package/libs/ncurses host-compile make[3] -C package/system/usign host-compile make[3] -C package/boot/grub2 host-compile make[3] -C package/firmware/linux-firmware compile make[3] -C package/network/services/dropbear compile make[3] -C package/libs/libpcap compile make[3] -C package/network/utils/linux-atm compile make[3] -C package/network/utils/resolveip compile make[3] -C package/libs/ocf-crypto-headers compile make[3] -C package/utils/busybox compile make[3] -C package/utils/mkelfimage compile make[3] -C package/libs/libnl-tiny compile make[3] -C package/libs/libjson-c compile make[3] -C package/utils/lua compile make[3] -C package/libs/lzo compile make[3] -C package/libs/zlib compile make[3] -C package/libs/ncurses compile make[3] -C package/kernel/linux compile make[3] -C package/libs/openssl compile make[3] -C package/libs/libubox compile make[3] -C package/utils/util-linux compile make[3] -C package/utils/jsonfilter compile make[3] -C package/system/usign compile make[3] -C package/boot/grub2 compile make[3] -C package/network/utils/iptables compile make[3] -C package/network/ipv6/odhcp6c compile make[3] -C package/network/services/dnsmasq compile make[3] -C package/network/services/ppp compile make[3] -C package/system/mtd compile make[3] -C package/system/opkg compile make[3] -C package/system/ubus compile make[3] -C package/system/uci compile make[3] -C package/utils/ubi-utils compile make[3] -C package/network/config/firewall compile make[3] -C package/network/services/odhcpd compile make[3] -C package/network/config/netifd compile make[3] -C package/system/ubox compile make[3] -C package/system/procd compile make[3] -C package/system/fstools compile make[3] -C package/base-files compile make[2] package/install make[3] package/preconfig make[2] target/install make[3] -C target/linux install make[2] package/index

    图2-2 OpenWrt编译过程

    编译生成物位于代码目录下“bin/x86”目录下。如果想单独编译一个模块可以输入以下命令进行编译,以TcpDump模块为例:

    make package/tcpdump/clean清除编译生成的文件,包含安装包及编译过程生成的临时文件。make package/tcpdump/prepare进行编译准备,包含下载软件代码包、并解压缩和打补丁。make package/tcpdump/configure根据设置选项进行配置并生成Makefile。make package/tcpdump/compile根据生成的Makefile进行编译。make package/tcpdump/install生成安装包。

    以上编译命令都可以添加“V=s”来查看详细编译过程。还有很多全局编译命令含义如下:

    make download下载所有已选择的软件代码压缩包。make clean 删除编译目录。make dirclean除了删除编译目录之外还删除编译工具目录。make printdb 输出所有的编译变量定义。 相关资源:Openwrt开发指南.docx
    最新回复(0)