- OpenWrt 简介:理解它是什么,为什么用它。
- 开发环境准备:搭建编译和开发所需的软硬件环境。
- OpenWrt 源码结构:了解核心目录和文件的作用。
- 编译系统详解:从
make menuconfig到生成固件的全过程。 - 添加自定义软件包:这是开发的核心,包括 Hello World 和复杂应用。
- 设备驱动开发:如何为硬件添加内核驱动。
- 创建自定义固件:将你的软件包和配置打包成最终的固件文件。
- 调试与烧录:如何将固件烧录到设备并进行调试。
- 进阶学习资源:持续学习的方向。
OpenWrt 简介
OpenWrt 是什么? OpenWrt 是一个从 Linux 内核到用户空间高度定制的、开源的嵌入式操作系统,它不是一个简单的路由器固件,而是一个完整的、可扩展的 Linux 发行版。

为什么选择 OpenWrt 进行开发?
- 高度可定制:你可以从零开始构建固件,只包含你需要的组件,实现最小化安装。
- 强大的包管理:使用
opkg命令,可以像在 Debian/Ubuntu 上使用apt一样轻松安装、升级或删除软件包。 - 模块化设计:系统由许多独立的软件包组成,添加新功能或修改现有功能变得非常容易。
- 强大的社区支持:拥有庞大而活跃的社区,有海量的第三方软件包和文档支持。
- 现代工具链:使用最新的 GCC、Glibc 等工具链,确保代码的先进性和安全性。
开发环境准备
在开始之前,你需要准备一个开发主机(推荐使用 Linux 或 WSL2 on Windows)。
1 安装依赖 (以 Ubuntu/Debian 为例)
# 更新软件包列表 sudo apt update # 安装构建所需的依赖包 sudo apt install -y build-essential ccache ecj fastjar gawk git g++ unzip libncurses5-dev libncursesw5-dev zlib1g-dev subversion libssl-dev libelf-dev python3-distutils rsync wget # 安装 Python 依赖 sudo apt install -y python3-pip python3-setuptools python3-wheel pip3 install --user six
2 获取 OpenWrt 源码
OpenWrt 使用 Git 进行版本控制,我们推荐从 master 分支获取最新的开发版。
# 创建工作目录 mkdir openwrt && cd openwrt # 克隆官方仓库 git clone https://github.com/openwrt/openwrt.git . # (可选) 初始化子模块 ./scripts/feeds update -a ./scripts/feeds install -a
注意:首次克隆后,你需要耐心等待,因为源码非常大(包含内核、工具链、所有软件包等)。

