buildroot debian ubuntu
| 维度 | Buildroot | Debian | Ubuntu |
|---|---|---|---|
| 定位 | 固件生成器 | 通用 Linux 发行版 | 商业化通用发行版 |
| 目标 | 嵌入式量产 | 通用 + 嵌入式 | 桌面 / 服务器 / AI |
| rootfs | 整体生成 | 包管理 | 包管理 |
| 包管理 | ❌ 无 apt | ✅ apt | ✅ apt |
| 系统体积 | 5~50MB | 200MB+ | 1GB+ |
| 启动速度 | 最快(秒级) | 中等 | 最慢 |
| 可裁剪性 | 极高 | 低 | 很低 |
| 可控性 | 100% | 70% | 50% |
| 量产友好 | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐ |
| 学习成本 | 高 | 低 | 最低 |
| 适合你这种工程师 | 非常适合 | 调试舒服 | 偶尔用 |
RK3568 无人送货小车
RK3568 + 无人送货小车 + 2GB RAM / 16GB Flash
👉 首选:Buildroot 👉 调试期可用:Debian ❌ 不建议:Ubuntu
为什么不推荐 Debian 直接量产
| 维度 | Debian | Buildroot |
|---|---|---|
| 出问题你能否“下死手” | ❌ | ✅ |
| 强制复位 modem | ❌ | ✅ |
| USB 断电重枚举 | ❌ | ✅ |
| OTA 可控 | ❌ | ✅ |
| 系统行为可预测 | ❌ | ✅ |
Buildroot 4G
/etc/ppp/peers/quectel-pppd.sh
#!/bin/sh
# ============================================================
# quectel-pppd.sh
# 用于通过 PPP 拨号连接 Quectel 4G 模块(ttyUSB3)
# 参数顺序:devname apn user password
# ============================================================
echo "quectel-pppd options in effect:"
# -----------------------------
# 默认值设置
# -----------------------------
QL_DEVNAME=/dev/ttyUSB1 # 4G 模块对应串口设备
QL_APN=3gnet # 默认 APN,可根据运营商修改
QL_USER=user # PPP 用户名(如果需要)
QL_PASSWORD=passwd # PPP 密码(如果需要)
# -----------------------------
# 命令行参数覆盖默认值
# -----------------------------
if [ $# -ge 1 ]; then
QL_DEVNAME=$1
echo "devname $QL_DEVNAME # (from command line)"
else
echo "devname $QL_DEVNAME # (default)"
fi
if [ $# -ge 2 ]; then
QL_APN=$2
echo "apn $QL_APN # (from command line)"
else
echo "apn $QL_APN # (default)"
fi
if [ $# -ge 3 ]; then
QL_USER=$3
echo "user $QL_USER # (from command line)"
else
echo "user $QL_USER # (default)"
fi
if [ $# -ge 4 ]; then
QL_PASSWORD=$4
echo "password $QL_PASSWORD # (from command line)"
else
echo "password $QL_PASSWORD # (default)"
fi
# -----------------------------
# chat 命令,用于初始化 4G 模块并拨号
# -----------------------------
CONNECT="'chat -s -v ABORT BUSY ABORT \"NO CARRIER\" ABORT \"NO DIALTONE\" ABORT ERROR ABORT \"NO ANSWER\" TIMEOUT 30 \
\"\" AT OK ATE0 OK ATI\;+CSUB\;+CSQ\;+CPIN?\;+COPS?\;+CGREG?\;\&D2 \
OK AT+CGDCONT=1,\\\"IP\\\",\\\"$QL_APN\\\",,0,0 OK ATD*99# CONNECT'"
# 解释:
# - chat -s -v : 安静模式并打印调试信息
# - ABORT … : 遇到这些关键字就停止拨号
# - TIMEOUT 30 : 每步等待 30 秒
# - AT OK … : 发送 AT 指令初始化模块
# - ATE0 : 关闭回显
# - ATI / +CSUB… : 查询模块信息、SIM 状态、信号质量
# - &D2 : 设置 DTR 行断开模块复位
# - AT+CGDCONT=1,"IP","$QL_APN" : 设置 PDP Context
# - ATD*99# : 拨号建立 PPP 链路
# - CONNECT : 表示 chat 成功后进入 PPP 连接状态
# -----------------------------
# 启动 pppd
# -----------------------------
pppd $QL_DEVNAME 115200 user "$QL_USER" password "$QL_PASSWORD" \
connect "'$CONNECT'" \
disconnect 'chat -s -v ABORT ERROR ABORT "NO DIALTONE" SAY "\nSending break to the modem\n" "" +++ "" +++ "" +++ SAY "\nGood bay\n"' \
noauth # 不要求对端认证
debug # 输出调试信息到 stdout
defaultroute # 将 PPP 网卡设置为默认路由
noipdefault # 不使用默认 IP
novj novjccomp noccp # 关闭压缩(Van Jacobson header & CCP)
ipcp-accept-local # 接受对端配置的本地 IP
ipcp-accept-remote # 接受对端配置的远端 IP
ipcp-max-configure 30 # 最大 IPCP 尝试次数
local # 强制本地模式(不使用调制解调器控制线)
lock # 锁定串口,防止并发访问
modem # 使用调制解调器控制信号
dump # 输出 PPP 协议调试信息
nodetach # 不脱离终端,方便后台监控
nocrtscts # 禁用硬件流控
usepeerdns # 使用对端提供的 DNS
& # 后台执行 pppd
# ============================================================
# 注意事项(无人车量产需要考虑)
# 1. 脚本当前没有 watchdog,pppd 掉线不会自动重拨
# 2. PPP 模式效率低,QMI/MBIM 更现代且稳定
# 3. 日志 dump / debug 会频繁写 Flash,量产建议写内存盘
# 4. defaultroute 会覆盖系统默认路由,需要策略路由控制多网口环境
# 5. 建议结合 USB/GPIO 复位,实现模块掉线自愈
# ============================================================
4G 拨号过程
root@rk3568-buildroot:/# sh /etc/ppp/peers/quectel-pppd.sh
quectel-pppd options in effect:
devname /dev/ttyUSB2 # (default) → 你选择的 PPP 数据口
apn 3gnet # (default) → 使用的运营商 APN
user user # (default) → PPP 拨号用户名
password passwd # (default) → PPP 拨号密码
root@rk3568-buildroot:/# pppd options in effect:
debug # (from command line) → 输出详细调试信息
nodetach # (from command line) → 不后台运行,方便调试
dump # (from command line) → 输出数据包内容
noauth # (from command line) → 不要求对端认证
user user # (from command line) → 用户名
password ?????? # (from command line) → 密码(隐藏显示)
/dev/ttyUSB2 # (from command line) → 物理串口
115200 # (from command line) → 波特率
lock # (from command line) → 锁定串口
connect ''chat -s -v ABORT BUSY ABORT "NO CARRIER" ABORT "NO DIALTONE" ABORT ERROR ABORT "NO ANSWER" TIMEOUT 30 "" AT OK ATE0 OK ATI\;+CSUB\;+CSQ\;+CPIN?\;+COPS?\;+CGREG?\;\&D2 OK AT+CGDCONT=1,\"IP\",\"3gnet\",,0,0 OK ATD*99# CONNECT''
# (from command line) → 拨号脚本,用 chat 执行 AT 指令和拨号
disconnect chat -s -v ABORT ERROR ABORT "NO DIALTONE" SAY "\nSending break to the modem\n" "" +++ "" +++ "" +++ SAY "\nGood bay\n"
# (from command line) → 断开连接时执行的 chat 指令
nocrtscts # (from command line) → 禁用 RTS/CTS 硬件流控
modem # (from command line) → 使用 modem 模式
novj # (from command line) → 禁用 Van Jacobson 压缩
novjccomp # (from command line) → 禁用压缩
ipcp-accept-local # (from command line) → 接受对端给本机分配的 IP
ipcp-accept-remote # (from command line) → 接受对端要求分配给对方的 IP
noipdefault # (from command line) → 不使用默认 IP
ipcp-max-configure 30 # (from command line) → IPCP 最大配置尝试次数
defaultroute # (from command line) → 拨号成功后设置默认路由
usepeerdns # (from command line) → 使用对端提供的 DNS
noccp # (from command line) → 禁用压缩控制协议
abort on (BUSY) # 遇到 BUSY 立即中止
abort on (NO CARRIER) # 遇到 NO CARRIER 立即中止
abort on (NO DIALTONE) # 遇到 NO DIALTONE 立即中止
abort on (ERROR) # 遇到 ERROR 立即中止
abort on (NO ANSWER) # 遇到 NO ANSWER 立即中止
timeout set to 30 seconds # 每个 expect 的超时时间
send (AT^M)
expect (OK)
^M
OK
-- got it
# 发送 AT 检查模块是否在线,收到 OK
send (ATE0^M)
expect (OK)
^M
^M
OK
-- got it
# 禁用回显 ECHO,收到 OK
send (ATI;+CSUB;+CSQ;+CPIN?;+COPS?;+CGREG?;&D2^M)
expect (OK)
^M
^M
Quectel^M
EC800M^M
Revision: EC800MCNLFR06A07M04^M
^M
SubEdition: V01^M
^M
+CSQ: 16,99^M
^M
+CGREG: 2,0^M
^M
+CPIN: READY^M
^M
+COPS: 0^M
^M
OK
-- got it
# 查询模块信息、信号质量、注册状态和 SIM 状态,模块返回 OK,SIM 就绪
send (AT+CGDCONT=1,"IP","3gnet",,0,0^M)
expect (OK)
^M
^M
OK
-- got it
# 配置 PDP Context,APN 为 3gnet,模块确认 OK
send (ATD*99#^M)
expect (CONNECT)
^M
^M
CONNECT
-- got it
# 拨号成功,模块返回 CONNECT,表示 PPP 链路可以建立
Script ''chat ... ATD*99# CONNECT'' finished (pid 2752), status = 0x0
# 拨号脚本顺利完成,status=0 表示没有错误
Serial connection established.
using channel 1
Using interface ppp0
# PPP 链路建立成功,使用 ppp0 接口
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0xaa353776> <pcomp> <accomp>]
rcvd [LCP ConfReq id=0x1 <asyncmap 0x0> <auth pap> <magic 0x32d478c8> <pcomp> <accomp>]
sent [LCP ConfAck id=0x1 <asyncmap 0x0> <auth pap> <magic 0x32d478c8> <pcomp> <accomp>]
rcvd [LCP ConfAck id=0x1 <asyncmap 0x0> <magic 0xaa353776> <pcomp> <accomp>]
# LCP 链路协商,双方交换 ConfReq/ConfAck 包
sent [PAP AuthReq id=0x1 user="user" password=<hidden>]
rcvd [PAP AuthAck id=0x1 "" 00]
PAP authentication succeeded
# PPP 认证使用 PAP,认证成功
sent [IPCP ConfReq id=0x1 <addr 0.0.0.0> <ms-dns1 0.0.0.0> <ms-dns2 0.0.0.0>]
rcvd [LCP TermReq id=0x2]
LCP terminated by peer
# 对端模块立即发送 LCP 终止请求,挂断 PPP 链路 → 模块拒绝 PPP
sent [LCP TermAck id=0x2]
rcvd [IPCP ConfReq id=0x0]
Discarded non-LCP packet when LCP not open
rcvd [IPCP ConfRej id=0x1 <ms-dns1 0.0.0.0> <ms-dns2 0.0.0.0>]
Discarded non-LCP packet when LCP not open
Modem hangup
Connection terminated.
# PPP 链路彻底断开,无法分配 IP,最终连接失败
PPP 拨号 对比 QMI 拨号
| 项目 | PPP | QMI |
|---|---|---|
| 年代 | 拨号时代 | LTE 时代 |
| 数据通道 | ttyUSB | wwan0 |
| 稳定性 | ❌ | ✅ |
| 掉线恢复 | 手写脚本 | 模块自动 |
| 维护成本 | 高 | 低 |
| 运营商兼容 | 差 | 好 |
| 无人车量产 | ❌ 不推荐 | ✅ 强烈推荐 |
QMI 拨号
lxg@lxg:~/code/project/linux/rk3568_linux$ ls ./buildroot/board/rockchip/common/base/usr/bin/
4G_dialing.sh 5G_dialing.sh create_ap quectel-CM rkisp_demo rpdzkj-mobilenet.sh video_camera.sh
4G_dialing.sh
#!/bin/bash
# =========================
# 4G 模块自动拨号脚本(Quectel EC20 / EC200 系列)
# 功能:
# 1. 遍历 USB 设备,识别 Quectel 4G 模块
# 2. 判断是否已有网络接口(usb0 / wwan0)
# 3. 若无接口或网络不通:
# - 通过 AT 指令切换 usbnet 模式
# - 启动 quectel-CM 进行 QMI/ECM 拨号
# =========================
# /dev/serial/by-id 下是 udev 创建的“稳定串口名”
DIRECTORY="/dev/serial/by-id"
# 保存最终选中的 AT 串口
Serial_port=""
# 计数器,用于选第 N 个 ttyUSB(Quectel 通常第 3 个是 AT 口)
counter=0
# =========================
# 函数:Switching_mode
# 作用:
# 1. 根据 USB 设备信息拼出 serial-by-id 名字
# 2. 在 /dev/serial/by-id 中找到对应 ttyUSB
# 3. 默认取第 3 个(counter == 2)
# =========================
Switching_mode()
{
# USB 设备信息(来自 sysfs)
PRODUCT_NAME=$(cat "$device_dir/product")
MANUFACTURER=$(cat "$device_dir/manufacturer")
SERIAL_NUMBER=$(cat "$device_dir/serial")
# 生成 /dev/serial/by-id 的前缀名
# 有些模块没有序列号,要兼容
if [ "$SERIAL_NUMBER" == "" ];then
Serial="usb-${MANUFACTURER}_${PRODUCT_NAME}"
else
Serial="usb-${MANUFACTURER}_${PRODUCT_NAME}_$SERIAL_NUMBER"
fi
# 在 by-id 目录中查找对应的串口
# Quectel 模块通常:
# ttyUSB0/1: modem / diag
# ttyUSB2: AT 指令口(经验值)
for file in $(ls "$DIRECTORY" | grep "$Serial" | sort); do
if [ "$counter" -eq 2 ]; then
Serial_port=$file
echo "Serial_port:$Serial_port"
break
fi
counter=$((counter+1))
done
}
# =========================
# 主流程:遍历所有 USB 设备
# =========================
for device_dir in /sys/bus/usb/devices/*; do
if [ -e "$device_dir/idProduct" ]; then
# 读取 USB Product ID
product_id=$(cat "$device_dir/idProduct")
# ==================================================
# EC200 系列(6001 / 6002 / 6005)
# ==================================================
if [ "$product_id" = "6002" ] || [ "$product_id" = "6001" ] || [ "$product_id" = "6005" ]; then
echo "This is a EC200 module!"
# 查找该 USB 设备下暴露的网络接口
for interface in ${device_dir}/*/net/*; do
name=$(basename $interface)
echo "name:$name"
done
# 如果系统中不存在该网络接口
if [ ! -e "/sys/class/net/$name" ]; then
echo "$name not found!!!"
# 查找 AT 串口
Switching_mode "$device_dir"
if [ -e $DIRECTORY/$Serial_port ]; then
# 切换到 usbnet=1(ECM/QMI 模式)
echo -e "AT+QCFG=\"usbnet\",1" > $DIRECTORY/$Serial_port
sleep 1
# 启动 quectel-CM(后台)
/usr/bin/quectel-CM >> /tmp/4G.log 2>&1 &
else
echo "The Serial_port not found!!!"
fi
else
# 网络接口存在,进行连通性测试
echo "This is EC200 Connection test"
ping -c 2 -W 3 -I $name 8.8.8.8
# ping 失败,认为 4G 掉线
if [ ! "$?" == "0" ]; then
echo "EC200 Connect faile!!!"
Switching_mode "$device_dir"
if [ -e $DIRECTORY/$Serial_port ]; then
# 原厂这里注释掉了 usbnet=0
# 表示:不强制切回 PPP
sleep 1
/usr/bin/quectel-CM >> /tmp/4G.log 2>&1 &
else
echo "The Serial_port not found!!!"
fi
else
echo "EC200 Connect success!"
exit 1
fi
fi
fi
# ==================================================
# EC20 系列(0125)
# ==================================================
if [ "$product_id" = "0125" ]; then
echo "This is a EC20 module!"
for interface in ${device_dir}/*/net/*; do
name=$(basename $interface)
echo "name:$name"
done
if [ ! -e "/sys/class/net/$name" ]; then
echo "$name not found!!!"
Switching_mode "$device_dir"
if [ -e $DIRECTORY/$Serial_port ]; then
# EC20 默认使用 usbnet=0(QMI)
echo -e "AT+QCFG=\"usbnet\",0" > $DIRECTORY/$Serial_port
sleep 1
/usr/bin/quectel-CM -d >> /tmp/4G.log 2>&1 &
else
echo "The Serial_port not found!!!"
fi
else
echo "This is EC20 Connection test"
ping -c 2 -W 3 -I $name 8.8.8.8
if [ ! "$?" == "0" ]; then
echo "EC20 Connect faile!!!"
Switching_mode "$device_dir"
if [ -e $DIRECTORY/$Serial_port ]; then
# 同样不强制切换 usbnet
sleep 1
/usr/bin/quectel-CM -d >> /tmp/4G.log 2>&1 &
else
echo "The Serial_port not found!!!"
fi
else
echo "EC20 Connect success!"
exit 1
fi
fi
fi
fi
done
quectel-CM
quectel-CM 是移远(Quectel)官方提供的 4G/5G 数据拨号与链路保持程序,主要用于 QMI / MBIM / ECM 等“非 PPP”拨号方式
查看当前网卡
root@rk3568-buildroot:/# ifconfig
dummy0 Link encap:Ethernet HWaddr 9A:28:A9:0B:24:0E
inet addr:169.254.46.104 Bcast:169.254.255.255 Mask:255.255.0.0
inet6 addr: fe80::e9f8:8c65:5e92:19e0/64 Scope:Link
UP BROADCAST RUNNING NOARP MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:1432 (1.3 KiB)
eth0 Link encap:Ethernet HWaddr A6:FC:A7:E6:8A:8F
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Interrupt:46
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
p2p0 Link encap:Ethernet HWaddr 96:BA:06:E7:0E:34
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
usb0 Link encap:Ethernet HWaddr AE:0C:29:A3:9B:6D
inet addr:100.89.144.41 Bcast:100.255.255.255 Mask:255.0.0.0
inet6 addr: fe80::56c4:6eb9:9036:e032/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:29 errors:0 dropped:0 overruns:0 frame:0
TX packets:45 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2842 (2.7 KiB) TX bytes:3954 (3.8 KiB)
wlan0 Link encap:Ethernet HWaddr 94:BA:06:E7:0E:34
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
root@rk3568-buildroot:/# ip route
default via 100.89.144.214 dev usb0 proto dhcp src 100.89.144.41 metric 1006
100.0.0.0/8 dev usb0 proto dhcp scope link src 100.89.144.41 metric 1006
169.254.0.0/16 dev dummy0 scope link src 169.254.46.104 metric 1002
Buildroot 系统启动脚本
lxg@lxg:~/code/project/linux/rk3568_linux$ ls buildroot/output/rockchip_rk3568/target/etc/init.d/
fuse3 S00mountall.sh S02leds-trigger-config.sh S20urandom S40bluetoothd S41dhcpcd S50pulseaudio S99-auto-reboot S99input-event-daemon
ninfod.sh S01boot-complete.sh S02sysctl S30dbus S40_ec801e S49ntp S50usbdevice.sh S99_camera_node S99_rpdzkj-mobilenet
rcK S01syslogd S05async-commit.sh S35iptables S40network S49weston S80dnsmasq S99chromium-wayland.sh socketcand
rcS S02klogd S10udev S36wifibt-init.sh S40rkaiq_3A S50dropbear S98iodomain.sh S99_config_soundcard
buildroot defconfig
rk3568_linux/buildroot/configs/rockchip_rk3568_defconfig
#include "base/base.config" # 基础配置,必须保留,包含核心工具链和根文件系统基础
#include "chips/rk3566_rk3568_aarch64.config" # RK3568/RK3566 平台配置,必须保留
#include "font/chinese.config" # 中文字体支持,可根据需求保留或删除
#include "fs/exfat.config" # exFAT 文件系统支持,如果不需要外部 exFAT SD/USB 可以删除
#include "fs/ntfs.config" # NTFS 文件系统支持,如果不使用 NTFS 外部盘可删除
#include "fs/vfat.config" # VFAT 文件系统支持,一般U盘必需,建议保留
#include "gpu/gpu.config" # GPU 驱动配置,RK3568 Mali GPU 必须保留
#include "multimedia/audio.config" # 音频支持,可根据无人车场景决定是否保留
#include "multimedia/camera.config" # 摄像头支持,如果无人车有摄像头必需保留
#include "multimedia/gst/audio.config" # GStreamer 音频插件,可根据需求删除
#include "multimedia/gst/camera.config" # GStreamer 摄像头插件,如果使用摄像头采集视频保留
#include "multimedia/gst/rtsp.config" # GStreamer RTSP 流播放/推流插件,若无人车没有 RTSP 流可删除
#include "multimedia/gst/video.config" # GStreamer 视频插件,保留与摄像头视频处理相关功能
#include "multimedia/mpp.config" # RK3568 硬件多媒体编解码器配置,视频解码/编码必需
#include "wifibt/bt.config" # 蓝牙支持,可删除如果无人车不使用蓝牙
#include "wifibt/wireless.config" # Wi-Fi 支持,如果无人车不需要 Wi-Fi 可删除
#include "tools/benchmark.config" # 测试/benchmark 工具,可删除生产环境
#include "tools/common.config" # 常用工具/脚本,建议保留
#include "tools/test.config" # 测试工具,可删除生产环境
#include "chromium.config" # Chromium 浏览器,可删除,如果无人车不需要浏览器UI
#include "npu2.config" # NPU 支持,如果无人车有 AI 推理芯片保留,否则可删除
#include "powermanager.config" # 电源管理,建议保留
#include "weston.config" # Weston 显示服务器,Qt 或 LVGL 全屏可选择保留或删除
#include "qt/qt5.config" # Qt5 库,做 GUI 必需
#include "qt/app.config" # Qt 应用,视具体项目保留
BR2_ROOTFS_OVERLAY+="board/rockchip/rk3566_rk3568/fs-overlay/" # 文件系统 overlay,保留
buildroot Weston
Weston 不是“桌面 UI”,而是 Wayland 的显示与窗口合成基础设施。 在嵌入式里,它是“跑 UI 的地基”,不是“给人用的桌面”。
Weston 本身不是桌面环境,开机后你一般会 自动启动 Qt / LVGL 应用覆盖全屏

桌面图标
root@rk3568-buildroot:/# ls etc/xdg/weston/weston.ini.d/
01-launcher.ini 02-desktop.ini 03-desktop-launcher.ini 04-desktop-launcher-group.ini
编译报错分析
Running 10-os-release.sh for /home/lxg/code/project/linux/rk3568_linux/buildroot/output/rockchip_rk3568/target (buildroot init=busybox)...
Adding information to /etc/os-release...
Adding release_version to get version info
fatal: No names found, cannot describe anything.
ERROR: Running /home/lxg/code/project/linux/rk3568_linux/device/rockchip/common/post-hooks/10-os-release.sh - write_release_version failed!
ERROR: exit code 128 from line 20:
SDK_VERSION=`git describe --tags $(git rev-list --tags --max-count=1)`
ERROR: call stack:
10-os-release.sh: write_release_version(20)
10-os-release.sh: main(58)
ERROR: Running /home/lxg/code/project/linux/rk3568_linux/device/rockchip/common/scripts/build.sh - run_hooks /home/lxg/code/project/linux/rk3568_linux/buildroot/output/rockchip_rk3568/target failed!
ERROR: exit code 128 from line 256:
/home/lxg/code/project/linux/rk3568_linux/device/rockchip/common/post-hooks/10-os-release.sh /home/lxg/code/project/linux/rk3568_linux/buildroot/output/rockchip_rk3568/target
ERROR: call stack:
build.sh: run_hooks(256)
build.sh: run_post_hooks(288)
build.sh: main(615)
build.sh: main(660)
修改方案
diff --git a/device/rockchip/common/scripts/post-os-release.sh b/device/rockchip/common/scripts/post-os-release.sh
index 9d4d50574..27726c223 100755
--- a/device/rockchip/common/scripts/post-os-release.sh
+++ b/device/rockchip/common/scripts/post-os-release.sh
@@ -17,7 +17,8 @@ fixup_os_release()
function write_release_version()
{
GIT_COMMIT=`git log --oneline -1 | awk {'print $1'}`
- SDK_VERSION=`git describe --tags $(git rev-list --tags --max-count=1)`
+ # SDK_VERSION=`git describe --tags $(git rev-list --tags --max-count=1)`
+ SDK_VERSION="RK3568-K5-$(date +%Y%m%d)"
BUILD_TIME=`date +"%Y-%m-%d %H:%M:%S"`
{
固定CH341的串口编号
获取ID_PATH
root@rk3568-buildroot:/# udevadm info -n /dev/ttyUSB3
P: /devices/platform/usbhost/fd000000.dwc3/xhci-hcd.4.auto/usb5/5-1/5-1:1.0/ttyUSB3/tty/ttyUSB3
N: ttyUSB3
S: serial/by-id/usb-1a86_USB_Serial-if00-port0
S: serial/by-path/platform-xhci-hcd.4.auto-usb-0:1:1.0-port0
S: ttyCH341USB0
E: DEVLINKS=/dev/serial/by-id/usb-1a86_USB_Serial-if00-port0 /dev/serial/by-path/platform-xhci-hcd.4.auto-usb-0:1:1.0-port0 /dev/ttyCH341USB0
E: DEVNAME=/dev/ttyUSB3
E: DEVPATH=/devices/platform/usbhost/fd000000.dwc3/xhci-hcd.4.auto/usb5/5-1/5-1:1.0/ttyUSB3/tty/ttyUSB3
E: ID_BUS=usb
E: ID_MODEL=USB_Serial
E: ID_MODEL_ENC=USB\x20Serial
E: ID_MODEL_FROM_DATABASE=HL-340 USB-Serial adapter
E: ID_MODEL_ID=7523
E: ID_PATH=platform-xhci-hcd.4.auto-usb-0:1:1.0
E: ID_PATH_TAG=platform-xhci-hcd_4_auto-usb-0_1_1_0
E: ID_REVISION=0264
E: ID_SERIAL=1a86_USB_Serial
E: ID_TYPE=generic
E: ID_USB_CLASS_FROM_DATABASE=Vendor Specific Class
E: ID_USB_DRIVER=ch341
E: ID_USB_INTERFACES=:ff0102:
E: ID_USB_INTERFACE_NUM=00
E: ID_VENDOR=1a86
E: ID_VENDOR_ENC=1a86
E: ID_VENDOR_FROM_DATABASE=QinHeng Electronics
E: ID_VENDOR_ID=1a86
E: MAJOR=188
E: MINOR=3
E: SUBSYSTEM=tty
E: USEC_INITIALIZED=117928515
编写Udev规则
rk3568_linux/buildroot/board/rockchip/common/base/etc/udev/rules.d/99-serial.rules
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", ENV{ID_PATH}=="platform-xhci-hcd.4.auto-usb-0:1:1.0", SYMLINK+="ttyCH341USB0"
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", ENV{ID_PATH}=="platform-fd8c0000.usb-usb-0:1:1.0", SYMLINK+="ttyCH341USB1"
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", ENV{ID_PATH}=="platform-fd800000.usb-usb-0:1.1:1.0", SYMLINK+="ttyCH341USB2"
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", ENV{ID_PATH}=="platform-fd800000.usb-usb-0:1.2:1.0", SYMLINK+="ttyCH341USB3"
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", ENV{ID_PATH}=="platform-fd800000.usb-usb-0:1.4:1.0", SYMLINK+="ttyCH341USB4"
OTA 升级
Rockchip_Developer_Guide_Linux_Upgrade_CN.pdf
升级方式
- Recovery 模式,设备上有一个单独的分区(recovery)用于升级操作。
- Linux A/B 模式,设备上有两套固件,可切换使用。
Recovery升级
updateEngine --image_url=/userdata/update.img --misc=update --savepath=/userdata/update.img --reboot &
A/B 分区 OTA
┌───────────────┐
│ boot │
├───────────────┤
│ rootfs_A ← 当前运行 │
├───────────────┤
│ rootfs_B ← OTA 写入 │
├───────────────┤
│ userdata │
└───────────────┘
- 当前运行 A
- OTA 包写入 B 分区
- 修改 boot 参数 → 下次启动从 B
- B 启动成功 → 标记成功
- B 启动失败 → 自动回滚到 A
恢复出厂设置
root@rk3568-buildroot:/# update
update: Rockchip Update Tool
update: --wipe_all
command: --wipe_all
update: write command to command file: done
update: write command to misc file: done
update: reboot!
0
次点赞