10. OpenWrt根文件系统的构建¶
10.1. OpenWrt简介¶
OpenWrt/LEDE是一个为嵌入式设备(通常是无线路由器)开发的高扩展度的GNU/Linux发行版。 与许多其他路由器的发行版不同,OpenWrt是一个完全为嵌入式设备构建的功能全面、 易于修改的由现代Linux内核驱动的操作系统。 在实践中,这意味着您可以得到您需要的所有功能,却仍能避免臃肿。
OpenWrt不是一个单一且不可更改的固件,而是提供了具有软件包管理功能的完全可写的文件系统,让您通过使用适配任何应用的软件包来定制设备。
OpenWrt SDK 更简化了开发软件的工序。OpenWRT不同于其他许多用于路由器的发行版,它是一个从零开始编写的、 功能齐全的、容易修改的路由器操作系统。实际上,这意味着您能够使用您想要的功能而不加进其他的累赘, 而支持这些功能工作的linux kernel又远比绝大多数发行版来得新。
对于开发人员来说,OpenWrt是一个无需围绕它构建完整固件就能开发应用程序的框架; 对于普通用户来说,这意味着拥有了完全定制的能力,能以意想不到的方式使用该设备。
OpenWrt官方网站:https://openwrt.org
OpenWrt官方Git仓库:https://github.com/openwrt/openwrt
我们使用基于官方openwrt-19.07长期支持版本源码,并由野火基于EBF6ULL平台进行定制的版本来制作OpenWrt文件系统。
下载地址:http://gitlab.ebf.local/openwrt/gateway/gateway_openwrt_imx6ull.git
10.2. 下载安装编译镜像系统(如果没有编译环境)¶
使用平台:Ubuntu 18.04 LTS 版本
可以使用我们提供的虚拟机镜像 https://doc.embedfire.com/products/link/zh/latest/linux/ebf_i.mx6ull.html#id4
也可以自己下载ubuntu 18.04 LTS官方镜像搭建 https://mirrors.aliyun.com/ubuntu-releases/bionic
10.3. 安装编译工具和依赖¶
编译OpenWrt之前需要安装必要的环境工具。
1 2 3 | sudo apt install -y subversion g++ zlib1g-dev build-essential git
sudo apt install -y libncurses5-dev gawk gettext unzip file libssl-dev
sudo apt install -y python rsync man-db wget zip time aria2
|
10.4. 获取野火OpenWrt源码¶
通常一个内核仓库往往维护着不同分支的内核源码,进入仓库目录下可通过命令查看及切换内核分支
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #克隆野火OpenWrt源码
git clone http://gitlab.ebf.local/openwrt/gateway/gateway_openwrt_imx6ull.git
#查看uboot分支
git branch -a
#打印消息如下
* openwrt-19.07
remotes/origin/HEAD -> origin/openwrt-19.07
remotes/origin/openwrt-19.07
#切换openwrt-19.07分支
git checkout openwrt-19.07
#打印消息如下
已经位于 'openwrt-19.07'
您的分支与上游分支 'origin/openwrt-19.07' 一致。
#重新查看当前分支
git branch
#打印消息如下,成功切换分支到 openwrt-19.07
* openwrt-19.07
|
也可以在下载时指定分支,如下所示
1 | git clone -b openwrt-19.07 http://gitlab.ebf.local/openwrt/gateway/gateway_openwrt_imx6ull.git
|
10.5. OpenWrt工程结构分析¶
OpenWrt内核源码目录如下
1 2 3 4 5 | bin dl key-build.pub make_fire.sh staging_dir
BSDmakefile feeds key-build.ucert package target
build_dir feeds.conf.default key-build.ucert.revoke README tmp
config include LICENSE rules.mk toolchain
Config.in key-build Makefile scripts tools
|
我们简单分析一下部分目录的作用
bin :编译最终生成的ipk软件包和使用打包脚本生成的最终文件,如压缩打包好的根文件系统和设备树、内核等。
dl : 编译前下载的软件包源码(此过程对网络条件有要求,须访问国外软件服务器)。
staging_dir : 保存工具、内核、工具链等所有代码的编译结果。
feeds :第三方软件包索引存放的位置。
package :官方软件包索引存放的位置。
target :主要是和平台有关的代码,最主要的是linux文件夹。
build_dir :用来解压所有的源代码和编译它们的位置。
include :顶层通用Makefile,其他Makefile中包含的Makefile都可以在其中找到。
toolchain :交叉编译工具链相关。
scripts :脚本工具,包括一些用shell,perl,python编写的通用工具。
tools :编译使用到的工具集。
除了上述目录外,还有一些文件值得我们关注
.config :OpenWrt的配置文件
feeds.conf.default :feeds包的远程地址
make_fire.sh :野火构建脚本,可用于挖完成编译前的准备工作
10.6. OpenWrt编译前的准备工作¶
在编译OpenWrt源码前,我们还要进行一些准备工作,以满足编译的要求。
10.6.1. 更新升级软件包¶
从git拉取软件包索引仓库到本地,并更新本地软件包列表。相关内容存放在feeds目录。
1 2 3 | #更新升级软件包列表
./scripts/feeds update -a
./scripts/feeds install -a
|
10.6.2. 修改OpenWrt配置文件¶
我们需要运行以下命令来选在硬件平台和需要的软件包。
10.6.2.2. 配置说明¶
Target System : 选择NXP i.MX 6
Subtarget:选择NXP i.MX 6 with Cortex-A7
Target Profile:根据型号选择,编译nand版本则选择 Embedfire 6ULL NAND
Target Images:配置生成镜像打包时的相关参数,rootfs和kernel的分区大小可以在这里配置。
选择完成后,退出并保存。
警告
由于没有在OpenWrt自带内核中添加野火EBF6ULL开发板,直接选择 Embedfire 6ULL NAND 会导致编译失败。 如果想要编译野火定制镜像,请查看野火定制镜像构建章节。如想体验原生OpenWrt编译过程,请选择非野火硬件进行编译。
如果要保存当前的配置文件,可以运行以下脚本。配置文件的保存名称和保存路径可以任意修改。 下面的脚本将配置文件保存在OpenWrt根目录下,名称为defconfig
1 2 | #保存配置文件
./scripts/diffconfig.sh > defconfig
|
如果要将保存的配置文件应用到编译中,可以使用下面的命令。
1 2 3 | #应用保存的配置文件
cat defconfig > .config
make defconfig
|
10.6.3. 下载软件包源码¶
由于大部分软件包的源码托管服务器都在国外,请使用适当方法加速访问,否则会导致软件包下载缓慢或下载失败。
当网络情况良好时,我们可以使用-j选项来进行多线程下载,n为同时下载的线程数,建议不要太大,n小于4。 如果不想多线程下载,着忽略-j选项。
1 2 | #下载软件包源码
make download -jn
|
10.7. 编译OpenWrt¶
1 2 | #下载软件包源码
make V=s -jn
|
使用make命令进行源码的编译。参数V表示输出log的等级,V=s为输出所有的信息,等同于V=99,V=0为不输出,不使用V参数时默认为0。 -j表示同时进行指定数量的任务进行编译,也就是指定编译的线程数,n为线程数大小,不指定-jn参数时自动判断编译所需的线程数。
由于OpenWrt部分软件包不支持多线程编译,当我们指定n大于1时,会有极大的可能导致编译失败, 所以推荐大家使用 make V=s命令来减少不必要的麻烦。
由于我们在实际的开发过程中使用服务器进行编译,服务器具有核心多但单核频率低的特点, 如果仅使用单线程编译,效率甚至不如普通PC。所以,我们往往会先进行多线程编译, 直到工程编译失败,再使用单线程编译,具体过程如下:
1 2 3 4 5 6 7 8 9 10 11 12 | #首先进行多线程编译
make V=s -j56
#遇到编译错误,尝试单线程编译
make V=s -j1
#如果单线程编译不通过,检查详细报错信息并解决错误
#单线程编译报错软件包通过之后,Ctrl+C打断编译,继续使用多线程编译
make V=s -j56
#重复上述过程,直到编译完成
|
注解
以上开发编译流程可以有效提高开发效率,减少编译源码占用的时间。
10.8. 编译完成¶
经过一段时间的编译(具体时间与编译服务器性能相关),我们就得到了编译好的OpenWrt根文件系统,在此过程中还顺便完成了kernel、设备树、Uboot的编译。
编译产生的最终文件,存放在 bin/targets/ 目录下,并根据处理器型号架构进行分类。
10.9. 总结¶
以上就是一个典型的OpenWrt编译流程,借助于OpenWrt SDK的完善,整个过程近似于一键编译。
但是由于我们要定制很多的功能,就需要将更改的配置保存下来,并根据实际情况替换内核和Uboot。
有关野火定制固件的构建将在后面章节详细说明。