先交代一句,这篇文章面向两类人:一类是刚接触OpenBMC、想找一个不花钱也不怕把板子搞坏的方式练手的人;另一类是做BMC固件移植、CI验证、甚至Driver开发的老手,需要在本地起一个虚拟的AST2600环境跑跑看。不管你是哪一类,用QEMU模拟AST2600-EVB跑OpenBMC,都是一条非常务实的路子,比反复拔插串口线、等真机物流、担心刷错image变砖要高效得多。这篇文章就从零开始,把OpenBMC环境搭建的完整流程、启动参数、常见坑全部梳理一遍。
1. 先搞明白:为什么是AST2600-EVB,为什么用QEMU
1.1 这块板子和OpenBMC分别是什么
AST2600是ASPEED面向服务器BMC场景做的一颗SoC,双核ARM Cortex-A7,集成DDR4控制器、VGA显示、双千兆网口、大量IPMI/KCS/PWM等外设。服务器主板上那颗“带外管理芯片”十有八九就是它或它的同门兄弟。EVB就是ASPEED官方的评估板,型号里带EVB三个字母,意思是厂家用来验证芯片功能、跑参考固件的基准硬件。对做服务器BMC的工程师来说,AST2600-EVB几乎是绕不开的参考平台。
OpenBMC则是Linux基金会下面的开源BMC固件项目,不是传统意义的“BIOS”,而是一个跑在BMC上的完整Linux发行版加管理栈。它用Yocto/OpenEmbedded来构建,核心组件包括u-boot、Linux内核、systemd、busybox、以及一堆自我命名的“phosphor-”服务,比如phosphor-host-ipmid负责IPMI、phosphor-webui提供Web管理界面、phosphor-settings管理配置项。说直白点,OpenBMC就是一套面向服务器管理场景定制的精简Linux。
把AST2600-EVB和OpenBMC放在一起,意义在于:ASPEED官方有基于AST2600的参考硬件,OpenBMC社区有对AST2600的软件支持,两者一组合就是一个标准的BMC固件开发平台。你在这个平台上开发的功能,后续很容易移植到自家服务器的BMC模块上——因为硬件底子和固件框架都是同一个体系的。
1.2 模拟器带来的实际价值
用QEMU跑AST2600-EVB,最大的价值在于把“硬件依赖”降到零。真机验证BMC固件,你得准备串口线、电源、网线、TFTP服务器,还要担心刷机失败把板子刷成砖;而在QEMU里,一切都被抽象成了软件模型:串口终端直接映射到当前终端窗口,网络通过QEMU的user模式转发到宿主机,Flash镜像就是一个普通文件,刷坏了重新拷贝一份就好。
另一个很大的价值是自动化。CI/CD流程里如果要跑OpenBMC的集成测试,不可能每台机器都插一块AST2600-EVB,更不可能人工盯着串口输出。用QEMU可以做到一键启动虚拟机、注入IPMI命令、检查Redfish接口返回、然后自动销毁环境。很多OpenBMC社区的单元测试和集成测试,就是基于QEMU完成的。对于只是想在本地快速体验一下OpenBMC开发流程的人来说,QEMU也比真机门槛低得多。
还有一点容易被忽略:QEMU对AST2600的模拟已经相当真实,覆盖了CPU、中断控制器、定时器、串口、网卡、flash控制器等主要外设。这意味着在真机上可能出现的一些底层问题和驱动问题,在QEMU环境下同样能暴露出来。当然它终究不是真实硅片,像PWM精确时序、ADC采样这类和模拟电路强相关的功能,QEMU给不了真实反馈,适合在上面做逻辑验证而不是硬件级调试。
2. 环境准备:构建OpenBMC和安装QEMU
2.1 构建OpenBMC对主机的硬性要求
先泼一盆冷水:OpenBMC不是那种“下载个压缩包解压就能跑”的固件,它是通过Yocto/OpenEmbedded完整构建出来的。构建过程会下载大量源码包、交叉编译工具链,然后逐一编译所有组件,最终打包成可烧写的Flash镜像。整个过程对主机的CPU、内存、磁盘要求都不低。
我个人建议的最低配置是这样的:
- 操作系统:Ubuntu 20.04或更新版本,Debian 11/12也行。CentOS/RHEL系列要额外处理一些包名差异,不建议新手用。
- CPU:4核以上。构建OpenBMC时很多recipe是并行编译的,核越多越快,但也要注意bitbake默认的
BB_NUMBER_THREADS取值经常比核数高,容易把机器拖死。 - 内存:至少8GB,16GB以上体验好很多。内存不足时编译阶段会频繁报错,甚至直接OOM。
- 磁盘:至少64GB剩余空间,建议SSD。OpenBMC一次全量构建的临时文件、缓存、镜像加起来很容易吃掉20GB以上。
- 网络:需要能稳定访问GitHub和各类源码镜像。网络条件差的话,光下载源码就够你喝一壶的。
如果你手头只有一台配置一般的机器,也不是不能用,但要做好心理准备:首次全量构建可能要跑三四个小时甚至更久。后面我会讲怎么判断构建是否正常,以及哪些阶段耗时最长。
2.2 安装基础依赖包
构建OpenBMC需要一堆系统级依赖。在Ubuntu/Debian上执行:
sudo apt update sudo apt install -y \ git python3 python3-dev python3-setuptools \ python3-distutils python3-pexpect gcc g++ gawk make \ file wget bzip2 gzip unzip chrpath diffstat texi2html \ texinfo lrzsz patch xz-utils cpio bc perl \ openssl libssl-dev socat这里面有几个包值得单独说。chrpath和diffstat是Yocto构建系统中的常见依赖,缺少它们会在很后面的构建阶段才报错,排查起来很痛苦。python3-distutils在Python 3.12里已经被移除了,如果你用的是较新版本的Ubuntu,可能需要用python3-setuptools代替,或者单独安装python3-distutils-extra。socat虽然和构建无关,但后面运行OpenBMC时会用来转发串口或网络端口,提前装好省得临时找。
如果你用的是Fedora/RHEL系列,包名会不一样,需要把libssl-dev换成openssl-devel、chrpath换成chrpath(这个倒是一致),python3-distutils则要装python3-devel。总的来说,Ubuntu是社区文档里最常用的构建主机环境,建议保持一致。
2.3 安装QEMU:不要用太老的版本
AST2600的QEMU machine是近几年才合入上游的,所以版本不能太老。Ubuntu 20.04自带的QEMU 4.2版本完全不支持AST2600,必须升级。最简单的办法是直接安装新版系统的QEMU包:
sudo apt install -y qemu-system-arm qemu-system-arm --version如果输出的版本号是5.0以上,基本就够用了。我实测比较稳的是QEMU 7.x和8.x,对AST2600-EVB的支持已经比较成熟。如果你用的发行版自带的QEMU还是太老,可以考虑从源码编译QEMU,但没必要为了这个专门折腾,除非你要调试QEMU本身的模拟逻辑。
还有一个容易被忽视的点:OpenBMC社区其实维护了一个QEMU分支,地址在github.com/zybu/qemu,里面有一些针对ASPEED芯片特殊外设的补丁,比上游合入得更早也更全。如果你跑起来后发现某些外设行为不对,可以考虑切到OpenBMC维护的QEMU分支重新编译。但对大多数场景来说,上游QEMU已经够用了。
安装完QEMU后,可以先验证一下是否支持AST2600 machine:
qemu-system-arm -machine help | grep ast输出里能看到ast2600-evb,就说明当前QEMU支持这块板子了。
3. 编译OpenBMC固件:从源码到可烧写的镜像
3.1 拉取代码并初始化构建目录
OpenBMC的源码托管在GitHub上,主仓库地址是github.com/openbmc/openbmc。这个仓库里包含了构建所需的meta层、机器配置、以及所有子模块的依赖定义,整个构建通过bitbake驱动。
拉取代码的方式如下:
git clone https://github.com/openbmc/openbmc.git cd openbmc仓库体积不小,克隆的时候耐心等一会儿。拿到代码后,下一步就是初始化构建目录。OpenBMC用setup脚本自动生成指定机器的构建目录:
source setup ast2600-evb这条命令会创建一个build-ast2600-evb目录,并把bitbake命令的路径、环境变量都设置好。执行成功后会看到类似### Shell environment set up for builds. ###的提示。
整个过程有几个细节要注意。第一,source setup必须在openbmc仓库根目录下执行,否则找不到模板文件。第二,setup脚本支持用setup <machine> <build_dir>自定义构建目录名,默认会生成build-<machine>格式。第三,如果你以前构建过其他机器,想切到AST2600,需要在新的终端里重新source setup ast2600-evb,确保环境变量是干净的。
3.2 触发构建并理解构建过程
初始化完成后,执行实际的构建命令:
bitbake obmc-phosphor-imageobmc-phosphor-image是OpenBMC最常用的image目标,它会生成一个包含u-boot、内核、根文件系统、BMC管理服务的完整固件镜像。
第一次构建时,bitbake会先解析所有meta层和recipe,这一步会花几分钟。然后进入下载阶段,从GitHub和各种源码托管站点拉取所有组件的源码。下载完成后进入编译阶段,这个阶段耗时最长,而且CPU占用会拉满,属于正常现象。最后是打包阶段,把编译好的所有组件打包成镜像文件。
整个过程中,终端会不断刷新任务进度。如果你看到Executing (N of M)这类输出,说明正在按依赖关系逐个执行任务。中间偶尔会出现WARN:级别的日志,不用太紧张,很多是版本警告或者license检查提示,不影响最终产物。
构建完成后,镜像文件会输出到build-ast2600-evb/tmp/deploy/images/ast2600-evb/目录下。重点看这几个文件:
obmc-phosphor-image-ast2600-evb.static.mtd:完整的Flash镜像,包含了u-boot、内核、根文件系统,可以直接烧写到板载Flash。QEMU启动时用的“硬盘”就是这个。u-boot.bin:编译出来的u-boot二进制,单独调试u-boot用。zImage:Linux内核镜像。obmc-phosphor-image-ast2600-evb.ubi:UBI格式的根文件系统镜像,NAND Flash场景会用到。
进入构建目录的方式是:
cd build-ast2600-evb/tmp/deploy/images/ast2600-evb/ ls -lh建议用ls -lh看一眼文件大小,一个完整的AST2600 EVB镜像一般在几十MB量级。如果文件只有几MB,大概率是构建出了问题,后面启动时会卡住。
3.3 构建过程的资源占用和常见“假失败”
很多第一次构建OpenBMC的人会被终端里满屏的报错吓到,但bitbake的输出信息量非常大,并不是所有带ERROR:字样的都是致命问题。我见过最多的情况是某个recipe下载源码超时,bitbake会报ERROR: xxx: fetch failed,但整体构建并不会立刻退出,而是会重试几次。如果重试后还是失败,这个recipe才会真正失败并中止构建。
比较稳妥的做法是看到ERROR:后先确认对应的recipe名字和失败原因。如果确实只是网络原因,可以检查网络后再执行一次bitbake obmc-phosphor-image,bitbake会从断点继续,已经编译好的任务不会重新编译。
构建期间还需要盯一下磁盘空间。OpenBMC构建产生的临时文件散落在build-ast2600-evb/tmp/work*目录下,组件一多,磁盘占用就会快速增长。如果磁盘写满,bitbake通常会报No space left on device,这种错误清理起来很麻烦,因为很多临时文件还在被锁占用。建议构建前先df -h确认剩余空间。
4. 用QEMU启动AST2600-EVB:从镜像到登录系统
4.1 准备启动参数:Flash镜像和网络转发
编译好的obmc-phosphor-image-ast2600-evb.static.mtd就是一块“虚拟Flash芯片”。QEMU通过-drive参数把它挂载到AST2600的flash控制器上,模拟从Flash启动的过程。
启动命令的核心部分长这样:
qemu-system-arm \ -m 1024 \ -M ast2600-evb \ -nographic \ -drive file=obmc-phosphor-image-ast2600-evb.static.mtd,format=raw,if=mtd \ -net nic \ -net user,hostfwd=:127.0.0.1:2222-:22,hostfwd=:127.0.0.1:2443-:443逐项拆开看参数含义:
-m 1024:给虚拟机分配1024MB内存。AST2600芯片最多支持1GB DDR,给足内存跑Linux更顺畅。如果你发现启动过程内存吃紧,可以适当下调到512MB。-M ast2600-evb:指定机器类型为AST2600-EVB评估板,这行让QEMU加载对应的板级设备模型。-nographic:不开图形窗口,把串口重定向到当前终端。OpenBMC启动时u-boot和内核的日志都会从这里输出。-drive ... if=mtd:关键的Flash挂载参数。if=mtd告诉QEMU这块“盘”是挂到MTD子系统上的,对应真实硬件里的SPI Flash。-net nic:给虚拟机添加一块网卡,QEMU针对AST2600会自动选择合适的网卡模型。-net user,hostfwd=...:使用user模式网络,并把宿主机的2222端口转发到虚拟机的22端口(SSH)、2443端口转发到虚拟机的443端口(HTTPS WebUI和Redfish)。这样在宿主机上访问127.0.0.1:2222就相当于访问虚拟BMC的SSH端口。
启动前确认当前目录下有那个.static.mtd镜像文件,否则QEMU会报无法打开镜像的错误。
4.2 启动过程:从u-boot到Linux登录
执行上面的QEMU命令后,终端会立刻输出u-boot的启动日志。AST2600的u-boot先是初始化DDR、时钟、flash,然后加载内核和设备树。整个过程大约几十秒,比真机快不少。你不需要做任何操作,u-boot会自动加载内核启动。
内核启动阶段会打印大量设备初始化日志,包括内存布局、设备树信息、各个驱动的probe过程。OpenBMC的内核日志有一个特点:大量服务是通过systemd并行启动的,所以日志会交错出现,而且因为内核里所有console日志都打在同一个串口上,看起来会有点乱。耐心等一到两分钟,直到出现类似这样的登录提示:
OpenBMC Release ... ast2600-evb login:用户名为root,密码分两种情况。较新版本的OpenBMC默认密码是0penBmc(注意是数字0,不是字母o)。如果你用的是很老的版本,可能root没有密码,直接回车就能登录。首次登录后建议立刻用passwd改掉密码,毕竟这是跑在本地虚拟机里的,折腾过程中如果开放了端口转发,裸奔的默认密码终归不太安全。
登录成功后,可以先跑几个命令确认系统状态:
cat /etc/os-release uname -a busctl list | head -n 20busctl list会列出所有通过D-Bus注册的系统服务,能看到phosphor-*系列服务说明BMC管理栈已经跑起来了。想看具体某个服务状态可以用systemctl status,比如:
systemctl status phosphor-host-ipmid systemctl status phosphor-webui如果这两个服务都处于active (running)状态,说明IPMI和Web管理功能正常。
4.3 从宿主机访问虚拟BMC
BMC的典型使用方式是“远程管理”,所以登录进串口只是第一步,更重要的是验证SSH、HTTPS WebUI和Redfish这些管理接口能不能用。
SSH登录在宿主机上执行:
ssh root@127.0.0.1 -p 2222第一次连接会提示确认host key,输入yes后输入密码。OpenBMC的SSH服务用的是Dropbear,功能精简,但日常登录和转发都没问题。
Redfish接口是现在做BMC自动化最喜欢用的接口,用curl验证一下:
curl -k -u root:0penBmc https://127.0.0.1:2443/redfish/v1/Systems/system-k参数是因为OpenBMC默认使用自签名证书,curl会报证书错误,直接跳过验证。如果返回的JSON里能看到"PowerState": "On"、"Manufacturer": "ASPEED"之类的信息,说明Redfish服务正常,这台虚拟BMC已经可以提供和真机基本一致的管理能力了。
WebUI也可以顺便测一下,浏览器访问https://127.0.0.1:2443,忽略证书警告后用root和密码登录即可。OpenBMC的WebUI功能比较全,传感器数据、系统状态、用户管理、固件更新这些都有,体验比看串口输出直观得多。
5. 常见问题与排查技巧实录
5.1 构建阶段的高频问题
问题一:bitbake找不到命令。
执行bitbake时报command not found。原因基本只有一个:没有source setup ast2600-evb,或者换了一个终端窗口后没重新source。这个环境变量只在当前shell会话里有效,新开终端必须重新执行。
问题二:构建到一半报ERROR: xxx fetch failed。
前面说过这是网络下载问题。OpenBMC的recipe会从GitHub、kernel.org、sourceforge等地方拉取源码,任何一个源不稳定都可能导致失败。处理办法是等网络稳定后重新执行bitbake obmc-phosphor-image,已完成的构建会缓存复用。如果某个源码包反复下载失败,可以手动把下载好的源码包放进build-ast2600-evb/downloads/目录,bitbake会识别已下载的文件并跳过网络请求。
问题三:构建过程中磁盘满了。
最直接的解决办法是构建前预留足够空间,另外可以用bitbake -c clean清理某个不需要的recipe的构建产物。注意不要随便删tmp/work下的目录,bitbake的锁机制会因为你手动删文件而报一些莫名其妙的错误。
问题四:CPU占用长期100%,机器卡死。
Yocto的并行度设置太激进。在conf/local.conf里可以调整:
BB_NUMBER_THREADS = "4" PARALLEL_MAKE = "-j 4"这两个值建议设成和你机器核心数一致或略低,不要贪多。4核8线程的机器设-j 8往往比设-j 4慢,因为大量进程在抢CPU缓存和调度时间。
5.2 QEMU启动阶段的高频问题
问题一:qemu-system-arm: machine 'ast2600-evb' not found。
这就是QEMU版本太老,不支持AST2600 machine。用qemu-system-arm --version确认版本,低于5.0的升级QEMU,或者直接用OpenBMC社区维护的QEMU分支源码编译。
问题二:启动后没有任何输出。
最常见原因是-drive的镜像路径不对或格式不对。确认你指向的是obmc-phosphor-image-ast2600-evb.static.mtd文件,并且format=raw和if=mtd都写对了。另外可以试试加-serial mon:stdio参数,有些环境下串口重定向行为会有差异。
问题三:SSH能连上但输入密码后又被踢掉,或者一直提示密码错误。
先确认你输入的密码是0penBmc(数字0开头),不是OpenBmc。如果实在不确定,在串口登录后执行passwd root重新设置一个密码,再用SSH连接。
问题四:宿主机上访问127.0.0.1:2443打不开网页。
先确认QEMU进程里的hostfwd参数是不是写了hostfwd=:127.0.0.1:2443-:443,别漏了127.0.0.1前面的部分。另外确认虚拟BMC里的webui服务确实在监听443端口,可以进串口执行ss -lntp | grep 443看看。
5.3 使用体验优化和进阶玩法
基础环境跑通之后,有几个优化方向很值得做。
第一个方向是快照功能。QEMU支持-snapshot模式,所有对镜像的写入都只落到临时内存区,不会污染原始镜像文件。调试OpenBMC的时候经常要改配置、刷固件,一旦改坏了,关掉QEMU重新启动就是全新状态,这个特性非常实用。
第二个方向是自动化测试。OpenBMC的代码仓库里有一个tests目录,里面有大量基于QEMU的集成测试用例。跑这些用例不需要真机,只需要提前构建好QEMU镜像,然后由自动化脚本拉起QEMU、通过SSH或HTTPS接口执行断言。如果你想在CI里加OpenBMC验证,这是最省事的路子。
第三个方向是结合TFTP或NFS调试内核。QEMU启动的时候可以通过-kernel和-initrd参数指定单独的内核和initramfs,配合-append传内核启动参数,这样每次修改内核后就不用重新打包整个Flash镜像,开发迭代速度快很多。命令大概是:
qemu-system-arm -M ast2600-evb -nographic \ -kernel zImage \ -initrd obmc-phosphor-initramfs-ast2600-evb.cpio.xz \ -append "root=/dev/ram0 console=ttyS4,115200" \ -net nic -net user,hostfwd=:127.0.0.1:2222-:22这类模式在调试内核驱动时是最常用的,我第一次在QEMU里跑起来自定义内核模块,就是在-kernel模式下完成的,比反复烧整个镜像效率高一个数量级。
最后再说一个个人习惯:我会把整套启动命令写成一个shell脚本,比如run-ast2600.sh,把镜像路径、hostfwd端口、内存大小都做成变量。每次调试只需要改变量,不用在终端里敲一长串参数。这个脚本还可以放在CI里的artifacts目录里,别人拿到镜像也能一键复现环境。对于团队协作来说,这比共享一串复杂的命令行要靠谱得多。
如果你也是第一次在OpenBMC上做开发,我的建议是先把今天的流程完整走通,生成能启动的QEMU环境,然后尝试在系统里跑几条常见的BMC管理命令,感受一下整个管理栈的运作方式。之后再考虑u-boot修改、内核裁剪、自定义service这些更深的玩法。QEMU这一步走通了,后面折腾真机也就有底气了。