开机就要手动敲 ifconfig:一台 Tina Linux 开发板的网络自动配置修复实录
记录时间:2026-10
平台:Allwinner V851se / sun8iw21,Tina Linux 5.0(OpenWrt 系),内核 4.9.191,armv7l,64 MB DDR
现象:开机后网口没有 IP,必须手动ifconfig eth0 up+udhcpc才能上网
结果:开机自动拿 IP、MAC 固定、断链能自愈;顺带把"永远 1970 年"的时间问题也一并解决
一、问题是什么
这块板子刷的是厂商提供的 Tina Linux 镜像。正常情况下插上网线、上电,几秒内就该拿到地址。实际表现是:
- 上电后
ifconfig看不到eth0的 IPv4 地址; ping网关不通;- 但只要手动执行
ifconfig eth0 up
udhcpc -i eth0
立刻就能拿到地址,网也通了。
"手动就好、开机不行"是很典型的初始化顺序/配置错误,不是驱动问题。于是从启动日志开始查。
二、第一现场:启动日志里的三行报错
串口(115200 8N1)抓一次完整启动,把网络相关的行挑出来:
Starting network: Failed to connect to ubus
/sbin/ifup: line 43: /sbin/wifi: not found
FAIL
ifconfig: invalid hw-addr 00:
udhcpc: started, v1.33.2
udhcpc: sending discover
udhcpc: sendto: Network is down
udhcpc: read error: Network is down, reopening socket
[ 14.63] udhcpc: no lease, forking to background
同时内核侧还有两条:
[ 1.583870] Failed to alloc md5
[ 1.587402] eth0: Use random mac address
这三组日志,正好对应三个独立的问题。
三、根因拆解
3.1 ifup 是 netifd 的壳,而 netifd 根本没跑
第一行 Failed to connect to ubus 是突破口。本镜像的 /sbin/ifup 不是 Debian 的 ifupdown,而是 OpenWrt netifd 的封装,它通过 ubus 给 netifd 发指令。
但检查一下系统的实际状态:
| 检查项 | 结果 |
|---|---|
ubusd / netifd / procd 进程 |
都不存在 |
/etc/network/interfaces |
不存在 |
/etc/config/ |
只有 dhcp,没有 network |
/etc/init.d/network(netifd 启动器) |
文件名没有 S 前缀,永远不会被执行 |
也就是说:这个镜像是"半个 OpenWrt"——装了一堆依赖 netifd 的脚本,却没把 netifd 这套运行时启动起来。
于是 /sbin/ifup -a 必然失败 → 网卡没有被 up → 后面 udhcpc 发的所有 discover 都是 Network is down。
这是主因:eth0 从头到尾是 admin-down 状态,DHCP 再努力也发不出包。
3.2 MAC:字段名写错,静默退化成随机 MAC
原脚本是这么取 MAC 的:
MAC_ADDR="`cat /sys/class/sunxi_info/sys_info | awk '1=="sunxi_chipid" {print3}' | sed 's/../&:/g' | cut -c1-14`"
/sbin/ifconfig eth0 hw ether "00:$MAC_ADDR"
但看一下这个文件里实际有什么:
# cat /sys/class/sunxi_info/sys_info
sunxi_platform : sun8iw21
sunxi_secure : normal
sunxi_serial : 1a2b3c4d5e6f...(40 位)
sunxi_chiptype : 00007000
sunxi_batchno : 0x18860001
没有 sunxi_chipid 这个字段(4.9 内核上叫 sunxi_serial)。
结果 awk 输出空串 → MAC_ADDR 为空 → 命令变成 ifconfig eth0 hw ether "00:" → 报 invalid hw-addr 00: → MAC 保持内核分配的随机值。
内核那两条日志就是证据:Failed to alloc md5(eFuse 里没有可用 MAC)、eth0: Use random mac address(退化成随机 MAC)。
后果不只是"看起来不专业":每次开机 MAC 都变,DHCP 服务器每次都当新设备,地址会一路漂移,端口映射、固定 IP 绑定、日志追踪全都失效。
3.3 udhcpc 起跑时,网卡还是 down 的
原脚本最后一句是 udhcpc -b -R &。-b 的语义是"拿不到租约就转后台",看起来没问题。
但执行顺序是:ifup(失败)→ 设 MAC(也失败)→ 起 udhcpc。此时网卡还是 down,udhcpc 的所有 sendto 都返回 ENETDOWN,日志里就是 Network is down。
-b 之后它会 fork 到后台继续重试——但网卡永远没人去 up,所以它重试到天荒地老也没用。
四、先做一次最小验证
在改代码之前,先用最小操作确认"DHCP 服务器和链路本身没问题",避免改错方向:
ip link set eth0 up
sleep 3
cat /sys/class/net/eth0/carrier # 1 = 有载波
udhcpc -i eth0 -f -t 3 -T 3
输出:
udhcpc: sending select for 192.0.2.44
udhcpc: lease of 192.0.2.44 obtained, lease time 86400
udhcpc: setting default routers: 192.0.2.1
拿到地址、默认路由也写进去了。结论:链路、PHY、DHCP 服务器全部正常,问题 100% 在开机脚本。
这一步很重要——很多人跳过它,直接去怀疑网卡驱动或交换机,浪费大量时间。
五、修复:重写 S40network
5.1 完整脚本
#!/bin/sh
#
# Start the network: bring eth0 up with a stable MAC, then run a DHCP client.
#
# Replaces the stock Tina script which relied on OpenWrt's netifd/ifup.
# In this image ubus/netifd is not running and /etc/network/interfaces does
# not exist, so "/sbin/ifup -a" always failed and eth0 was left admin-down;
# udhcpc then sat at "sendto: Network is down" and never got a lease.
# Also /sys/class/sunxi_info/sys_info on this kernel exposes "sunxi_serial",
# not "sunxi_chipid", so the old MAC line expanded to "00:" and failed,
# leaving a new random MAC on every boot.
#
IFACE=eth0
UDHCPC_SCRIPT=/etc/udhcpc.script
# fall back to the netifd-provided script if ours is missing
[ -f "UDHCPC_SCRIPT" ] || UDHCPC_SCRIPT=/usr/share/udhcpc/default.script
PIDFILE=/run/udhcpc.IFACE.pid
WDPID=/run/net-watchdog.pid
mkdir -p /run /run/network
chip_id() {
[ -r /sys/class/sunxi_info/sys_info ] || return 0
id=`awk '1=="sunxi_serial" {print3}' /sys/class/sunxi_info/sys_info`
[ -n "id" ] || id=`awk '1=="sunxi_chipid" {print 3}' /sys/class/sunxi_info/sys_info`
[ -n "id" ] || id=`awk '1=="sunxi_chiptype" {print3}' /sys/class/sunxi_info/sys_info`
[ -n "id" ] || id=`cat /sys/class/net/IFACE/address | sed 's/://g'`
echo "id"
}
set_mac() {
id=`chip_id`
if [ -n "id" ]; then
mac="02:`echo "id" | cut -c1-10 | sed 's/../&:/g;s/://'`"
else
mac="02:11:22:33:44:55"
fi
ip link set dev "IFACE" address "mac" 2>/dev/null || ifconfig "IFACE" hw ether "mac"
echo "MAC mac"
}
wait_link() {
n=0
while [n -lt 10 ]; do
[ "`cat /sys/class/net/IFACE/carrier 2>/dev/null`" = "1" ] && return 0
sleep 1
n=`exprn + 1`
done
return 1
}
dhcp_start() {
pid=`cat "PIDFILE" 2>/dev/null`
[ -n "pid" ] && kill "pid" 2>/dev/null
udhcpc -b -R -i "IFACE" -p "PIDFILE" -s "UDHCPC_SCRIPT" -t 10 -T 3
}
watchdog() {
while true; do
sleep 30
if ! ip -4 addr show dev "IFACE" 2>/dev/null | grep -q "inet "; then
pid=`cat "PIDFILE" 2>/dev/null`
if [ -z "pid" ] || ! kill -0 "pid" 2>/dev/null; then
dhcp_start
fi
fi
done
}
case "1" in
start)
printf "Starting network: "
set_mac
ip link set dev "IFACE" up
wait_link && printf "(link up) " || printf "(link down, will retry) "
ip -4 addr flush dev "IFACE" 2>/dev/null
dhcp_start
watchdog &
echo! > "WDPID"
echo "OK"
;;
stop)
printf "Stopping network: "
pid=`cat "PIDFILE" 2>/dev/null`
[ -n "pid" ] && kill "pid" 2>/dev/null
pid=`cat "WDPID" 2>/dev/null`
[ -n "pid" ] && kill "pid" 2>/dev/null
ip -4 addr flush dev "IFACE" 2>/dev/null
ip link set dev "IFACE" down
echo "OK"
;;
restart|reload)
"0" stop
sleep 1
"0" start
;;
*)
echo "Usage:0 {start|stop|restart}"
exit 1
;;
esac
exit $?
5.2 关键取舍
① 彻底不碰 ifup / netifd。
在这个镜像里它们不可能工作;与其去补 procd/ubus(要移植一整套运行时),不如直接 ip link set dev eth0 up,一行搞定。
② 先设 MAC,再 up。
顺序反了会触发 gmac 重新探测 PHY,日志里出现 ac300-ephy PHY not found! / phy init again 这种吓人的报错——虽然能恢复,但没必要制造噪声。
③ MAC 生成规则:02: + 序列号前 10 位。
sunxi_serial 前 10 位 : 1a2b3c4d5e
最终 MAC : 02:1a:2b:3c:4d:5e
02的二进制是0000 0010:bit0=0 表示单播,bit1=1 表示本地管理地址,不会冒充任何厂商 OUI;- 同一颗芯片恒定,跨重启、跨重刷都不变,DHCP 服务器能稳定认出是同一台设备;
- 取不到序列号时依次回退
sunxi_chipid→sunxi_chiptype→ 当前 MAC,最后兜底写死一个固定值。
如果你们有产线工装把 MAC 烧进 eFuse,这里换成读 eFuse 即可。注意本板内核对 eFuse 的报错是 Failed to alloc md5,说明 eFuse 里确实没有可用 MAC。
④ 等链路,但别死等。
wait_link 最多等 10 秒。网线没插时不能把开机卡住——所以等不到就继续往下走,让 udhcpc 自己退避重试。
⑤ udhcpc 参数要写全。
udhcpc -b -R -i eth0 -p /run/udhcpc.eth0.pid -s /etc/udhcpc.script -t 10 -T 3
-b:没租约时转后台继续重试(不是直接退出);-R:退出时释放租约,避免服务器侧留死租约;-p:写 pidfile,给看门狗判断用;-s:显式指定脚本,不依赖编译期默认路径;-t 10 -T 3:10 次 × 3 秒,给慢速 DHCP 服务器留足响应时间。
⑥ pidfile 必须放 /run。
本镜像里 /var/run 不存在(不是 /run 的符号链接),写 /var/run/xxx.pid 会直接报 nonexistent directory。
⑦ 加一个 30 秒看门狗。
每 30 秒检查一次:没有 IPv4、且 udhcpc 进程不在 → 重新拉起。覆盖"进程被 OOM 杀掉""被误杀"这类极端情况。
5.3 修复后的启动日志
Starting network: MAC 02:1a:2b:3c:4d:5e
[ 8.96] sunxi-gmac gmac0 eth0: Link is Up - 100Mbps/Full - flow control rx/tx
(link up) udhcpc: lease of 192.0.2.44 obtained, lease time 86400
OK
六、顺手修掉"一块网卡两个 IP"
修完主问题后,发现另一个隐患:板上 eth0 曾同时挂着两个同网段地址(192.0.2.17 和 192.0.2.183)。
追下去是 udhcpc 的默认脚本 default.script 的问题——它在 renew 时只做 ip addr add,从不删除旧地址:
setup_interface() {
echo "udhcpc: ip addr add ip/{subnet:-255.255.255.0} ..."
ip addr add ip/{subnet:-255.255.255.0} broadcast {broadcast:-+} devinterface
...
只要租约换过一次地址(服务器重启、网段调整、租期到期重分配),地址就会一直往上叠。
补一行即可:
setup_interface() {
echo "udhcpc: ip addr add ip/{subnet:-255.255.255.0} broadcast {broadcast:-+} devinterface"
+ ip -4 addr flush dev interface
ip addr addip/{subnet:-255.255.255.0} broadcast{broadcast:-+} dev $interface
deconfig 分支本来就 flush,所以只需补 setup_interface 这一处。
七、时间也一起修:从 1970 到自动校时
网络通了之后暴露第二个问题:每次开机时间都是 1970-01-01。
7.1 三层原因
| 层 | 现象 | 性质 |
|---|---|---|
| 驱动/寄存器 | hwclock -r/-w 都成功,写入后读回一致 |
正常,不是固件 bug |
| 掉电保持 | 热重启能保住;拔电就归零 | 硬件:RTC 没有有效备份电源(无纽扣电池 / 电池失效) |
| 走时精度 | 120 秒真实时间,RTC 只走了 115 秒(慢约 4%) | 硬件:32.768 kHz 晶振没起振,实际跑在芯片内部 RC 上 |
对比一下就清楚了:晶振的误差应该是 ppm 级(每天零点几秒),4% 的误差只可能是内部 RC 振荡器。
另外固件侧还有一个实实在在的缺口:镜像里带的 /etc/init.d/sysntpd 是 OpenWrt procd 版本,本机没有 procd/ubus,而且文件名没有 S 前缀、根本不会被执行。也就是说整个系统没有任何校时手段。
所以"每次开机 1970"是「硬件掉电归零」+「固件没有校时」叠加的结果。
7.2 S49ntp:把校时也做成巡检
既然 DHCP 那边能用看门狗自愈,时间也可以。新增一个周期巡检脚本(全文见附录 A),核心循环:
while true; do
if net_ready; then
if ! time_sane; then
insane=`expr insane + 1`
rtc_pending=1
if [insane -ge 2 ]; then
killall -q ntpd 2>/dev/null # 连续两圈时间都不对 → 重启 ntpd 重新 step
sleep 1
insane=0
fi
else
insane=0
fi
start_ntpd
if time_sane; then
if [ rtc_pending -eq 1 ] || [ `exprtick % RTC_WRITE_EVERY` -eq 0 ]; then
if hwclock -w >/dev/null 2>&1; then # 把系统时间写回 RTC
rtc_last=`date -u +%Y-%m-%dT%H:%M:%SZ`
rtc_pending=0
fi
fi
fi
tick=`exprtick + 1`
fi
save_status
sleep $CHECK
done
参数与行为:
| 变量 | 默认 | 含义 |
|---|---|---|
CHECK |
60 | 巡检间隔(秒) |
RTC_WRITE_EVERY |
5 | 每 5 圈(5 分钟)回写一次 RTC |
SANE_YEAR |
2024 | 年份小于它即判定"时间不合理" |
设计要点:
- 时间"坏"了要恢复得快:连续两圈不合理就重启 ntpd,强制它重新做一次 step;
- 恢复正常要立刻回写 RTC,不要等下一个 5 分钟周期——否则这 5 分钟内断电,下次开机又回到 1970;
- RTC 掉电归零是硬件问题,固件救不了,只能靠联网后 NTP 秒级校准;定期回写 RTC 只对热重启有意义(冷启动仍然是 1970)。
状态落在 /run/timekeeper.status,方便排查:
check=2026-10-17T05:48:07Z year=2026 ntpd=1077 restarts=1 rtc=2026-10-17T05:47:06Z
八、验证:行为矩阵
改完之后逐项实测(不是"应该能行",是真实拔插/杀进程/改时间):
| 场景 | 操作 | 实测结果 |
|---|---|---|
| 正常开机 | 网线插好上电 | 链路 up 后 1~2 秒拿到租约 |
| 开机时没插网线 | ip link set eth0 down 后启动 |
打印 Network is down,转后台;插回 20 秒内自动握手 |
| 网线中途拔插 | 运行中 down/up | 地址保留,恢复后继续可用 |
| DHCP 客户端被杀 | kill -9 + 清地址 |
看门狗 45 秒内拉起并重新拿租约 |
| ntpd 被杀 | killall ntpd |
1 个巡检周期内拉起,计数 +1 |
| 时钟被改坏 | date -s "1970-01-01" |
ntpd 4 秒内 step 回正确时间 |
| RTC 回写周期 | 观察状态文件 | 精确每 5 分钟:05:42:06 → 05:47:06 |
| MAC 稳定性 | 连续多次重启 | 始终 02:1a:2b:3c:4d:5e |
九、固化:把改动塞回 BSP 包
板子上改完只是"这一台好了",要交付得改到源码/BSP 里。
9.1 结构:这个工程有点"脏"
目标 SDK 里,OpenWrt 主干是另一个芯片的,本芯片的 BSP 是后补的一个 tar 包(tina-bsp-BOARD.tar.gz),解出来只覆盖 brandy/ device/ openwrt/target/BOARD 三块。
所以改动要落在这个 tar 包里,而不是去动 openwrt/openwrt 公共树。
| # | 包内路径(相对 openwrt/target/BOARD/.../busybox-init-base-files/) |
动作 |
|---|---|---|
| 1 | etc/init.d/S40network |
替换 |
| 2 | etc/init.d/S49ntp |
新增 |
| 3 | etc/udhcpc.script |
新增(netifd 默认脚本 + 1 行 flush) |
9.2 第三个文件为什么要"另起炉灶"
default.script 原本属于 netifd 包(openwrt/openwrt/package/network/config/netifd/...),不在 BSP 包里。两种做法都不好:
- 改 netifd 的文件:破坏"只动 BSP"的原则,还影响其它板子;
- 在 base-files 里放同名路径覆盖:依赖包安装顺序,谁后装谁赢,静默失效最难查。
所以改成:BSP 自带一份 etc/udhcpc.script,让 S40network 显式 -s 指向它。零顺序依赖,也不碰公共树。
9.3 tar 手术要点
cd ~
rm -rf bsp-work && mkdir bsp-work
tar -xzf tina-bsp-BOARD.tar.gz -C bsp-work
B=bsp-work/openwrt/target/BOARD/busybox-init-base-files
cp S40network "B/etc/init.d/S40network" && chmod 755 "B/etc/init.d/S40network"
cp S49ntp "B/etc/init.d/S49ntp" && chmod 755 "B/etc/init.d/S49ntp"
# udhcpc 脚本 = netifd 原文 + 1 行
cp openwrt/openwrt/package/network/config/netifd/files/usr/share/udhcpc/default.script "B/etc/udhcpc.script"
awk '{if (!d &&0 ~ /^[[:space:]]*ip addr add/) {print "\tip -4 addr flush dev interface"; d=1} print}' \
"B/etc/udhcpc.script" > "B/etc/udhcpc.script.new"
mv "B/etc/udhcpc.script.new" "B/etc/udhcpc.script"
chmod 755 "B/etc/udhcpc.script"
# 重打包:按顶层目录名打包,别用 "."(会多出 ./ 前缀)
cd bsp-work && tar -czf ~/tina-bsp-BOARD-new.tar.gz brandy device openwrt
校验结果(本次实测):成员数 2286 → 2288(+2 个新文件),顶层条目、符号链接数量与原子一致,三个文件权限均 755,sh -n 全过。
一个反直觉但重要的点:备份文件不能叫
Sxx...。这个镜像的rc.final用for i in /etc/init.d/S??*遍历执行,任何S开头的残留都会被当启动脚本跑一遍。我第一次把备份存成S40network.orig,结果开机时旧脚本又跑了一次,把新脚本设的地址又清掉——日志里出现两条Starting network。备份应放/root/或改成不以S开头的名字。
十、踩过的坑
| 坑 | 现象 | 应对 |
|---|---|---|
udhcpc -b 转后台后"没有日志" |
fork 之后 stdout 被重定向到 /dev/null,控制台再也不打印 sending discover,很像卡死 |
别信日志,看 ps 和 ip addr;进程其实在按退避间隔重发 |
/var/run 不存在 |
写 pidfile 报 nonexistent directory |
统一用 /run |
备份名以 S 开头 |
rc.final 的 S??* 通配把它当启动脚本执行,导致重复初始化 |
备份放 /root/,或改名 |
| busybox 裁得很狠 | 没有 wc、head、stat、df、timeout、tar |
用 awk/sed 替代;大文件解压只能靠 python3 -m tarfile |
/tmp 是 28 MB tmpfs |
写大文件报 No space left |
临时文件放 /mnt/UDISK |
| Windows 下写脚本带 CRLF | 上传后报 \r: not found,expr 报 non-numeric |
传输前统一转 LF |
一次 dmesg 把串口 shell 卡死 |
busybox dmesg 读 /proc/kmsg 阻塞 |
用 Ctrl-C 救回;要看日志改命令别直接 dmesg |
| 长命令经串口/远程执行被吃引号 | 括号、$、中文、空格都会翻车 |
命令写成 .sh 传上去再 bash 执行 |
十一、小结
这case表面上像"网卡驱动有问题",实际是三层叠加:
ifup依赖一套没启动的运行时(netifd),导致网卡从未被 up;- 一个 sysfs 字段名写错,静默退化成随机 MAC;
- DHCP 客户端起跑在网卡 down 之后,失败后不会重来。
修复的关键不是写更多代码,而是把"依赖"去掉:不依赖 netifd,直接用 ip link set up;不依赖"开机一次成功",而是加看门狗让它能自愈。
时间问题同理:硬件(无备份电池 + RC 振荡器)确实修不了,但"固件完全不校时"是可以补的——补上之后,冷启动仍然从 1970 起步,但联网后 1 秒内就对齐了。
最后一点体会:"手动就好、开机不行"几乎总是初始化路径问题,先把启动日志里那几行报错逐字读一遍,比盲猜驱动快得多。
附录 A:S49ntp 全文
#!/bin/sh
#
# Time keeper: periodic NTP supervision + RTC mirror.
#
# Works like the network watchdog in S40network: on a fixed interval it checks
# the state and repairs it, instead of relying on a single one-shot at boot.
#
# - every CHECK seconds: verify eth0 has an address and DNS/NTP is reachable
# - make sure the ntpd daemon is alive (restart it when it died)
# - make sure the system clock is sane (year >= SANE_YEAR); if it stays bogus
# for two consecutive checks, restart ntpd so it does a fresh time step
# - write system time back into the RTC every RTC_WRITE_EVERY checks, and
# immediately once a bogus clock has been corrected. This board's RTC is
# not battery backed and drifts ~4%, so it must be re-seeded regularly.
#
# Disable: rm /etc/init.d/S49ntp
# Servers: edit NTP_SERVERS below
# Tuning: CHECK / RTC_WRITE_EVERY / SANE_YEAR can be overridden from env
#
NTP_SERVERS="ntp.aliyun.com ntp.tencent.com cn.pool.ntp.org"
CHECK={CHECK:-60}
RTC_WRITE_EVERY={RTC_WRITE_EVERY:-5}
SANE_YEAR={SANE_YEAR:-2024}
STATUS=/run/timekeeper.status
PIDFILE=/run/timekeeper.pid
mkdir -p /run
peers() {
p=""
for s inNTP_SERVERS; do
p="p -ps"
done
echo "p"
}
link_up() {
ip -4 addr show dev eth0 2>/dev/null | grep -q "inet "
}
net_ready() {
link_up || return 1
ping -c 1 -W 2 `echoNTP_SERVERS | cut -d" " -f1` >/dev/null 2>&1
}
time_sane() {
y=`date +%Y`
[ "y" -ge "SANE_YEAR" ] 2>/dev/null
}
start_ntpd() {
[ -n "`pidof ntpd`" ] && return 0
ntpd `peers` >/dev/null 2>&1
sleep 1
[ -n "`pidof ntpd`" ] && ntpd_starts=`expr ntpd_starts + 1`
}
save_status() {
echo "check=`date -u +%Y-%m-%dT%H:%M:%SZ` year=`date +%Y` ntpd=`pidof ntpd` restarts=ntpd_starts rtc=rtc_last">STATUS
}
case "1" in
start)
printf "Starting timekeeper: "
(
tick=0
insane=0
ntpd_starts=0
rtc_last="-"
rtc_pending=1
while true; do
if net_ready; then
if ! time_sane; then
insane=`exprinsane + 1`
rtc_pending=1
if [ insane -ge 2 ]; then
killall -q ntpd 2>/dev/null
sleep 1
insane=0
fi
else
insane=0
fi
start_ntpd
if time_sane; then
if [rtc_pending -eq 1 ] || [ `expr tick %RTC_WRITE_EVERY` -eq 0 ]; then
if hwclock -w >/dev/null 2>&1; then
rtc_last=`date -u +%Y-%m-%dT%H:%M:%SZ`
rtc_pending=0
fi
fi
fi
tick=`expr tick + 1`
fi
save_status
sleepCHECK
done
) &
echo !>"PIDFILE"
echo "OK"
;;
stop)
printf "Stopping timekeeper: "
pid=`cat "PIDFILE" 2>/dev/null`
[ -n "pid" ] && kill "pid" 2>/dev/null
killall -q ntpd 2>/dev/null
echo "OK"
;;
restart|reload)
"0" stop
sleep 1
"0" start
;;
*)
echo "Usage:0 {start|stop|restart}"
exit 1
;;
esac
exit $?
附录 B:udhcpc.script 与 netifd 默认脚本的差异
只有一处(setup_interface() 内):
--- default.script (netifd, 1485 B)
+++ /etc/udhcpc.script (BSP, 1518 B)
@@ -18,6 +18,7 @@
setup_interface() {
echo "udhcpc: ip addr add ip/{subnet:-255.255.255.0} broadcast {broadcast:-+} devinterface"
+ ip -4 addr flush dev interface
ip addr addip/{subnet:-255.255.255.0} broadcast{broadcast:-+} dev interface
[ -n "router" ] && [ "router" != "0.0.0.0" ] && [ "router" != "255.255.255.255" ] && {
文章评论