前阵子维护一批 RK3588 边缘盒子,标签全被磨没了,只能 SSH 上去认板。同事张嘴就是一句:cat /proc/cpuinfo一看不就有了?结果输出贴出来,一屋子人都沉默了。Model name 写着ARMv8 Processor rev 0 (v8l),CPU part 一栏既有0xd05又有0xd0b。熟悉 Arm 架构的人看到这两个值,能推出这是大小核组合,但离“RK3588”三个字还差着十万八千里。这篇文章就是记录我把“靠猜 CPU 型号”彻底改成“设备画像”的完整过程,包含可以直接抄的识别命令、采集脚本,以及刷机、跑 YOLOv8、接外设这些真实场景里的用法。
先说结论:在 ARM64 平台上,/proc/cpuinfo本来就不承诺告诉你 SoC 型号。它给的是 CPU 核心微架构信息,而 SoC 型号藏在设备树、内核驱动和 sysfs 节点里。把后两者系统化地读出来,再和 CPU part 交叉验证,才算真正完成一次“设备画像”。
1. 为什么 lscpu 和 /proc/cpuinfo 在 RK3588 上会“失灵”
1.1 你猜不到型号,因为 ARM 的 cpuinfo 根本不包含 SoC 字段
x86 上用lscpu很容易看到Model name: Intel(R) Core(TM) i7-12700,所以在 ARM 板子上大家也习惯性认为cat /proc/cpuinfo就能看到“RK3588”这种字符串。但 ARM64 的 cpuinfo 是由内核里arch/arm64/kernel/cpuinfo.c根据每个核的 MIDR 寄存器生成的。MIDR 只记录 implementer、variant、architecture、part number 这些微架构 ID,不记录芯片厂商和 SoC 型号。
RK3588 的 8 个核里,4 个是 Cortex-A76,4 个是 Cortex-A55。在多数板子上你会看到:
$ cat /proc/cpuinfo | grep -E "processor|CPU part|CPU implementer" processor : 0 CPU implementer : 0x41 CPU part : 0xd0b processor : 1 CPU implementer : 0x41 CPU part : 0xd0b ... processor : 4 CPU implementer : 0x41 CPU part : 0xd050xd05是 Cortex-A55 的 part number,0xd0b是 Cortex-A76 的 part number。0x41表示 ARM。这套信息只能说明“这是 ARM 的大小核”,无法区分 RK3588、RK3576、RK3568 这些同为大小核或同核的芯片。比如 RK3568 是 4 个 A55,也会出现0xd05;如果你只靠 part 判断,很容易把 RK3568 和 RK3588 的小核混为一谈。
1.2 Model name 是“通用壳”,不是给你认芯片用的
ARM64 内核里,如果当前 MIDR 没有对应的 core 描述,/proc/cpuinfo的 model name 就统一显示成类似ARMv8 Processor rev 0 (v8l)的字样。这个字符串是固定的模板,跟具体芯片没有一对一的映射关系。换句话说,你在 RK3588、RK3399、甚至一些服务器 ARM 芯片上都能看到几乎一模一样的输出。
这也是为什么很多自动化脚本想用lscpu的 model name 判断板卡型号,在 ARM 平台会翻车。判断 RK3588 不能用“猜”,得换数据源。
1.3 用户态工具和内核导出的边界
/proc/cpuinfo是内核生成的虚拟文件,普通用户态程序改不了它。市面上有些“改 CPU 型号”的玩法,改的是 Android 的 build.prop、系统属性、或者某个上层 App 读取的字符串,并不是改/proc/cpuinfo。所以做设备识别时,与其依赖某个软件自己声称的型号,不如多读几个由内核直接导出的硬件节点,交叉验证之后才可信。
2. 真正能确认 RK3588 的三条路:设备树 compatible、soc_id 与内核日志
2.1 /proc/device-tree 是内核给你开的“硬件台账”
设备树(DTB)在启动时被内核解析,之后会以目录结构挂在/proc/device-tree下。你可以直接读它来获取 SoC 和板卡信息。最关键的是根节点上的compatible属性,它表示这块板子和芯片的兼容标识。
直接cat这个文件会看到一串被 null 字符分隔的字符串,在终端里显示很乱。正确读法是:
$ tr '\0' '\n' < /proc/device-tree/compatible rockchip,rk3588 rockchip,rk3588-evb1-v10对 RK3588 官方 SDK 镜像来说,rockchip,rk3588几乎一定会出现。如果是第三方板卡,通常前面还会带板厂自定的名字,比如myvendor,rk3588-ev-board,但中间一般也包含rk3588字段。
同样值得看的是/proc/device-tree/model,它描述整板型号,例如:
$ cat /proc/device-tree/model Rockchip RK3588 EVB1 V10 Board如果你的板卡是 RK3588 的某个定制规格,这里可能出现板厂的产品名。这个字段在刷固件选镜像时很有用,能快速确认手上板子的官方型号,而不是靠外壳贴纸猜。
2.2 soc0/soc_id 节点:内核驱动的“自我介绍”
在不少 ARM 内核里,SoC 驱动会注册成/sys/devices/soc0,下面有几个字段可以直接读:
$ cat /sys/devices/soc0/soc_id 3588 $ cat /sys/devices/soc0/machine RK3588具体值依内核版本略有差异,可能是3588、RK3588、rk3588,但基本都能对上。有些主线内核路径会不太一样,脚本里最好兼容/sys/class/soc/soc0和/sys/devices/soc0两个位置。
2.3 dmesg 里的 Rockchip 启动痕迹
内核启动日志里通常有一堆 Rockchip 相关输出。执行:
$ dmesg | grep -iE "rockchip|rk3588|rknpu" | head -n 20能看到类似rockchip-gpio,rk3588-...,rknpu等驱动注册信息。这是辅助证据,不是决定证据;但配合 compatible 和 soc_id 一起看,基本就盖棺定论了。
到这里,识别 RK3588 的路径已经清晰:读设备树 compatible、读 soc0/soc_id、看 dmesg 驱动日志,再拿 CPU part 作为辅助验证。下一步,就是把这一套整理成一份可以长期复用的设备画像。
3. 把它做成设备画像脚本:一次采集,长期受用
3.1 画像到底画什么:CPU、内存、NPU、GPU、外设、分区
“识别型号”只是第一步。真正干活时你需要知道的不光是“这是 RK3588”,还包括:内存多大、eMMC 多大、有没有 NPU 节点、编解码器是否正常、SPI/I2C/摄像头节点注册了没有、内核版本是什么、分区是不是 A/B 结构。把这些信息一次性采集出来存成文本,就是我说的“设备画像”。
一份可用的画像至少覆盖:
- SoC/板级:compatible、model、soc_id、machine
- CPU:架构、核数、主频范围、CPU part
- 内存与存储:MemTotal、eMMC/SD 容量、分区布局
- 算力相关:NPU 节点、GPU 节点、MPP 编解码节点
- 外设:spidev、i2c、串口、PCIe、网卡
- 系统:内核版本、发行版、启动日志关键行
有了这份清单,刷机和跑模型前就不用来回查命令了。
3.2 device_profile.sh 完整脚本与运行效果
下面这个脚本我一直在用。把它放到板子上,比如/usr/local/bin/device_profile.sh,每次开新板先跑一遍,输出重定向存起来。
#!/usr/bin/env bash echo "================ SOC / BOARD ================" echo "compatible: $(tr '\0' ' ' < /proc/device-tree/compatible 2>/dev/null)" echo "model: $(cat /proc/device-tree/model 2>/dev/null)" for d in /sys/devices/soc0 /sys/class/soc/soc0; do [ -d "$d" ] || continue echo "soc0 path: $d" echo " soc_id = $(cat $d/soc_id 2>/dev/null)" echo " machine = $(cat $d/machine 2>/dev/null)" echo " family = $(cat $d/family 2>/dev/null)" break done dmesg 2>/dev/null | grep -iE "rockchip|rk3588|rknpu" | head -n 15 echo "================ CPU ================" lscpu 2>/dev/null | grep -E "Architecture|Byte Order|CPU\(s\)|Model name|CPU max MHz|CPU min MHz" echo "--- cpuinfo part list ---" grep -E "processor|CPU part|CPU implementer" /proc/cpuinfo | sort | uniq -c echo "================ MEMORY / STORAGE ================" free -h | head -n 2 grep -E "MemTotal|MemAvailable" /proc/meminfo echo "--- block devices ---" lsblk -d -o NAME,SIZE,MODEL,TRAN 2>/dev/null echo "--- partitions ---" cat /proc/partitions | head -n 30 echo "================ NPU / GPU / CODEC ================" ls -l /dev/rknpu /dev/mali* /dev/mpp_service 2>/dev/null ls /sys/kernel/debug/rknpu 2>/dev/null && cat /sys/kernel/debug/rknpu/version 2>/dev/null find /dev -maxdepth 1 -name "video*" 2>/dev/null | head -n 20 which v4l2-ctl >/dev/null 2>&1 && v4l2-ctl --list-devices 2>/dev/null echo "================ PERIPHERALS ================" for i in /dev/spidev* /dev/i2c-* /dev/ttyS* /dev/ttyUSB* /dev/ttyACM*; do [ -e "$i" ] && echo "$i" done echo "--- pci devices ---" ls /sys/bus/pci/devices 2>/dev/null | head -n 10 echo "--- network interfaces ---" ls /sys/class/net 2>/dev/null echo "================ OS / KERNEL ================" uname -a grep -E "PRETTY_NAME|VERSION_ID" /etc/os-release 2>/dev/null在 RK3588 官方 EVB 板上跑出来的效果类似:
================ SOC / BOARD ================ compatible: rockchip,rk3588 rockchip,rk3588-evb1-v10 model: Rockchip RK3588 EVB1 V10 Board soc0 path: /sys/devices/soc0 soc_id = 3588 machine = RK3588 ... ================ CPU ================ CPU(s): 8 Model name: ARMv8 Processor rev 0 (v8l) CPU max MHz: 2280.0000 CPU min MHz: 408.0000 --- cpuinfo part list --- 4 CPU implementer : 0x41 4 CPU part : 0xd0b 4 CPU part : 0xd05 ...看到 4 个0xd0b加 4 个0xd05,同时 compatible 里带rockchip,rk3588,这个板子基本可以确认是 RK3588 大小核满血 8 核。
3.3 把画像接入工作流:开箱建档、刷机前比对、故障复盘
我现在的习惯是三步走。第一,新板子到手先跑一份画像:
$ sudo bash device_profile.sh | tee /var/log/device_profile_$(date +%Y%m%d_%H%M%S).txt第二,刷机前把当前画像和固件要求的板型做比对,确认 compatible 和 model 匹配,再动手。第三,板子出问题时,翻出刷机当天留存的画像,和故障现场输出做 diff,能很快定位是固件、驱动还是外设问题。比如有次客户报“MIPI 摄像头不出图”,我对比画像发现出图正常的板子/dev/video0存在,故障板却只有/dev/video1,进一步查 dmesg 才发现 sensor 的 reset 引脚配置被板厂改过。这种问题如果没有历史画像,排查时间会翻倍。
脚本里可以加一行:
$ diff /var/log/device_profile_old.txt /var/log/device_profile_new.txt字段差异一眼就能看穿。
4. 画像数据在真实项目里能怎么用
4.1 刷系统前先画像,避免把 MACHINE 镜像刷到另一块板上
RK3588 的 SDK 动辄提供十几个 defconfig:EVB1、EVB2、平板、盒子、带 MIPI 屏和不带屏的版本。外壳标签一旦磨损,光看板子外形很容易选错。这时候model和compatible就是唯一可靠依据。
有一次我们给客户代烧系统,对方只报了一句“RK3588 的板子”。我让现场先跑画像,结果输出是model: MY-BOX-RK3588-64G,compatible: myvendor,rk3588,而官方 SDK 默认 EVB1 镜像的 compatible 是rockchip,rk3588-evb1-v10。两者都能启动,但 EVB1 镜像没有适配客户板子的 USB 转串口和 LED GPIO,外设全乱了。最后联系板厂拿到对应 defconfig 重新编译才解决。画像能让你在烧写前就预判这些风险,而不是烧完才发现点不亮外设。
4.2 用画像判断 RK3588 部署 YOLOv8 的算力路径
很多人拿到 RK3588 就急着部署 YOLOv8,第一反应是“6 TOPS NPU 应该随便跑”。实际上能不能跑、跑多快,取决于 NPU 驱动、内存带宽、量化模型和板子本身的外设负载。先跑一遍画像,能确认几件事:
/dev/rknpu存在,说明 BSP 内核里 NPU 驱动已加载,可以走 RKNN 硬件推理路径;MemTotal是 8G 还是 16G,决定能不能同时跑推理、解码和业务服务;- dmesg 里有没有
rknpu版本信息,方便和 RKNN Toolkit 要求的驱动版本对照; - 有没有
/dev/mpp_service,决定视频流的前处理能不能走硬件解码,而不用 CPU 软解。
实际部署时,我会先用画像确认 NPU 正常,再跑一遍 RKNN 的 benchmark 脚本。以 YOLOv8s INT8、640x640 为例,在 RK3588 上通常能达到几十 FPS 的水平,但具体数值受分辨率、后处理线程、是否用 RGA 做预处理影响很大。没有画像,你连“是驱动问题还是模型问题”都分不清。
4.3 接 SPI、MIPI 摄像头、做 FFmpeg 推流前先看设备节点
项目里要接 SPI 外设,先看画像里有没有/dev/spidev*;要接 MIPI 摄像头,先看/dev/video*和 v4l2-ctl 列出的拓扑;要做 FFmpeg 推流,先确认/dev/mpp_service在不在——这是 Rockchip MPP 编解码的服务节点,没有它,h264_rkmpp这类硬件编码器就是空谈。
判断能否硬编推流的命令组合很简单:
$ ls /dev/mpp_service /dev/mpp_service $ ffmpeg -encoders 2>/dev/null | grep rkmpp V..... h264_rkmpp H.264 (Rockchip Media Process Platform) V..... hevc_rkmpp HEVC (Rockchip Media Process Platform)设备节点存在、FFmpeg 带 rkmpp 编码器,再谈推流参数才有意义。否则你花半天调参,最后发现编码器根本没编译进去。这些都是设备画像能提前回答的问题。
5. 那些识别失败的案例:为什么有人会“看走眼”
5.1 设备树被板厂魔改后的陷阱
第三方 RK3588 板卡基本都会修改设备树。有的板厂把 compatible 写成了myboard,rk3588-custom,有的为了兼容多个型号,compatible里的字符串顺序还会变。如果你脚本里写死“第一行必须是rockchip,rk3588”,就会翻车。
正确做法是全文匹配rk3588关键字:
$ if tr '\0' '\n' < /proc/device-tree/compatible | grep -q "rk3588"; then echo "SoC matches RK3588" fi同理,model字段也可能和芯片型号无关,它更接近“产品名”。识别芯片以 compatible 为主,model 只用于确认板型。
5.2 内核版本不同导致节点路径对不上
RK3588 既有 Rockchip BSP 内核(5.10、6.1),也有主线内核。两者对 sysfs 的导出方式不完全一致。BSP 里常见的/sys/devices/soc0/soc_id、/dev/rknpu、/dev/mpp_service,在主线内核上不一定存在。反过来,主线内核可能在/sys/firmware/devicetree下有更完整的设备树信息。
所以判断 RK3588 时,不能只看“有没有 rknpu 节点”这种单一信号。设备树 compatible 是更稳定的依据,因为它无论 BSP 还是主线内核都会保留。遇到节点缺失,先怀疑内核版本,而不是怀疑硬件。
5.3 软件层“改 CPU 型号”能骗到什么级别
回到开头说的“改 CPU 型号”。Android 设备上确实存在通过改 build.prop、系统属性等手段让“关于本机”显示成别的型号的做法,但这属于上层软件伪装。Linux 下/proc/cpuinfo是内核根据 MIDR 现场生成的,普通用户态没有权限改。设备树 compatible 更是启动时由内核解析 DTB 得到的,想伪装它得先伪造整个固件。
因此,做设备管理平台时要记住:uname -a和某个 App 里显示的“型号”都不能作为硬件识别的唯一依据。真正可信的是由内核直接导出的设备树和 sysfs 节点。多个数据源交叉验证后再入库,后面做资产管理才不会把 RK3588 误判成别的芯片。
5.4 一张自检清单帮你盖棺定论
我把自己的判断逻辑整理成了一张表,新手可以直接照着逐项打勾:
| 检查项 | 期望值 | 可信度 |
|---|---|---|
/proc/cpuinfo的 CPU part | 同时出现0xd05和0xd0b | 强线索,但非充分 |
/proc/device-tree/compatible | 包含rk3588 | 核心依据 |
/proc/device-tree/model | 含 RK3588 或板厂型号 | 辅助依据 |
/sys/devices/soc0/soc_id | 为3588/RK3588 | 核心依据(BSP 可用) |
dmesg中 Rockchip/rknpu 相关行 | 存在 | 辅助依据 |
表格里所以标“核心依据”的项,至少有两条同时命中的时候,我才会在资产台账里写“已确认 RK3588”。如果只有 CPU part 命中,我会先标记“疑似 RK3588”,等拿到板厂 DTS 或烧一份官方镜像验证后再转正。
我在实际使用中还有一个习惯,就是每块板子开箱跑画像后,生成的文本直接提交到内部运维平台的资产记录里。后续如果这板子要部署新业务,先翻出画像做一轮“容量评估”,再决定要不要加内存、换镜像或者调整外设。RK3588 这类平台生命周期很长,型号识别这个动作看似基础,但一旦把细节做扎实,后面刷机、调优、排查问题都能省下大把时间。