OpenWrt 源码结构
了解目录结构是高效开发的第一步。
openwrt/
├── feeds/ # 第三方软件包源码
├── package/ # 核心软件包和自定义软件包
│ ├── base-files/ # 系统基础配置文件 (如 /etc 目录下的文件)
│ ├── busybox/ # Busybox 工具集
│ ├── dropbear/ # SSH 客户端/服务器
│ ├── ... # 其他核心软件包
│ └── my-custom-app/ <-- 你将在这里添加自己的软件包
├── target/ # 特定目标平台 (CPU架构) 的配置
│ ├── linux/ # Linux 内核相关
│ └── ... # 如 ar71xx, mediatek, ipq806x 等
├── tools/ # 构建系统所需的工具
├── toolchain/ # 交叉编译工具链 (GCC, Binutils 等)
├── .config # 内核和软件包的配置文件 (由 menuconfig 生成)
├── Makefile # 主构建文件
└── scripts/ # 构建脚本和辅助函数
编译系统详解
编译 OpenWrt 的核心是 make 命令。
1 配置你的固件
make menuconfig
这将打开一个基于文本的图形化配置界面。
- Target System:选择你的路由器硬件平台(如
MediaTek Ralink)。 - Subtarget:选择具体的子系列(如
MT7620 based boards)。 - Target Profile:选择具体的设备型号(如
HILINK HLK-7628N),选择这个后,系统会自动勾选该设备所需的默认软件包。 - Global build settings:可以设置编译线程数 (
Build options->Parallel compile jobs),推荐设置为你的 CPU 核心数。 - Modules:在这里你可以添加或删除软件包。
- 选择
LuCI->Applications可以找到各种网络应用。 - 选择
Network->Routing and Redirection可以找到路由软件。 - 最关键的一步:在
Utilities或其他分类中,找到你之前添加的my-custom-app并勾选它。
- 选择
配置完成后,选择 Save 保存配置,然后选择 Exit 退出,配置会保存在 .config 文件中。
2 开始编译
# 清理之前的编译 (首次构建前可选,但推荐) make clean # 开始编译 (首次编译会非常耗时,请耐心等待) # -j 后面跟线程数,建议使用 CPU 核心数 make -j$(nproc)
编译成功后,你会在 bin/targets/<target_system>/<subtarget>/ 目录下找到生成的固件文件(通常是 .bin 或 .img)。
添加自定义软件包
这是 OpenWrt 开发的核心,我们将创建一个简单的 "Hello World" 应用。
1 创建软件包目录结构
在你的 OpenWrt 源码根目录下,创建以下结构:
package/my-custom-app/
├── Makefile
└── src/
└── helloworld.c
2 编写 C 源码 (src/helloworld.c)
#include <stdio.h>
int main() {
printf("Hello from my custom OpenWrt application!\n");
return 0;
}
3 编写 Makefile (package/my-custom-app/Makefile)
这是告诉 OpenWrt 如何构建你的软件包的关键文件。
include $(TOPDIR)/rules.mk
# 软件包名称
PKG_NAME := my-custom-app
# 软件包版本
PKG_VERSION := 1.0
# 软件包的源码目录
PKG_RELEASE := 1
# 源码目录
PKG_SOURCE := $(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
# 如果没有外部源码,可以留空,我们将直接使用本地文件
PKG_BUILD_DEPENDS :=
include $(INCLUDE_DIR)/package.mk
# 定义软件包信息
define Package/my-custom-app
SECTION:=utils
CATEGORY:=Utilities=A simple Hello World application
MAINTAINER:=Your Name <your.email@example.com>
endef
# 定义如何编译和安装软件包
define Package/my-custom-app/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/helloworld $(1)/usr/bin/
endef
$(eval $(call BuildPackage,$(PKG_NAME)))
Makefile 关键字段解释:
PKG_NAME: 软件包名称,必须和目录名一致。PKG_VERSION: 软件包版本号。SECTION: 软件包分类(如utils,net,admin)。CATEGORY: 在menuconfig中显示的分类。: 软件包的简短描述。define Package/.../install: 定义安装规则。$(INSTALL_DIR)创建目录,$(INSTALL_BIN)复制可执行文件到目标设备的/usr/bin/目录。
4 更新并选择软件包
你需要让 OpenWrt 的包管理系统知道你的新软件包。
# 在 openwrt 根目录下执行 ./scripts/feeds update my-custom-app ./scripts/feeds install my-custom-app
这会在 package/ 目录下创建一个符号链接指向你的 my-custom-app。
然后再次运行 make menuconfig,你可以在 Utilities 分类下找到 my-custom-app 并勾选它,最后保存并退出。
5 重新编译
现在你不需要编译整个固件,只需要重新编译你修改的软件包。
# 清理软件包缓存 (可选) make package/clean # 只编译 my-custom-app make package/my-custom-app/compile
编译成功后,生成的 helloworld 可执行文件会在 bin/packages/<your_arch>/my-custom-app/ 目录下。
设备驱动开发
添加内核驱动比添加用户空间应用更复杂,因为它需要修改内核。
- 获取内核源码:在
make menuconfig中配置并编译一次固件后,完整的内核源码会被下载到build_dir/linux-<kernel_version>目录下。 - 放置驱动代码:将你的驱动代码(
.c和.h文件)放在package目录下的一个新文件夹中,package/my-kernel-driver/。 - 编写 Makefile:编写一个
Makefile来编译你的驱动代码,并将其编译成一个内核模块(.ko文件)。 - 修改内核配置:在
make menuconfig中,你需要启用 "Kernel modules" -> "Other modules" 下的你的驱动。 - 编写安装脚本:在
Package/your_driver/install部分编写脚本,将编译好的.ko文件复制到目标设备的/lib/modules/目录下,并可能需要创建一个启动脚本来加载它。
这个过程与用户空间软件包类似,但更贴近内核,需要你对 Linux 内核模块编程有一定了解。
创建自定义固件
当你添加了所有需要的软件包(包括自定义的 my-custom-app)后,回到 第 4.2 节,执行完整的 make 命令。
make -j$(nproc)
编译完成后,你会在 bin/targets/<target_system>/<subtarget>/ 目录下找到最终的固件文件,openwrt-ramips-mt7620-hlk-7628n-squashfs-sysupgrade.bin,这个文件就是你可以烧录到路由器中的完整操作系统。
调试与烧录
1 烧录固件
不同设备的烧录方法不同,常见方法有:
- Web 界面上传:很多路由器提供固件升级页面。
- TFTP 服务器:设备启动时按住复位键,通过 TFTP 协议上传固件。
- Sysupgrade 命令:如果你刷的是 OpenWrt 官方固件,可以使用
sysupgrade命令在线升级。
# 在路由器上执行 sysupgrade -n /path/to/your/custom-firmware.bin
2 调试技巧
- SSH 登录:刷机后,路由器通常会分配一个 IP 地址(如
168.1.1),使用root用户和默认密码(通常在设备背面标签上)登录。 - 查看日志:
logread命令可以查看系统日志。 - 查看启动信息:
dmesg命令可以查看内核启动时的信息,对于驱动调试非常有用。 - 使用串口:对于深度硬件调试,连接路由器的 UART 串口是获取最底层启动信息和崩溃日志的最佳方式。
- 在软件包中添加调试信息:在
Makefile中添加CFLAGS += -g来编译带调试信息的版本,然后通过gdb或gdbserver进行远程调试。
进阶学习资源
- 官方文档:OpenWrt Wiki 是最权威的信息来源,包含了几乎所有主题的文档。
- 源码就是最好的文档:当你遇到问题时,直接阅读
package/和target/目录下的现有软件包和驱动的Makefile和源码,这是学习的最佳途径。 - 社区论坛:OpenWrt 论坛 是提问和交流的好地方。
- 第三方软件包:浏览
feeds/目录下的软件包,学习其他人是如何构建复杂应用的。
这份教程为你提供了一个完整的 OpenWrt 开发入门路径,从编译第一个固件,到添加自定义应用,再到理解驱动开发,每一步都建立在之前的基础上,祝你开发顺利!
