OpenWrt Introduction
概述
OpenWrt 是针对嵌入式设备(特别是无线路由器)的 Linux 系统。OpenWrt使用带有包管理的完全可写的文件系统,这与静态、封闭的固件不同。OpenWrt 可以使用户获得更大的自由来进行个性化的配置(包括应用软件包的选择)、对系统及底层硬件资源完全的掌握。从安全的角度讲,用户可以自己检测固件是否包含安全漏洞或者后门(backdoor)程序,OpenWrt 的更新相对原固件更加及时,安全问题会更快地发现并解决。
历史
最新版本:22.03.3
设备支持和软件包
设备支持
OpenWrt 支持超过 65+ Target/Soc,覆盖的指令集架构包括 ARM、MIPS、MIPS64、PPC、X86 和 x86_64 。
设备存储容量要求:
- 最小 4M 的 Flash(不支持 GUI),8M 更好(支持 GUI);
- 最小 32M 的 RAM,64M 更好。
如果使用 18.06 或 更高的 OpenWrt 版本,上述 4/32 的最小要求可能无法满足,参看 4/32警告。
ToH 中列举了当前支持的设备列表,根据厂商及型号索引相关支持信息。用户可以更新该列表,加入已经过测试的新设备。
软件包
现在最新 21.02 版本的软件包仓库: Package Index
这些软件包(1000+)可以用来扩展系统的功能,它包括一些分类:管理类(Administration)、语言类(Languages)、库(Libraries)、基础系统(Base System)、引导(BootLoader)、固件(Firmware)、网络类(Network)和 工具类(Utilties)等等。
整体架构
OpenWrt 的整体架构和其他 Linux 发行版系统类似,基本上采用 软件包+包管理器+内核 的结构。
OpenWrt 的软件包在源代码中基本上只有一个 Makefile 文件,其中包含软件包上游的信息以及 OpenWrt 自己所作的修改。这与ArchLinux的做法类似。所有的软件包都使用 OpenWrt 自己的工具链进行编译,但工具链本身需要先通过用户(Host)系统上的编译工具链生成。所以 OpenWrt 的工具链实际上是交叉编译工具链。在 [LFS 0: LFS 项目介绍] 中有更多关于交叉编译的细节。
OpenWrt 使用 opkg 包管理器。其软件仓库分为 base 和 luci、packages、routing、telephony。base 为主仓库,由核心开发人员维护;后面 4 个仓库称为 package feeds,它们由社区维护,每个包都有一个维护者。package feed系统很容易扩展,用户可以将自己的包放入官方的feed中或者根据自己手头特殊的固件来定制化feed(将包放到自己的下载服务器中)。
软件包的版本号:上游主版本号-OpenWrt子版本号,子版本号代表 OpenWrt 对该上游软件包进行了修改或者包装(与 debian 系统类似)。
内核本身也可以看作一个软件包,虽然它的编译相对来说更加复杂,但Makefile中的结构和其他软件包基本上都是相同的。
源代码结构
OpenWrt 的源代码仓库:
- GitWeb - OpenWrt 的
mastergit仓库 - GitHub - 持续更新的 GitWeb 的镜像仓库
目录结构:
- /config : menuconfig 的配置文件
- /include: 属于主仓库的软件包的
makefile和configuration - /scripts: 构建过程中使用的脚本(Perl、Python 和 shell 等)
- /target:
Buildroot构建imagebuild、kernel、sdk和toolchain的makefile和configuration - /toolchain: 构建交叉编译工具链的
makefile和configuration - /tool: 构建过程中使用的工具的
makefile和configuration
构建
在第3节中说,OpenWrt 的工具链为交叉编译工具链,因为大部分目标设备的CPU 架构都与 Host 系统不同。对于用户来说,可以手动构建自己的工具链,然后构建 OpenWrt,但这种做法相对困难且很容易出错。
OpenWrt 的构建系统采取了不同的方法:它构建任何一部分都是从零开始、下载、打补丁和编译,包括交叉工具链也是如此。简单地说,OpenWrt 的构建系统不包含任何二进制代码或者源代码,它安全自动化的下载、针对给定的平台打补丁、针对给定的平台进行编译。另外,用户通过修改模板,进而改变这个过程中任何一步的行为。
构建系统所工作的主要目录
tools: 构建
toolchain、packages或image generator所使用的基本软件(例如Autoconf和Automake等);虽然这些基本软件会有一部分已经安装在Host系统上,但 OpenWrt 选择编译自己的工具软件,这使得它不需要担心Host系统可能存在的版本不兼容问题。toolchain: 包括
编译器、链接器、汇编器、运行时库和通用工具;构建过程中会生成两个其他目录toolchainbuild{arch}和stagingdir{arch};前者是构建临时目录,后者是工具链的安装目录。target: 包含针对特定嵌入式平台的补丁或者配置选项;例如
target/linux子目录又根据不同的嵌入式平台进行划分,在某个嵌入式平台的目录中包含了对 Linux 内核的补丁和内核配置;类似的,target/imagebuilder子目录描述了如何针对特定平台打包固件。package: 打包后的软件包,后缀名为
ipk(就像如果使用debian包格式,后缀名为deb)dl: 构建过程中下载的源代码等会放到该目录。
在target和package步骤中,也会生成临时构建目录build_{arch}。
在主目录下会生成 build_dir 和 staging_dir 目录,build_dir用来解压下载后的软件包源码,然后编译它;staging_dir用来作为所有已编译好的程序的安装目录,它们可以用来构建其他软件包或者集成到最后的固件中。build_dir分为几个子目录:
- build_dir/host:所有将会运行在 Host系统上的工具,例如
sed和flex等。 - build_dir/hostpkg:
- build_dir/toolchain-xxxxxxx :所有运行在
Host系统上的交叉编译工具链、Linux内核,以及被运行在Target系统上的工具多需要链接的库,例如musl和uClibc(两者都是针对嵌入式设备的 C 库)等。 - build_dir/target-xxxxxxx:运行在
Target系统上的软件。
staging_dir 目录也分类类似的几个子目录:
- staging_dir/host :一个小型的 Linux 根目录,包括运行在 Host上的工具,其中有些工具符号链接到 Host 系统上已经安装的相同工具。
- staging_dir/hostpkg:
- staging_dir/toolchain-xxxxxxx:一个小型的 Linux 根目录,包含运行在 Host 上的交叉编译工具链,例如 aarch64-openwrt-linux-musl-gcc。
- staging_dir/target-xxxxxxx/root-xxxx:一个 Linux 根目录,并且是最后生成固件的根文件系统的基础。
特性
- 很容易移植软件。
- 使用
kconfig来配置相关特性。 - 提供内置的交叉编译工具链。
- 处理标准的下载、打补丁、配置、编译和打包工作流。
- 对一些损坏的包提供一些通用的
fixups。
构建流程
a. tools
b. toolchain/binutils - 交叉汇编器、交叉连接器等
c. toolchain/gcc - 交叉编译器(我们在LFS 0: LFS 项目介绍中介绍过,gcc 的构建需要多次 Pass)
d. target/linux - 内核模块
e. package - core(即base)仓库和feed仓库软件包
f. target/linux - 内核镜像
g. target/imagebuilder - 生成固件
补丁管理
Buildroot
简单实践
所用路由器配置
Flash芯片: cFeon QN32B-104HIP 32M 容量
微处理器 A:MediaTek MT7628DBN,该处理器的相关属性如下:
- CPU: 32位 MIPS 24K™CPU核
- 时钟频率:580 MHZ
- I-Cache, D-Cache : 64kb, 32kb
- Memeory: 16bits
- RF : 2T2R 802.11n 2.4 GHz
- USB: 2.0
- DRAM : 8M
微处理器 B: MediaTek MT7613BEN,该处理器的相关属性如下:
- 5G WIFI 芯片
- 64M RAM
MT7628 原理图: