OpenWrt Introduction

概述

OpenWrt 是针对嵌入式设备(特别是无线路由器)的 Linux 系统。OpenWrt使用带有包管理的完全可写的文件系统,这与静态、封闭的固件不同。OpenWrt 可以使用户获得更大的自由来进行个性化的配置(包括应用软件包的选择)、对系统及底层硬件资源完全的掌握。从安全的角度讲,用户可以自己检测固件是否包含安全漏洞或者后门(backdoor)程序,OpenWrt 的更新相对原固件更加及时,安全问题会更快地发现并解决。

参考 OpenWrt Developer Guide

历史

最新版本:22.03.3

设备支持和软件包

设备支持

OpenWrt 支持超过 65+ Target/Soc,覆盖的指令集架构包括 ARMMIPSMIPS64PPCX86x86_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 包管理器。其软件仓库分为 baselucipackagesroutingtelephonybase 为主仓库,由核心开发人员维护;后面 4 个仓库称为 package feeds,它们由社区维护,每个包都有一个维护者。package feed系统很容易扩展,用户可以将自己的包放入官方的feed中或者根据自己手头特殊的固件来定制化feed(将包放到自己的下载服务器中)。

软件包的版本号:上游主版本号-OpenWrt子版本号,子版本号代表 OpenWrt 对该上游软件包进行了修改或者包装(与 debian 系统类似)。

内核本身也可以看作一个软件包,虽然它的编译相对来说更加复杂,但Makefile中的结构和其他软件包基本上都是相同的。

源代码结构

OpenWrt 的源代码仓库:

  • GitWeb - OpenWrt 的 master git仓库
  • GitHub - 持续更新的 GitWeb 的镜像仓库

目录结构:

  • /config : menuconfig 的配置文件
  • /include: 属于主仓库的软件包的makefileconfiguration
  • /scripts: 构建过程中使用的脚本(Perl、Python 和 shell 等)
  • /target: Buildroot构建imagebuildkernelsdktoolchainmakefileconfiguration
  • /toolchain: 构建交叉编译工具链的makefileconfiguration
  • /tool: 构建过程中使用的工具的makefileconfiguration

构建

在第3节中说,OpenWrt 的工具链为交叉编译工具链,因为大部分目标设备的CPU 架构都与 Host 系统不同。对于用户来说,可以手动构建自己的工具链,然后构建 OpenWrt,但这种做法相对困难且很容易出错。

OpenWrt 的构建系统采取了不同的方法:它构建任何一部分都是从零开始、下载、打补丁和编译,包括交叉工具链也是如此。简单地说,OpenWrt 的构建系统不包含任何二进制代码或者源代码,它安全自动化的下载、针对给定的平台打补丁、针对给定的平台进行编译。另外,用户通过修改模板,进而改变这个过程中任何一步的行为。

构建系统所工作的主要目录

  • tools: 构建 toolchainpackagesimage generator所使用的基本软件(例如AutoconfAutomake等);虽然这些基本软件会有一部分已经安装在Host系统上,但 OpenWrt 选择编译自己的工具软件,这使得它不需要担心Host系统可能存在的版本不兼容问题。

  • toolchain: 包括编译器链接器汇编器运行时库通用工具;构建过程中会生成两个其他目录 toolchainbuild{arch}stagingdir{arch};前者是构建临时目录,后者是工具链的安装目录

  • target: 包含针对特定嵌入式平台的补丁或者配置选项;例如target/linux子目录又根据不同的嵌入式平台进行划分,在某个嵌入式平台的目录中包含了对 Linux 内核的补丁和内核配置;类似的,target/imagebuilder子目录描述了如何针对特定平台打包固件。

  • package: 打包后的软件包,后缀名为ipk(就像如果使用debian包格式,后缀名为deb

  • dl: 构建过程中下载的源代码等会放到该目录。

targetpackage步骤中,也会生成临时构建目录build_{arch}

在主目录下会生成 build_dirstaging_dir 目录,build_dir用来解压下载后的软件包源码,然后编译它;staging_dir用来作为所有已编译好的程序的安装目录,它们可以用来构建其他软件包或者集成到最后的固件中。build_dir分为几个子目录:

  • build_dir/host:所有将会运行在 Host系统上的工具,例如sedflex等。
  • build_dir/hostpkg:
  • build_dir/toolchain-xxxxxxx :所有运行在Host系统上的交叉编译工具链、Linux内核,以及被运行在Target系统上的工具多需要链接的库,例如musluClibc(两者都是针对嵌入式设备的 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 原理图: