1 编译环境搭建
1.1 安装工具
在下载OpenWrt源码前,需要在Ubuntu系统中安装一系列工具,这些工具主要用于OpenWrt版本管理,解压tar包,编译,打包img等,按如下步骤来安装工具:
sudo apt-get install g++
sudo apt-get install libncurses5-dev
sudo apt-get install zlib1g-dev
sudo apt-get install bison
sudo apt-get install flex
sudo apt-get install unzip
sudo apt-get install autoconf
sudo apt-get install gawk
sudo apt-get install make
sudo apt-get install gettext
sudo apt-get install gcc
sudo apt-get install binutils
sudo apt-get install patch
sudo apt-get install bzip2
sudo apt-get install libz-dev
sudo apt-get install asciidoc
sudo apt-get install subversion
sudo apt-get install sphinxsearch
sudo apt-get install libtool
sudo apt-get install sphinx-common
1.2 下载SourceCode
官网给出的OpenWrt源码下载方式是:
git clone git://github.com/openwrt/openwrt.git
如果从git://github.com/openwrt/openwrt.git这个链接上无法下载,可以改成下面的链接试试:
git clone https://github.com/openwrt/openwrt.git
最新的稳定版分支是chao_calmer,建议切换到稳定分支,使用下面的命令切换:
git checkout -b chao_calmer origin/chao_calmer
注意:从官网上下载下来的OpenWrt源码和marvell内部的OpenWrt源码存在差异,所以官网下载下来的源码仅供学习使用,下面都是基于官网上下载的OpenWrt源码来做的分析,版本是chao_calmer.
1.3 编译前准备工作
在编译OpenWrt之前,需要通过feeds来下载软件套件,主要有:Luci,packages,management,routing,telephone等。OpenWrt提供了一个脚本来做这些软件套件的下载和配置工作,使用下面两个命令完成:
./scripts/feeds update -a
./scripts/feeds install -a
update会将软件套件下载feeds目录下面,install会将feeds的内容创建软链接到package/feeds。
执行命令:
make menuconfig
选择Target System为”Marvell Armada 37x/38x/XP”,选择Target Profile为”Marvell Armada 385 DB AP (DB-88F6820-AP)”,配置选择编译Luci或者其他packages。
menuconfig目标定义在include/toplevel.mk中;
menuconfig: scripts/config/mconf prepare-tmpinfo FORCE
if [ \! -e .config -a -e $(HOME)/.openwrt/defconfig ]; then \
cp $(HOME)/.openwrt/defconfig .config; \
fi
$< Config.in
如果没有找到.config,则将defconfig拷贝到.config。实际上defconfig也是不存在的,所以通过命令scripts/config/mconfig Config.in来生成.config,首目录下面的Config.in会include子目录下面的Config.in。
执行命令:
make kernel_menuconfig
配置kernel的menuconfig,与配置标准的linux menuconfig一样,kernel_menuconfig也是定义在include/toplevel.mk。
kernel_menuconfig: prepare_kernel_conf
$(_SINGLE)$(NO_TRACE_MAKE) -C target/linux menuconfig
make kernel_menuconfig实际上是进到target/linux目录下执行menuconfig。
target/linux/Makefile的menuconfig目标实际上是进到$(BOARD)目录下执行menuconfig,所以最终是执行了target/linux/mvebu/Makefile的menuconfig目标。
kernel的menuconfig目标定义在kernel-build.mk中,规则定义如下:
oldconfig menuconfig nconfig: $(STAMP_PREPARED) $(STAMP_CHECKED) FORCE
rm -f $(LINUX_DIR)/.config.prev
rm -f $(STAMP_CONFIGURED)
$(LINUX_RECONF_CMD) > $(LINUX_DIR)/.config
$(_SINGLE)$(MAKE) -C $(LINUX_DIR) $(KERNEL_MAKEOPTS) $$@
$(LINUX_RECONF_DIFF) $(LINUX_DIR)/.config > $(LINUX_RECONFIG_TARGET)
实际上做了三件事:
1、生成$(LINUX_DIT)/.config
2、进到$(LINUX_DIR)目录执行menuconfig
3、如果.config有修改则保存到$(LINUX_RECONFIG_TARGET);
1. 生成$(LINUX_DIT)/.config
$(LINUX_RECONF_CMD)定义在include/target.mk中。
LINUX_RECONF_CMD = $(call __linux_confcmd,$(LINUX_RECONFIG_LIST),)
__linux_confcmd = $(SCRIPT_DIR)/kconfig.pl $(2) $(patsubst %,+,$(wordlist 2,9999,$(1))) $(1)
LINUX_RECONFIG_LIST = $(wildcard $(GENERIC_LINUX_CONFIG) \
$(LINUX_TARGET_CONFIG) $(if $(USE_SUBTARGET_CONFIG),$(LINUX_SUBTARGET_CONFIG)))
__linux_confcmd就是调用了kconfig.pl脚本,LINUX_RECONFIG_LIST包含了两个文件,一个是target/linux/generic/config-3.18,另一个是target/linux/mvebu/config.3.18。也就使用脚本kconfig.pl来生成.config。
2. 进到$(LINUX_DIR)目录执行menuconfig
这步和普通的linux目录下执行make menuconfig是一样的。
3. 如果.config有修改则保存到$(LINUX_RECONFIG_TARGET)
$(LINUX_RECONF_DIFF)也是kconfig.pl脚本,$(LINUX_RECONFIG_TARGET)是target/linux/mvebu/config.3.18,也就是说如果.config有修改,则会保存到target/linux/mvebu/config.3.18上。
1.4 整体编译
执行make V=s进行整体编译,第一次编译建议使用make V=s,可以看到详细的编译过程以及出错信息,如果想要加快编译速度,可以添加参数-j n,表示使用n条线程同时编译。
整体编译分成下面几个步骤,包括编译host工具、编译交叉工具链、编译内核模块、编译ipk、安装ipk到文件系统、编译内核、将内核和文件系统组合成最终的bin文件。
make clean清除$(BUILD_DIR)、$(STAGING_DIR)、$(BIN_DIR)和$(BUILD_LOG_DIR);
make dirclean清除$(STAGING_DIR_HOST)、$(TOOLCHAIN_DIR)、$(BUILD_DIR_HOST)、$(BUI