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 这种仓库才是某一个服务的源码。
阅读:
- https://github.com/openbmc/docs/blob/master/architecture/interface-overview.md
- https://github.com/openbmc/docs/blob/master/architecture/optionality.md
完成标准:能讲清主机、机箱、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。

浙公网安备 33010602011771号