ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

RK3568移植OpenBMC实战:从Yocto构建到带外管理性能优化

RK3568移植OpenBMC实战:从Yocto构建到带外管理性能优化 1. 为什么要在Rock3A上折腾OpenBMC手里这块Rock3A开发板是瑞芯微RK3568的方案四核A55主频最高2.0GHz带NPU和双千兆网口社区支持也还算活跃。我最初拿到它的目的是做边缘计算网关跑了一段时间Ubuntu之后发现一个挺实际的问题设备部署在无人值守的机房里一旦系统崩溃或者内核panic只能跑现场去重启。这种场景下带外管理能力就成了刚需。OpenBMC正好解决这个痛点。它是一套开源的BMC固件框架核心思路是在主处理器之外维护一个独立的管理通道即使主系统完全挂掉你依然可以通过网络访问BMC查看传感器数据、控制电源、挂载虚拟介质、查看系统日志。传统上OpenBMC跑在ASPEED的AST2500/AST2600这类专用BMC芯片上但这些芯片价格不便宜而且和主SoC是分离的两套系统。Rock3A的RK3568本身性能足够强如果能让它同时承担主业务和BMC管理两个角色硬件成本能省下一大块。这个想法听起来有点“歪门邪道”因为OpenBMC的官方支持列表里根本没有RK3568。但OpenBMC的架构本身是高度可移植的它基于Yocto构建底层是Linux上层是phosphor系列守护进程和D-Bus消息总线。只要能把Yocto的BSP层跑通理论上任何能跑Linux的ARM板子都有机会。我花了大概三周时间从零开始把OpenBMC移植到了Rock3A上中间踩了不少坑也积累了一些性能数据。这篇文章就把整个过程拆开来讲包括方案选型、设备树适配、内核配置、用户空间裁剪、性能对比以及那些文档里不会写的避坑经验。适合谁来读如果你手上有RK3568或者类似ARM开发板想了解BMC固件的移植流程或者你正在做带外管理的方案选型这篇内容应该能帮你省下不少试错时间。即使你之前没接触过OpenBMC只要对嵌入式Linux和Yocto有基本概念跟着思路走也能理解整个链路。2. 移植前的整体方案设计与选型考量2.1 为什么选OpenBMC而不是自己写一套管理程序有人可能会问不就是远程看个传感器、控制个电源吗自己写个Python脚本加个Web界面不就行了我一开始也这么想过但实际评估下来自己造轮子的成本远高于预期。OpenBMC提供的不只是几个API它有一套完整的、经过工业场景验证的框架。phosphor-dbus-interfaces定义了标准化的传感器、电源、日志、固件更新等接口phosphor-hwmon负责传感器采集phosphor-state-manager管理电源状态机bmcweb提供Redfish兼容的REST API。这些组件之间的解耦做得很好你可以按需裁剪但接口规范是统一的。如果自己写光是Redfish协议兼容性这一项就够喝一壶的更别说后续的固件更新、日志持久化、多用户权限管理这些功能。另一个考虑是社区生态。OpenBMC背后有Facebook、IBM、Intel等公司在推代码质量和文档虽然不算完美但至少有人在维护。遇到问题去邮件列表或者Gerrit上搜大概率能找到类似案例。自己写的方案出了问题只能自己扛。2.2 RK3568作为BMC主控的可行性分析RK3568跑OpenBMC最大的疑问是资源够不够。OpenBMC在AST2600上的典型内存占用是512MB左右而Rock3A标配2GB或4GB LPDDR4完全够用。存储方面OpenBMC的rootfs大概200-300MB加上日志和配置分区16GB eMMC绰绰有余。CPU性能更是碾压AST2600四核A55跑D-Bus消息总线毫无压力。真正需要关注的是外设接口。BMC的核心功能包括I2C传感器采集、GPIO电源控制、UART串口重定向、网络管理、PWM风扇控制。RK3568的I2C控制器有6路GPIO数量充足UART也有多路PWM支持8通道。从硬件接口层面看完全能满足BMC的基本需求。唯一需要注意的是RK3568的I2C控制器在Linux下的驱动是i2c-rk3x需要确认它支持从机模式如果要做IPMB的话不过对于本地传感器采集主机模式就够了。2.3 Yocto BSP层的选择用官方还是自己搭OpenBMC的构建系统基于Yocto官方提供了meta-phosphor层和几个参考机器的BSP。对于RK3568没有现成的meta层可用。我有两个选择一是基于Rockchip官方的Yocto BSPmeta-rockchip来改二是从OpenBMC的meta-aspeed或者meta-arm参考层出发自己写一个meta-rock3a。我最终选了第二条路。原因是Rockchip官方的Yocto BSP版本比较老而且和OpenBMC的Yocto版本kirkstone不一定对得上。从meta-arm出发我可以复用ARM通用的内核配置和工具链只需要针对RK3568写一个小的BSP层包含机器配置、内核配方、设备树和u-boot配方。这样层次更清晰后续升级也方便。具体来说我创建了meta-rock3a层目录结构如下meta-rock3a/ ├── conf/ │ ├── machine/ │ │ └── rock3a.conf │ └── layer.conf ├── recipes-bsp/ │ ├── u-boot/ │ │ └── u-boot-rock3a.bb │ └── trusted-firmware-a/ │ └── trusted-firmware-a-rock3a.bb ├── recipes-kernel/ │ └── linux/ │ ├── linux-rock3a_5.15.bb │ └── linux-rock3a/ │ ├── defconfig │ └── rock3a.dts └── recipes-phosphor/ └── ... (OpenBMC相关配方覆盖)机器配置里关键的是指定内核设备树、串口控制台、以及OpenBMC需要的几个特性开关。这部分后面会详细展开。2.4 启动链路的规划从BootROM到BMC用户空间RK3568的启动流程是BootROM - TPL/SPL - U-Boot - Linux Kernel - Init。OpenBMC的用户空间由systemd管理phosphor服务通过D-Bus互相通信。移植的关键是确保每个阶段都能正确加载。我规划的分区方案是分区大小内容uboot4MBU-Boot SPLboot64MBKernel Image DTBrootfs512MBOpenBMC rootfs (squashfs)data剩余空间日志、配置、持久化数据rootfs用squashfs只读挂载data分区用ext4可读写。这样即使rootfs损坏恢复也容易。U-Boot环境变量里设置bootargs指向正确的分区和console。3. 核心细节解析与实操要点3.1 设备树适配让内核认识Rock3A的硬件设备树是移植中最琐碎但也最关键的部分。Rock3A的硬件布局和Rockchip官方的EVB板有差异不能直接套用。我需要根据原理图确认几个关键外设的引脚和总线地址。首先是I2C。Rock3A引出了I2C1、I2C3、I2C5等几路我选了I2C3接一颗LM75温度传感器做测试。在设备树里需要配置i2c3 { status okay; clock-frequency 100000; pinctrl-names default; pinctrl-0 i2c3m0_xfer; lm75: lm7548 { compatible national,lm75; reg 0x48; }; };这里有个坑RK3568的I2C引脚有多种mux选项i2c3m0和i2c3m1对应的物理引脚不同。我一开始没注意用了默认的mux结果传感器读不到数据。后来对着原理图确认了实际用的是m0组引脚改成i2c3m0_xfer才正常。GPIO部分我需要控制一个电源使能引脚。在设备树里定义gpio-power { compatible gpio-leds; power_en { gpios gpio0 RK_PB7 GPIO_ACTIVE_HIGH; default-state off; label power-en; }; };然后在OpenBMC的phosphor-gpio-monitor配置里引用这个GPIO实现电源状态监控。UART方面Rock3A的调试串口是UART2对应ttyS2。在chosen节点里设置chosen { stdout-path serial2:1500000n8; bootargs consolettyS2,1500000n8 earlycon; };注意波特率是1500000不是常见的115200。这个在Rockchip的板子上很常见如果设错了串口会输出乱码。3.2 内核配置裁剪只保留BMC需要的功能OpenBMC的内核不需要桌面环境、声卡、GPU这些但需要确保I2C、GPIO、PWM、hwmon、watchdog、网络这些驱动都编译进去。我基于multi_v7_defconfig和defconfig做了一份精简配置关键选项如下CONFIG_I2Cy CONFIG_I2C_CHARDEVy CONFIG_I2C_RK3Xy CONFIG_GPIO_SYSFSy CONFIG_GPIO_DWAPBy CONFIG_PWMy CONFIG_PWM_ROCKCHIPy CONFIG_SENSORS_LM75y CONFIG_WATCHDOGy CONFIG_DW_WATCHDOGy CONFIG_NETy CONFIG_STMMAC_ETHy CONFIG_PHYLIBy CONFIG_EXT4_FSy CONFIG_SQUASHFSy CONFIG_OVERLAY_FSy裁剪的时候要注意phosphor-hwmon依赖sysfs接口读取传感器所以CONFIG_HWMON和CONFIG_SENSORS_*必须开。另外OpenBMC的日志服务需要CONFIG_TMPFS和CONFIG_TMPFS_POSIX_ACL。内核大小方面裁剪后Image大概8MB左右加上DTB不到9MBboot分区64MB完全够用。启动时间实测从U-Boot到用户空间login提示大约12秒比AST2600的方案快不少。3.3 U-Boot适配从SPL到内核的跳转Rock3A的U-Boot需要支持从eMMC加载内核。我用的U-Boot版本是2022.07Rockchip的SPL框架已经比较成熟。关键配置在rock3a_defconfig里CONFIG_ARMy CONFIG_ARCH_ROCKCHIPy CONFIG_SPLy CONFIG_SPL_ROCKCHIP_BACK_TO_BROMy CONFIG_TARGET_ROCK3Ay CONFIG_DEFAULT_DEVICE_TREErk3568-rock3a CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR0x4000 CONFIG_SPL_PAYLOADu-boot.binCONFIG_SPL_ROCKCHIP_BACK_TO_BROMy这个选项很重要它让SPL加载完U-Boot后回到BootROM由BootROM跳转到U-Boot。如果不设这个SPL会直接跳转在某些DDR配置下可能不稳定。U-Boot的环境变量里设置bootcmdbootcmdmmc dev 0; ext4load mmc 0:2 ${kernel_addr_r} /Image; ext4load mmc 0:2 ${fdt_addr_r} /rk3568-rock3a.dtb; booti ${kernel_addr_r} - ${fdt_addr_r}这里假设boot分区是mmc 0的第2个分区。实际部署时可以用part uuid来定位更稳妥。3.4 OpenBMC用户空间裁剪去掉不需要的配方OpenBMC默认构建出来的镜像包含了很多面向服务器主板的功能比如IPMI、Redfish、WebUI、固件更新等。对于Rock3A这种轻量级场景有些可以裁掉。我在local.conf里通过IMAGE_INSTALL:remove去掉了一些重量级组件IMAGE_INSTALL:remove bmcweb phosphor-ipmi-host phosphor-ipmi-net但保留了phosphor-hwmon、phosphor-state-manager、phosphor-logging、phosphor-dbus-interfaces这些核心服务。裁剪后rootfs从原来的380MB降到了210MB左右启动时间也缩短了约3秒。需要注意的是phosphor-hwmon的配置文件需要根据实际传感器路径来写。在/etc/phosphor-hwmon/下创建conf文件TEMP/sys/class/hwmon/hwmon0/temp1_input然后systemd服务会自动读取并发布到D-Bus上。可以用busctl introspect xyz.openbmc_project.Hwmon /xyz/openbmc_project/sensors/temperature/TEMP来验证。4. 实操过程与核心环节实现4.1 构建环境搭建与Yocto配置构建OpenBMC需要一台Linux主机Ubuntu 20.04或22.04都可以。依赖包安装sudo apt install gawk wget git diffstat unzip texinfo gcc build-essential \ chrpath socat cpio python3 python3-pip python3-pexpect xz-utils debianutils \ iputils-ping python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev \ pylint xterm python3-subunit mesa-common-dev zstd liblz4-tool file locales然后拉取OpenBMC的代码git clone https://github.com/openbmc/openbmc.git cd openbmc git checkout kirkstone把之前写好的meta-rock3a层放到meta-rock3a目录下然后在bblayers.conf里添加BBLAYERS ${TOPDIR}/../meta-rock3a在local.conf里设置机器MACHINE ?? rock3a构建命令source oe-init-build-env bitbake obmc-phosphor-image第一次构建大概需要2-3小时取决于主机性能和网络。建议挂个代理加速下载但注意不要用任何违规工具直接用国内镜像源即可。Yocto的PREMIRRORS和SSTATE_MIRRORS可以配置成本地缓存第二次构建就快很多。4.2 镜像烧录与首次启动构建完成后镜像在tmp/deploy/images/rock3a/下。我用的是obmc-phosphor-image-rock3a.wic可以直接dd到SD卡或者eMMC。烧录到SD卡sudo dd ifobmc-phosphor-image-rock3a.wic of/dev/sdX bs4M statusprogress sync把SD卡插入Rock3A拨码开关设置成SD卡启动。上电后串口应该能看到U-Boot和内核的启动日志。第一次启动时systemd会做一些初始化工作比如生成SSH密钥、初始化D-Bus大概需要30秒左右。启动完成后串口会显示登录提示。默认用户名是root密码是0penBmc注意是数字0。登录后可以用systemctl status查看服务状态。4.3 传感器与电源管理功能验证登录BMC后先验证传感器是否正常busctl tree xyz.openbmc_project.Hwmon如果配置正确应该能看到/xyz/openbmc_project/sensors/temperature/TEMP这个路径。读取数值busctl get-property xyz.openbmc_project.Hwmon \ /xyz/openbmc_project/sensors/temperature/TEMP \ xyz.openbmc_project.Sensor.Value Value返回的应该是一个double类型的温度值。电源控制方面我通过GPIO模拟了一个电源按钮。在/etc/systemd/system/下创建一个服务[Unit] DescriptionPower Button Monitor Afterphosphor-gpio-monitor.service [Service] ExecStart/usr/bin/gpio-monitor -g power-button -t both -e power-button-pressed Restartalways [Install] WantedBymulti-user.target然后在D-Bus上监听power-button-pressed事件触发电源状态切换。这部分需要和phosphor-state-manager配合实际实现时我写了一个小的Python脚本桥接GPIO事件和D-Bus方法调用。4.4 网络配置与远程访问Rock3A有两个千兆网口我配置了eth0作为管理口静态IPip addr add 192.168.1.100/24 dev eth0 ip link set eth0 upOpenBMC默认启用了dropbear SSH服务可以直接远程登录。如果需要Web界面可以单独构建bmcweb但我觉得对于调试阶段SSH加busctl已经够用了。远程访问的稳定性实测下来不错连续运行72小时没有掉线。网络吞吐方面用iperf3测试BMC管理通道的带宽大概在800Mbps左右足够传输日志和固件。5. 性能对比与实测数据5.1 启动时间对比我把Rock3A OpenBMC和一台AST2600参考板的启动时间做了对比阶段Rock3A (RK3568)AST2600参考板U-Boot到内核1.8s2.5s内核到init3.2s4.1sinit到D-Bus就绪4.5s6.8sD-Bus到SSH可用2.5s3.2s总计12.0s16.6sRock3A快的主要原因在于CPU主频高2.0GHz vs 1.2GHz和eMMC读写速度快。不过AST2600的方案在功耗上更有优势典型功耗只有3W左右而Rock3A满载大概5-6W。5.2 内存与CPU占用OpenBMC核心服务在Rock3A上的资源占用服务内存占用CPU占用空闲systemd12MB0.3%dbus-daemon8MB0.1%phosphor-hwmon6MB0.2%phosphor-state-manager5MB0.1%phosphor-logging10MB0.5%dropbear4MB0.1%其他15MB0.5%总计60MB1.8%2GB内存的Rock3A跑这些服务绰绰有余剩余内存可以全部用作tmpfs缓存。CPU占用也很低四核A55基本处于 idle 状态。5.3 传感器采集延迟用LM75传感器测试从温度变化到D-Bus属性更新延迟大概在200-300ms。这个延迟主要来自phosphor-hwmon的轮询周期默认是1秒。如果需要更快的响应可以调整/etc/phosphor-hwmon/下的配置把轮询间隔改成500ms或更短。但要注意轮询太频繁会增加CPU占用。6. 常见问题与排查技巧实录6.1 串口无输出或乱码这是移植初期最常见的问题。排查顺序确认波特率。Rockchip的板子通常是1500000不是115200。如果U-Boot阶段有输出但内核阶段乱码检查bootargs里的console参数。确认引脚mux。UART2的引脚可能被其他功能占用检查设备树里的pinctrl配置。确认电平。Rock3A的调试串口是3.3V TTL如果用了RS232转接板电平不匹配会导致乱码。6.2 I2C传感器读不到数据我遇到过一次传感器地址正确但i2cdetect扫不到。后来发现是上拉电阻的问题。Rock3A的I2C总线内部有弱上拉但LM75模块自带的上拉电阻阻值偏大10K导致上升沿太慢。换成4.7K的上拉电阻后正常。如果不想改硬件可以在设备树里降低I2C时钟频率到50KHz试试。6.3 D-Bus服务启动失败OpenBMC的服务之间依赖关系比较复杂如果某个服务启动失败可能导致连锁反应。排查方法systemctl --failed journalctl -u phosphor-hwmon0.service -n 50常见原因是配置文件路径不对或者D-Bus接口名拼写错误。phosphor-hwmon的配置文件必须放在/etc/phosphor-hwmon/下文件名对应D-Bus对象路径。比如/etc/phosphor-hwmon/temp0.conf对应/xyz/openbmc_project/sensors/temperature/temp0。6.4 镜像烧录后无法启动如果dd烧录后板子没反应先检查拨码开关是否在正确的启动模式。Rock3A的启动模式由拨码开关决定SD卡启动和eMMC启动的拨码位置不同。另外wic镜像的分区表是GPT有些老的烧录工具可能不识别建议直接用dd。6.5 常见问题速查表现象可能原因解决方法串口无输出波特率错误改为1500000串口乱码引脚mux冲突检查pinctrl配置I2C扫描不到设备上拉电阻过大换4.7K上拉D-Bus服务失败配置文件路径错误检查/etc/phosphor-hwmon/镜像无法启动拨码开关错误确认启动模式网络不通PHY驱动未加载检查CONFIG_STMMAC_ETH启动卡在U-Boot环境变量错误检查bootcmd和分区号7. 实操心得与后续扩展思路移植过程中最大的体会是OpenBMC的框架设计确实考虑了很多工业场景的需求但它的默认配置是面向服务器主板的直接搬到开发板上会有很多冗余。裁剪的时候要大胆但核心的D-Bus接口和phosphor服务不能动否则后续扩展会很麻烦。另一个心得是设备树的调试要耐心。RK3568的引脚mux选项很多同一个功能可能有多个引脚组可选一定要对着原理图确认。我在这上面浪费了两天时间最后发现是I2C的mux选错了。后续如果想继续扩展有几个方向可以考虑一是把bmcweb加回来提供Redfish接口方便和上层管理平台对接二是实现固件更新功能通过phosphor-software-manager支持A/B分区升级三是把NPU利用起来做一些本地的异常检测比如根据温度趋势预测风扇故障。这些都需要在现有基础上继续裁剪和适配但核心的移植流程已经跑通了。最后分享一个小技巧构建OpenBMC的时候把SSTATE_DIR和DL_DIR配置到本地大容量硬盘上第二次构建能省很多时间。另外bitbake -c cleansstate和bitbake -c cleanall要慎用除非你确定要重新编译整个组件否则增量构建就够了。
返回列表