Openwrt

来自资料库(何亚红)
跳转到导航 跳转到搜索

源代码

主要

https://git.openwrt.org/openwrt/openwrt.git

备用

https://github.com/openwrt/openwrt.git

说明

openwrt是一个嵌入式Linux系统,提供可写的根文件系统。
通常用于无线路由器,也可以做物联网开发。
openwrt可提供完整的嵌入式Linux编译环境,可直接编写应用程序。 常用编译命令参数如下:

项目 类型 说明 备注
menuconfig Makefile目标 使用菜单配置buildroot 有些全局设置只在第一次配置时有效,如不确定是否生效,可删除.config后再使用menuconfig
download Makefile目标 下载构建所需源代码 一般用于网不好时预先下载源代码,使用此目标可较快获取缺失的源代码,此操作可下载大部分需要的源代码,有些源代码需要在编译过程中下载,如Go模块。
V 环境变量/Makefile变量 指定打印的级别,选项标志可组合 一般情况下使用V=sc查看详细信息

个人使用场景

  • 使用采用MT7688芯片作为核心的开发板做物联网开发。

移植提示

MT7688

对于简易的openwrt移植,本人主要做以下步骤:

  • 添加Linux内核设备树。根据硬件的实际连接添加设备树(*.dts)文件,通常可以选一个现成的拿来修改,目录为target/linux/ramips/dts。
  • 添加TARGET_DEVICES。在target/linux/ramips/image找到芯片名称对应的*.mk文件。参照里面其它设备的写法添加一个设备,需要注意的是dts文件名称与设备配置相匹配(不同版本略有不同),dts配置中model(设备型号)配置也须与设备配置一致(否则升级时会提示型号不匹配)。
  • 配置交换机。主要配置那些口为Lan口,那些为Wan,如不配置,固件可能不能启动(直接内核崩溃)。在target/linux/ramips/image找到MT7688对应的02_network文件,参照里面其它配置修改。注意:此配置与dts中的配置要相符合。
  • 添加package。参考package目录下的文件,编写自己的应用程序。
  • 修改基本rootfs文件系统。这是可选的,一般情况可通过添加package实现,但需要修改某些默认的名称就需要做此修改。

常用操作

若无特殊说明,下列操作均在openwrt-22.03测试,如系统版本不一致,下列操作仅供参考,不保证有效。

修改banner

为了登入openwrt时显示自己的图形,需要替换banner文件。

包目录: package/base-files/files/

文件:

  • etc/banner
  • etc/banner.failsafe

使用自己制作的banner文件替换原有文件即可。

修改默认主机名、时区

修改默认主机名需要修改生成默认配置的脚本。如使用升级安装且保留配置,系统会使用保留的配置,如需修改生效,需要恢复出厂设置。

包目录:package/base-files/files/

文件:bin/config_generate

下面是一个将主机名修改为HEYAHONG,时区修改为Asia/Shanghai,并添加中国国家授时中心的ntp服务器的patch:

diff '--exclude=.git' -ruN a/package/base-files/files/bin/config_generate b/package/base-files/files/bin/config_generate
--- a/package/base-files/files/bin/config_generate	2022-05-22 12:08:42.277985634 +0800
+++ b/package/base-files/files/bin/config_generate	2022-05-22 12:55:28.706322868 +0800
@@ -301,8 +301,9 @@
 	uci -q batch <<-EOF
 		delete system.@system[0]
 		add system system
-		set system.@system[-1].hostname='OpenWrt'
-		set system.@system[-1].timezone='UTC'
+		set system.@system[-1].hostname='HEYAHONG'
+		set system.@system[-1].timezone='CST-8'
+                set system.@system[-1].zonename='Asia/Shanghai'
 		set system.@system[-1].ttylogin='0'
 		set system.@system[-1].log_size='64'
 		set system.@system[-1].urandom_seed='0'
@@ -311,6 +312,7 @@
 		set system.ntp='timeserver'
 		set system.ntp.enabled='1'
 		set system.ntp.enable_server='0'
+		add_list system.ntp.server='ntp.ntsc.ac.cn'
 		add_list system.ntp.server='0.openwrt.pool.ntp.org'
 		add_list system.ntp.server='1.openwrt.pool.ntp.org'
 		add_list system.ntp.server='2.openwrt.pool.ntp.org'

此patch可直接保存为.patch文件并使用patch命令打补丁。

编译环境

docker编译环境镜像

openwrt-be : https://hub.docker.com/r/heyahong/openwrt-be

Go模块代理

当openwrt编译基于go语言的软件包时需要下载大量的Go模块,此时若网络不好就会编译失败。

其它种类的源代码包可通过其他的方式下载并放在dl目录,而Go软件的依赖模块一般模块较多,需要使用代理。

在编译前可执行以下命令启用七牛云代理:

export GO111MODULE=on
export GOPROXY=https://goproxy.cn

笔记

openwrt(procd)的Hotplug

Hotplug意为热插拔。在openwrt上使用Procd作为init程序与进程管理系统,当热插拔发生时,Procd将执行/etc/hotplug.d/下子目录的的脚本。

/etc/hotplug.d/下有很多子目录,当触发的事件不同时,执行不同子目录下的脚本,/etc/hotplug.d/子目录的含义如下:

子目录 说明
block Block device events: device connected/disconnected
button Buttons: not created by default, see /etc/rc.button instead
dhcp DHCP-related events
dsl DSL modem events
firewall Firewall-related events
iface Interface events: LAN/WAN/etc. is connected/disconnected
neigh Neighbor discovery
net Network-related events
ntp Time sync events: time step, time server stratum change
tftp TFTP-related events
usb USB devices like 3g-modem and tty*

