openbmc-learning-plan

OpenBMC 开发学习计划

从零开始,学到能独立改一个子系统,并在 QEMU 里验证。电源服务只是第 4 阶段中的一节,不是全部。

当前环境:

  • 系统:Windows 上的 Ubuntu 24.04 WSL2
  • 已有:qemu-system-arm、Romulus 固件、openbmc 仓库,目录在 ~/openbmc-dev
  • 登录:ssh -p 2222 root@127.0.0.1,密码 0penBmc(开头是数字 0)
  • Web:https://127.0.0.1:2443。当前这份 Romulus 镜像为了塞进 32MB 闪存,已经去掉网页界面
  • 编译:完整 bitbake 放到第 6 阶段。这台机器大约 8GB 内存、C 盘剩余约 87GB,低于文档建议的 16GB 内存和 200GB 磁盘

每个阶段做完再进入下一个。完成标准是唯一的出口。

1. 概念

先建立词汇,不写代码。

BMC 是主板上的管理控制器。主机操作系统关机时,它仍然在运行。它管理机箱电源、传感器、风扇、网络、用户、日志和固件更新。

外面进来的管理协议主要是 Redfish(HTTPS)和 IPMI。BMC 内部各服务通过 D-Bus 通信,由 systemd 拉起。openbmc 仓库是 Yocto 构建工程。phosphor-state-manager 这种仓库才是某一个服务的源码。

阅读:

完成标准:能讲清主机、机箱、BMC 三者的差别,以及一条 Redfish 请求为什么不会直接进入某个 .cpp。

2. 把正在运行的系统摸熟

QEMU 保持运行。这一阶段只操作已经启动的 Romulus,不编译。

要看的东西 命令
登录 ssh -p 2222 root@127.0.0.1
服务是否在跑 systemctl status bmcweb
主机电源 busctl introspect xyz.openbmc_project.State.Host /xyz/openbmc_project/state/host0
机箱电源 busctl introspect xyz.openbmc_project.State.Chassis /xyz/openbmc_project/state/chassis0
对象分布 busctl tree xyz.openbmc_project.ObjectMapper
传感器 在 /xyz/openbmc_project/sensors 下找对象
网络 busctl tree xyz.openbmc_project.Network
外面的同一份数据 curl -k -u root:0penBmc https://127.0.0.1:2443/redfish/v1/Systems
日志 journalctl -u bmcweb -n 30 --no-pager

完成标准:同一条信息能在 Redfish、D-Bus、systemd 三处对上。主机电源在 Redfish 里看到的状态,就是 host0 上的属性,由 phosphor-host-state-manager 提供。

3. 仓库和构建工程怎么对应

openbmc 里没有这些服务的 C++ 源码。每个服务有一个配方,SRC_URI 指向组件仓库,SRCREV 锁住提交。

电源服务的配方:

meta-phosphor/recipes-phosphor/state/phosphor-state-manager_git.bb

其中:

SRC_URI = "git://github.com/openbmc/phosphor-state-manager;branch=master;protocol=https"
SRCREV = "f10b56eeee87c06d1bf3a0f2703d3fe14d155764"

旁边单独克隆的 phosphor-state-manager 不会被这次构建自动用到。Romulus 的机器差异在 meta-ibm/meta-romulus/,用 .bbappend 追加选项,不改原始 .cpp。镜像装哪些功能,看:

meta-phosphor/recipes-phosphor/images/obmc-phosphor-image.bb

阅读:

完成标准:随便点一个 IMAGE_FEATURES 里的名字,能找到它对应的 packagegroup、配方和 GitHub 仓库。

4. 按子系统把源码走一遍

顺序不要换。每个子系统都做三件事:在 QEMU 里用 busctl 看到对象,在 phosphor-dbus-interfaces 里找到对应的 YAML,在服务仓库里找到处理这个属性的函数。

4.1 D-Bus 骨架

接口定义在 phosphor-dbus-interfaces。对象发现在 phosphor-objmgr。

阅读:https://github.com/openbmc/docs/blob/master/architecture/object-mapper.md

完成标准:给定一个对象路径,能用 ObjectMapper 查出是哪个服务实现的。

4.2 状态和电源

仓库:https://github.com/openbmc/phosphor-state-manager

  • 主机:host_state_manager.cpp 的 requestedHostTransition()
  • 机箱:chassis_state_manager.cpp 里的 systemd 目标表
  • 接口:phosphor-dbus-interfaces 中的 Host.interface.yaml、Chassis.interface.yaml

D-Bus 对象:

  • /xyz/openbmc_project/state/host0,属性 RequestedHostTransition,取值 On、Off、Reboot
  • /xyz/openbmc_project/state/chassis0,属性 RequestedPowerTransition

On 会拉起 obmc-chassis-poweron@0.target,关机走 obmc-chassis-hard-poweroff@0.target。主机开机目标 obmc-host-startmin@0.target 依赖机箱上电。

完成标准:能说出把 RequestedHostTransition 设成 On 之后,代码进入哪个函数,接着拉起哪个 systemd 目标。

4.3 库存和硬件配置

仓库:entity-manager。它读 JSON 配置,在 D-Bus 上发布 CPU、内存、风扇、电源的库存对象。

完成标准:能在 QEMU 里找到一个库存对象,并指出它来自哪份配置。

4.4 传感器

仓库:dbus-sensors。温度、电压、风扇转速从 hwmon 或 I2C 读进来,变成 /xyz/openbmc_project/sensors/...。

完成标准:能指出一个传感器的 Value 是哪个进程写上去的。

4.5 网络、用户、日志

仓库分别是 phosphor-network、phosphor-user-manager、phosphor-logging。

完成标准:能做一项不影响启动的调查,例如用 D-Bus 读出 BMC 主机名,或列出一条日志。

4.6 对外接口

Redfish 在 bmcweb。IPMI 在 phosphor-ipmi-host。两者都把外部请求转成前面的 D-Bus 调用。

完成标准:从 curl 看到的 Systems 电源字段追到 requestedHostTransition()。

4.7 更新、串口、LED、时间

仓库:

  • 固件更新:phosphor-software-manager
  • 串口:obmc-console
  • LED:phosphor-led-manager
  • 时间:phosphor-time-manager

这一节知道各自负责什么即可,先不改代码。

4.8 Web UI

仓库:webui-vue。页面通过 Redfish 访问 BMC。当前 Romulus 镜像没有装它,这一节只克隆源码,看登录页调用了哪个 Redfish 路径。

5. 启动链和机器层

固件不是一个进程。上电后是 U-Boot,然后 Linux 内核,然后 systemd。开关机目标 obmc-chassis-*、obmc-host-* 由 phosphor-state-manager 的配方安装。

Romulus 的板级文件在 openbmc/meta-ibm/meta-romulus/。真正操作 GPIO 的代码不在状态管理器里。x86 机器多在 x86-power-control。Romulus 是 OpenPOWER 的 QEMU 机型,没有真实电源芯片。

阅读:https://github.com/openbmc/docs/blob/master/development/add-new-system.md

只读,先不要新建机器。

完成标准:能画出「Redfish 请求,到 D-Bus 属性,到 systemd 目标,到平台服务」这条链,并指出 Romulus 的平台文件在哪个目录。

6. 编译并改一个服务

内存和磁盘接近 16GB、200GB 之后再做。阅读:

https://github.com/openbmc/docs/blob/master/development/hello-world.md

cd ~/openbmc-dev/openbmc
. setup romulus
devtool modify phosphor-state-manager

第一处改动只在 requestedHostTransition() 里加一条日志。编完后用已经下载的 qemu-system-arm 启动新镜像,用 journalctl 确认这句日志出现。不要一开始就改开关机条件。

devtool modify 会让 BitBake 使用本地的 phosphor-state-manager,而不是配方里锁死的 SRCREV。

启动命令:

cd ~/openbmc-dev
./qemu-system-arm -m 256 -M romulus-bmc -nographic \
  -drive file=./obmc-phosphor-image-romulus.static.mtd,format=raw,if=mtd \
  -net nic \
  -net user,hostfwd=:127.0.0.1:2222-:22,hostfwd=:127.0.0.1:2443-:443,hostfwd=udp:127.0.0.1:2623-:623,hostname=qemu

退出 QEMU:按 Ctrl+A,松开后再按 x。

完成标准:QEMU 里能看到自己加的那条日志。

7. 再扩到第二个子系统

用第 6 阶段的同一套方法改一个只读功能。例如在 bmcweb 里给某个 Redfish 字段加日志,或沿着 dbus-sensors 看一个传感器的上报路径。

完成标准:能独立选定仓库、找到配方、在 QEMU 里验证,不再对照电源那一节。

8. 提交修改

阅读:https://github.com/openbmc/docs/blob/master/development/README.md 里的 Gerrit 一节。

提交说明写行为变化,以及在哪台 QEMU 机器上验证过。学完怎样回复评审即可。

完成标准:能把第 6 阶段的日志改动整理成一次符合项目习惯的提交。在这之前不必注册 Gerrit。

posted @ 2026-10-22 17:45  一枚码农  阅读(7)  评论(0)    收藏  举报