对于热插拔脚本而言,Procd使用环境变量传递相应参数,如不确定,可将以下脚本放入对应的目录(注意:脚本文件需可执行权限),在系统日志中查看Procd传递给热插拔脚本的环境变量。

#!/bin/sh
logger hotpulg event
logger "`env`"

使用热插拔可在硬件发生变动时执行想要的脚本,如在硬盘插入时做一些操作(如自动挂载)。

环境变量

/etc/hotplug.d/子目录中各个脚本的环境变量不同。

block
变量名称 描述
ACTION For normal device (e.g: sda) it is either “add” or “remove”. Can be “change” if the device is dm-crypt (e.g: dm-0)
DEVICENAME seems same as DEVNAME below
DEVNAME Device or partition name (if I connect a drive I get a hotplug call with “sda” and another hotplug call with “sda1”)
DEVPATH full device path (for example “/devices/pci0000:00/0000:00:0b.0/usb1/1-1/1-1:1.0/host7/target7:0:0/7:0:0:0/block/sdc/sdc1 ”
DEVTYPE what the DEVNAME e DEVICENAME are names of, I've seen “partition” here when a device with a readable partition is inserted and a “disk” when that device is removed.
MAJOR major device number
MINOR minor device number
SEQNUM seqnum (a number)
SUBSYSTEM seems this is only “block”
dsl
变量名称 描述
DSL_NOTIFICATION_TYPE DSL_STATUS, DSL_INTERFACE_STATUS, DSL_DATARATE_STATUS_US, DSL_DATARATE_STATUS_DS
DSL_LINE_NUMBER 0, 1 *

当 DSL_NOTIFICATION_TYPE 为 DSL_STATUS时, 额外的环境变量如下:

变量名称 描述
DSL_XTU_STATUS ADSL, VDSL
DSL_TC_LAYER_STATUS ATM, EFM
DSL_EFM_TC_CONFIG_US NORMAL, PRE_EMPTION, UNKNOWN
DSL_EFM_TC_CONFIG_DS NORMAL, UNKNOWN

当 DSL_NOTIFICATION_TYPE 为 DSL_INTERFACE_STATUS时, 额外的环境变量如下:

变量名称 描述
DSL_INTERFACE_STATUS DOWN, READY, HANDSHAKE, TRAINING, UP
DSL_BONDING_STATUS INACTIVE, ACTIVE *

当 DSL_NOTIFICATION_TYPE 为 DSL_DATARATE_STATUS_US时, 额外的环境变量如下:

变量名称 描述
DSL_DATARATE_US_BC0 Upstream data rate in bit/s for Channel 0
DSL_DATARATE_US_BC1 Upstream data rate in bit/s for Channel 1 *

当 DSL_NOTIFICATION_TYPE 为 DSL_DATARATE_STATUS_DS时, 额外的环境变量如下:

变量名称 描述
DSL_DATARATE_DS_BC0 Downstream data rate in bit/s for Channel 0
DSL_DATARATE_DS_BC1 Downstream data rate in bit/s for Channel 1 *

注意: 带*的环境变量为可选项,仅当某些支持被启用时生效。

iface
变量名称 描述
ACTION ifdown, ifup, ifup-failed, ifupdate, free, reload, iflink, create
INTERFACE Name of the logical interface which went up or down (e.g. wan or lan)
DEVICE Name of the physical device which went up or down (e.g. eth0 or br-lan or pppoe-wan), when applicable

当 ACTION 是 ifupdate时, 额外的环境变量如下:

变量名称 描述
IFUPDATE_ADDRESSES 1 if address changed since previous ifupdate event
IFUPDATE_ROUTES 1 if a route changed since previous ifupdate event
IFUPDATE_PREFIXES 1 if prefix changed since previous ifupdate event
IFUPDATE_DATA 1 if ubus call network.interface.$INTERFACE set_data ... (or equivalent) happened
ntp
变量名称 描述
ACTION step, stratum, unsync or periodic
freq_drift_ppm ntp variables
offset Time adjustment done
stratum Quality (nr of servers to atomic clock)
poll_interval ntp variables
usb
变量名称 描述
ACTION add, remove as above
DEVNAME eg, “bus/usb/001/002”
DEVPATH eg, “/devices/platform/ehci-platform/usb1/1-1”
DEVICENAME eg “1-1”
DEVNUM eg 002
DRIVER “usb”
TYPE eg 9/0/1
PRODUCT the vendor/productcode/version, eg “424/2640/0” see lsusb
SEQNUM ? eg 335
BUSNUM eg 001
MAJOR eg 189
MINOR eg 1

参考资料

Linux内核Hotplug

在早期Linux系统中,可使用kernel的hotplug特性,设置一个热插拔助手程序。现代的Linux系统可能不再使用此特性。

具体方法是在/proc/sys/kernel/hotplug写入热插拔助手程序的路径,当热插拔事件发生时,助手程序被启动,其参数同样是通过环境变量传递的。

若不清楚具体的环境变量,也可将热插拔助手路径设置为一个打印环境变量的脚本。

对于openwrt而言,可能也不使用此特性,具体可查看/proc/sys/kernel/hotplug中的程序是否存在。

可读写的rootfs实现

openwrt添加了一个mtdsplit模块,可使用固件末尾的未使用空间创建一个新的分区,可用作可读写的根分区,主线Linux暂未实现此功能。

openwrt对主线Linux的修改可参见 target/linux/generic/目录。

构建技巧

保存下载的文件

默认情况下,openwrt编译过程中的文件保存在dl目录中,若使用软链接将此下载目录软链接到其它目录,则可实现下载文件的保留(make distclean只会删除dl目录,当dl目录为软链接时,只会删除dl软链接)。

当构建一个新的openwrt时,可在make前将之前保存的目录软链接到dl,则可节省部分下载文件的时间。

官方资料

网址:https://openwrt.org/