xref: /openbmc/docs/cheatsheet.md (revision d5afde3325b0622a2e9d19f41192a88321145014)
1cdfa8079SJeremy Kerr
2cdfa8079SJeremy Kerr# OpenBMC cheatsheet
3cdfa8079SJeremy Kerr
4cdfa8079SJeremy KerrThis document is intended to provide a set of recipes for common OpenBMC
5cdfa8079SJeremy Kerrcustomisation tasks, without having to know the full yocto build process.
6cdfa8079SJeremy Kerr
7cdfa8079SJeremy Kerr## Using a local kernel build
8cdfa8079SJeremy Kerr
9cdfa8079SJeremy KerrThe kernel recipe is in:
10cdfa8079SJeremy Kerr
11cdfa8079SJeremy Kerr```
12ba2abfa4SYong Li meta-phosphor/common/recipes-kernel/linux/linux-obmc_X.Y.bb
13cdfa8079SJeremy Kerr```
14cdfa8079SJeremy Kerr
15cdfa8079SJeremy KerrTo use a local git tree, change the `SRC_URI` to a git:// URL without
16cdfa8079SJeremy Kerra hostname. For example:
17cdfa8079SJeremy Kerr
18cdfa8079SJeremy Kerr```
19cdfa8079SJeremy KerrSRC_URI = "git:///home/jk/devel/linux;protocol=git;branch=${KBRANCH}"
20cdfa8079SJeremy Kerr```
21cdfa8079SJeremy Kerr
22cdfa8079SJeremy KerrThe `SRCREV` variable can be used to set an explicit git commit. The
23cdfa8079SJeremy Kerrdefault (`${AUTOREV}`) will use the latest commit in `KBRANCH`.
24cdfa8079SJeremy Kerr
257b22067aSJoel Stanley## Building for Palmetto
26cdfa8079SJeremy Kerr
277b22067aSJoel StanleyThe Palmetto target is `palmetto`.
287b22067aSJoel Stanley
297b22067aSJoel StanleyIf you are starting from scratch without a `build/conf` directory you can just:
307b22067aSJoel Stanley```
317b22067aSJoel Stanley$ cd openbmc
32873a0495SAdriana Kobylak$ TEMPLATECONF=meta-ibm/meta-palmetto/conf . openbmc-env
3335abff5fSJeremy Kerr$ bitbake obmc-phosphor-image
347b22067aSJoel Stanley```
357b22067aSJoel Stanley
3667850dd8SGunnar Mills## Building for Zaius
3757812c89SAdi Gangidi
3867850dd8SGunnar MillsThe Zaius target is `zaius`.
3957812c89SAdi Gangidi
4057812c89SAdi GangidiIf you are starting from scratch without a `build/conf` directory you can just:
4157812c89SAdi Gangidi```
4257812c89SAdi Gangidi$ cd openbmc
43873a0495SAdriana Kobylak$ TEMPLATECONF=meta-ingrasys/meta-zaius/conf . openbmc-env
4457812c89SAdi Gangidi$ bitbake obmc-phosphor-image
4557812c89SAdi Gangidi```
4657812c89SAdi Gangidi
47*d5afde33SAdriana Kobylak## Building a specific machine configuration
48*d5afde33SAdriana Kobylak
49*d5afde33SAdriana KobylakIf the system you want to build contains different machine configurations:
50*d5afde33SAdriana Kobylak
51*d5afde33SAdriana Kobylak    meta-<layer>/meta-<system>/conf/machine/machineA.conf
52*d5afde33SAdriana Kobylak    meta-<layer>/meta-<system>/conf/machine/machineB.conf
53*d5afde33SAdriana Kobylak
54*d5afde33SAdriana KobylakYou can specify the machine configuration you want to build by setting the
55*d5afde33SAdriana KobylakMACHINE environment variable. Then add `MACHINE` to the BB_ENV_EXTRAWHITE
56*d5afde33SAdriana Kobylakenvironment variable to make the new MACHINE value available to BitBake:
57*d5afde33SAdriana Kobylak
58*d5afde33SAdriana Kobylak    $ cd openbmc
59*d5afde33SAdriana Kobylak    $ TEMPLATECONF=meta-<layer>/meta-<system>/conf . openbmc-env
60*d5afde33SAdriana Kobylak    $ export MACHINE="machineB"
61*d5afde33SAdriana Kobylak    $ export BB_ENV_EXTRAWHITE="$BB_ENV_EXTRAWHITE MACHINE"
62*d5afde33SAdriana Kobylak    $ bitbake obmc-phosphor-image
63*d5afde33SAdriana Kobylak
640ea78f3aSChris Austen## Building the OpenBMC SDK
650ea78f3aSChris AustenLooking for a way to compile your programs for 'ARM' but you happen to be running on a 'PPC' or 'x86' system?  You can build the sdk receive a fakeroot environment.
660ea78f3aSChris Austen```
670ea78f3aSChris Austen$ bitbake -c populate_sdk obmc-phosphor-image
68155192f5Scausten$ ./tmp/deploy/sdk/openbmc-phosphor-glibc-x86_64-obmc-phosphor-image-armv5e-toolchain-2.1.sh
690ea78f3aSChris Austen```
700ea78f3aSChris AustenFollow the prompts.  After it has been installed the default to setup your env will be similar to this command
710ea78f3aSChris Austen```
72155192f5Scausten. /opt/openbmc-phosphor/2.1/environment-setup-armv5e-openbmc-linux-gnueabi
730ea78f3aSChris Austen```
740ea78f3aSChris Austen
757b22067aSJoel Stanley## Rebuilds & Reconfiguration
767b22067aSJoel Stanley
777b22067aSJoel StanleyYou can reconfigure your build by removing the build/conf dir:
787b22067aSJoel Stanley```
797b22067aSJoel Stanleyrm -rf build/conf
807b22067aSJoel Stanley```
81f6b9fe0eSAdriana Kobylakand running `openbmc-env` again (possibly with `TEMPLATECONF` set).
828196be3eSJeremy Kerr
83924bc9c1SGunnar Mills## Useful D-Bus CLI tools
848196be3eSJeremy Kerr
858196be3eSJeremy Kerr## `busctl`
868196be3eSJeremy Kerr
878196be3eSJeremy Kerrhttp://www.freedesktop.org/software/systemd/man/busctl.html
888196be3eSJeremy Kerr
89924bc9c1SGunnar MillsGreat tool to issue D-Bus commands via cli. That way you don't have to wait for
908196be3eSJeremy Kerrthe code to hit the path on the system. Great for running commands with QEMU
918196be3eSJeremy Kerrtoo!
928196be3eSJeremy Kerr
938196be3eSJeremy KerrRun as:
948196be3eSJeremy Kerr
958196be3eSJeremy Kerr```
968196be3eSJeremy Kerrbusctl call <path> <interface> <object> <method> <parameters>
978196be3eSJeremy Kerr```
988196be3eSJeremy Kerr
998196be3eSJeremy Kerr* \<parameters\> example : sssay "t1" "t2" "t3" 2 2 3
100dd7e9997SAndrew Jeffery
101dd7e9997SAndrew Jeffery## Using QEMU
102dd7e9997SAndrew Jeffery
103dd7e9997SAndrew JefferyQEMU has a palmetto-bmc machine (as of v2.6.0) which implements the core
104dd7e9997SAndrew Jefferydevices to boot a Linux kernel. OpenBMC also [maintains a
105dd7e9997SAndrew Jefferytree](https://github.com/openbmc/qemu) with patches on their way upstream or
106dd7e9997SAndrew Jefferytemporary work-arounds that add to QEMU's capabilities where appropriate.
107dd7e9997SAndrew Jeffery
10881db7dbaSChris Austen```
10981db7dbaSChris Austenqemu-system-arm -m 256 -M palmetto-bmc -nographic \
11081db7dbaSChris Austen-drive file=<path>/flash-palmetto,format=raw,if=mtd \
11181db7dbaSChris Austen-net nic \
11281db7dbaSChris Austen-net user,hostfwd=:127.0.0.1:2222-:22,hostfwd=:127.0.0.1:2443-:443,hostname=qemu \
11381db7dbaSChris Austen```
11481db7dbaSChris AustenIf you get an error you likely need to build QEMU (see the section in this document).   If no error and QEMU starts up just change the port when interacting with the BMC...
115dd7e9997SAndrew Jeffery
116dd7e9997SAndrew Jeffery```
11781db7dbaSChris Austencurl -c cjar -b cjar -k -H "Content-Type: application/json" \
11881db7dbaSChris Austen-X POST https://localhost:2443/login -d "{\"data\": [ \"root\", \"0penBmc\" ] }"
11981db7dbaSChris Austen```
12081db7dbaSChris Austenor
12181db7dbaSChris Austen
12281db7dbaSChris Austen```
12381db7dbaSChris Austenssh -p 2222 root@localhost
124dd7e9997SAndrew Jeffery```
125dd7e9997SAndrew Jeffery
126dd7e9997SAndrew JefferyTo quit, type `Ctrl-a c` to switch to the QEMU monitor, and then `quit` to exit.
127ae88254cSJoel Stanley
12881db7dbaSChris Austen## Building QEMU
12981db7dbaSChris Austen
13081db7dbaSChris Austen```
13181db7dbaSChris Austengit clone https://github.com/openbmc/qemu.git
13281db7dbaSChris Austencd qemu
13381db7dbaSChris Austengit submodule update --init dtc
13481db7dbaSChris Austenmkdir build
13581db7dbaSChris Austencd build
13681db7dbaSChris Austen../configure --target-list=arm-softmmu
13781db7dbaSChris Austenmake
13881db7dbaSChris Austen```
13981db7dbaSChris AustenBuilt file will be located at: ```arm-softmmu/qemu-system-arm```
14081db7dbaSChris Austen
14181db7dbaSChris Austen### Use a bridge device
14281db7dbaSChris AustenUsing a bridge device requires a bit of root access to set it up.  The benefit
14381db7dbaSChris Austenis your qemu session runs in the bridges subnet so no port forwarding is needed.
14481db7dbaSChris AustenThere are packages needed to yourself a virbr0 such as...
14581db7dbaSChris Austen
14681db7dbaSChris Austen```
14781db7dbaSChris Austenapt-get install libvirt libvirt-bin bridge-utils uml-utilities qemu-system-common
14881db7dbaSChris Austen
14981db7dbaSChris Austenqemu-system-arm -m 256 -M palmetto-bmc -nographic \
15081db7dbaSChris Austen-drive file=<path>/flash-palmetto,format=raw,if=mtd \
15181db7dbaSChris Austen-net nic,macaddr=C0:FF:EE:00:00:02,model=ftgmac100  \
15281db7dbaSChris Austen-net bridge,id=net0,helper=/usr/lib/qemu-bridge-helper,br=virbr0
15381db7dbaSChris Austen```
15481db7dbaSChris Austen
15581db7dbaSChris AustenThere are some other useful parms like that can redirect the console to another
15681db7dbaSChris Austenwindow.  This results in having an easily accessible qemu command session.
15781db7dbaSChris Austen```-monitor stdio -serial pty -nodefaults```
15881db7dbaSChris Austen
15981db7dbaSChris Austen
160ae88254cSJoel Stanley## Booting the host
161ae88254cSJoel Stanley
162ae88254cSJoel StanleyLogin:
163ae88254cSJoel Stanley```
16403504a95SGunnar Millscurl -c cjar -k -X POST -H "Content-Type: application/json" -d '{"data": [ "root", "0penBmc" ] }' https://${bmc}/login
165ae88254cSJoel Stanley```
166ae88254cSJoel Stanley
167ae88254cSJoel StanleyConnect to host console:
168ae88254cSJoel Stanley```
169ae88254cSJoel Stanleyssh -p 2200 root@bmc
170ae88254cSJoel Stanley```
171ae88254cSJoel Stanley
172ae88254cSJoel StanleyPower on:
173ae88254cSJoel Stanley```
174b56bec0dSGunnar Millscurl -c cjar -b cjar -k -H "Content-Type: application/json" -X PUT \
175b56bec0dSGunnar Mills  -d '{"data": "xyz.openbmc_project.State.Host.Transition.On"}' \
17603504a95SGunnar Mills  https://${bmc}/xyz/openbmc_project/state/host0/attr/RequestedHostTransition
177ae88254cSJoel Stanley```
178246fc994SLei YU
179246fc994SLei YU## GDB
180246fc994SLei YU
181246fc994SLei YU[SDK build](#building-the-openbmc-sdk) provides GDB and debug symbols:
182246fc994SLei YU
183246fc994SLei YU* `$GDB` is available to use once SDK environment is setup
184246fc994SLei YU* Debug symbols are located in `.debug/` directory of each executable
185246fc994SLei YU
186246fc994SLei YUTo use GDB:
187246fc994SLei YU
188246fc994SLei YU1. Setup SDK environment;
189246fc994SLei YU2. Run below GDB commands:
190246fc994SLei YU   ```
191246fc994SLei YU   cd <sysroot_of_sdk_build>
192246fc994SLei YU   $GDB <relative_path_to_exeutable> <path_to_core_file>
193246fc994SLei YU   ```
194246fc994SLei YU
195246fc994SLei YU## Coredump
196246fc994SLei YU
197246fc994SLei YUBy default coredump is disabled in OpenBMC. To enable coredump:
198246fc994SLei YU```
199246fc994SLei YUecho '/tmp/core_%e.%p' | tee /proc/sys/kernel/core_pattern
20048ec067cSLei YUulimit -c unlimited
201246fc994SLei YU```
202246fc994SLei YU
2034635bf2fSPatrick Venture## Cleaning up read-write file system changes
2044635bf2fSPatrick Venture
2054635bf2fSPatrick VentureYou may want to investigate which file(s) are persisting through the overlay
2064635bf2fSPatrick Venturerwfs.  To do this, you can list this path and then remove those files which
2074635bf2fSPatrick Ventureyou'd prefer the originals or remove the deletion overlay to restore files.
2084635bf2fSPatrick Venture
2094635bf2fSPatrick Venture```
2104635bf2fSPatrick Venture/run/initramfs/rw/cow/
2114635bf2fSPatrick Venture```
212e94a168cSLei YU
213e94a168cSLei YU## Building
214e94a168cSLei YU
215e94a168cSLei YU### Share downloads directory
216e94a168cSLei YUIt takes a long time for the first build of OpenBMC. It downloads various repos
217e94a168cSLei YUfrom the internet.
218e94a168cSLei YU
219e94a168cSLei YUCheck `build/downloads` to see all the downloaded repos.
220e94a168cSLei YU
221e94a168cSLei YU* If a repo is a single archive, it usually looks like this:
222e94a168cSLei YU   * `zlib-1.2.11.tar.xz` - The repo itself
223e94a168cSLei YU   * `zlib-1.2.11.tar.xz.done` - A flag indicating the repo is downloaded
224e94a168cSLei YU* If a repo is managed by git, it usually looks like this:
225e94a168cSLei YU   * `git2/github.com.openbmc.linux` - The git bare clone
226e94a168cSLei YU   * `git2/github.com.openbmc.linux.done` - A flag indicating the repo is downloaded
227e94a168cSLei YU
228e94a168cSLei YUBitbake will extract the code to the working directory during build, so the
229e94a168cSLei YU`downloads` directory could be shared by different builds on a system:
230e94a168cSLei YU
231e94a168cSLei YU* Set `DL_DIR` Bitbake environment variable to the location of your shared
232e94a168cSLei YU   downloads directory by editing the `build/conf/local.conf` file:
233e94a168cSLei YU   ```
234e94a168cSLei YU   DL_DIR ?= "<path>/<to>/<existing>/downloads"
235e94a168cSLei YU   ```
236e94a168cSLei YU* Or create a symbol link:
237e94a168cSLei YU   ```
238e94a168cSLei YU   ln -sf <path>/<to>/<existing>/downloads build/downloads
239e94a168cSLei YU   ```
240e94a168cSLei YUThen do the build.  It will save a lot of time from downloading codes.
241e94a168cSLei YU
242e94a168cSLei YU## Using git proxy
243e94a168cSLei YUIf you experience extremely slow download speed during code fetch (e.g. if you
244e94a168cSLei YUare in China), it is possible to use a git proxy to speed up the code fetch.
245e94a168cSLei YU
246e94a168cSLei YUGoogle `git-proxy-wrapper` will find various ways to setup the proxy for the
247e94a168cSLei YUgit protocol.
248e94a168cSLei YU
249e94a168cSLei YUBelow is an example wrapper in `~/bin` assuming a socks5 proxy at port 9054:
250e94a168cSLei YU```
251e94a168cSLei YU#!/bin/sh
252e94a168cSLei YU## Use connect-proxy as git proxy wrapper which supports SOCKS5
253e94a168cSLei YU## Install with `apt-get install connect-proxy`
254e94a168cSLei YU## Use with `export GIT_PROXY_COMMAND=~/bin/git-proxy-wrapper`
255e94a168cSLei YU/usr/bin/connect -S localhost:9054 "$@"
256e94a168cSLei YU```
257e94a168cSLei YUThen you can run `export GIT_PROXY_COMMAND=~/bin/git-proxy-wrapper` and you are
258e94a168cSLei YUnow downloading git code through your proxy.
259e94a168cSLei YU
260e94a168cSLei YU## devtool
261e94a168cSLei YU
262e94a168cSLei YU`devtool` is a convenient utility in Yocto to make changes in the local
263e94a168cSLei YUdirectory.
264e94a168cSLei YUTypical usage is:
265e94a168cSLei YU```
266e94a168cSLei YU# To create a local copy of recipe's code and build with it:
267e94a168cSLei YUdevtool modify <recipe>
268e94a168cSLei YUcd build/workspace/sources/<recipe>  # And make changes
269e94a168cSLei YUbitbake obmc-phosphor-image  # Build with local changes
270e94a168cSLei YU
271e94a168cSLei YU# After you have finished, reset the recipe to ignore local changes:
272e94a168cSLei YUdevtool reset <recipe>
273e94a168cSLei YU```
274e94a168cSLei YU
275e94a168cSLei YUTo use this tool, you need the build environment, e.g. `. oe-init-build-env`.
276e94a168cSLei YUThe above script will add `<WORKDIR>/scripts/` to your `PATH` env and
277e94a168cSLei YU`devtool` is in the path.
278e94a168cSLei YU
279e94a168cSLei YUBelow are real examples.
280e94a168cSLei YU
281e94a168cSLei YU
282e94a168cSLei YU### devtool on ipmi
283e94a168cSLei YU
284e94a168cSLei YUIf you want to debug or add a new function in ipmi, you probably need to
285e94a168cSLei YUchange the code in [phosphor-host-ipmid][1].
286e94a168cSLei YUChecking the recipes, you know this repo is in [phosphor-ipmi-host.bb][2].
287e94a168cSLei YUBelow are the steps to use devtool to modify the code locally, build and test
288e94a168cSLei YUit.
289e94a168cSLei YU1. Use devtool to create a local repo:
290e94a168cSLei YU   ```
291e94a168cSLei YU   devtool modify phosphor-ipmi-host
292e94a168cSLei YU   ```
293e94a168cSLei YU   devtool clones the repo into `build/workspace/sources/phosphor-ipmi-host`,
294e94a168cSLei YU   creates and checkout branch `devtool`.
295e94a168cSLei YU2. Make changes in the repo, e.g. adding code to handle new ipmi commands or
296e94a168cSLei YU   simply adding trace logs.
297e94a168cSLei YU3. Now you can build the whole image or the ipmi recipe itself:
298e94a168cSLei YU   ```
299e94a168cSLei YU   bitbake obmc-phosphor-image  # Build the whole image
300e94a168cSLei YU   bitbake phosphor-ipmi-host  # Build the recipe
301e94a168cSLei YU   ```
302e94a168cSLei YU4. To test your change, either flash the whole image or replace the changed
303e94a168cSLei YU   binary. Note that the changed code is built into `libapphandler.so` and it
304e94a168cSLei YU   is used by both host and net ipmi daemon.
305e94a168cSLei YU   It is recommended that you copy the changed binary to BMC because it is
306e94a168cSLei YU   easier to test:
307e94a168cSLei YU   ```
308e94a168cSLei YU   # Replace libapphandler.so.0.0.0
309e94a168cSLei YU   scp build/workspace/sources/phosphor-ipmi-host/oe-workdir/package/usr/lib/ipmid-providers/libapphandler.so.0.0.0 root@bmc:/usr/lib/ipmid-providers/
310e94a168cSLei YU   systemctl restart phosphor-ipmi-host.service  # Restart the inband ipmi daemon
311e94a168cSLei YU   # Or restart phosphor-ipmi-net.service if you want to test net ipmi.
312e94a168cSLei YU   ```
313e94a168cSLei YU5. Now you can test your changes.
314e94a168cSLei YU
315e94a168cSLei YU
316e94a168cSLei YU## Develop linux kernel
317e94a168cSLei YU
318e94a168cSLei YU### devtool on linux kernel
319e94a168cSLei YUIf you want to work on linux kernel, you can use devtool as well, with some
320e94a168cSLei YUdifferences from regular repos.
321e94a168cSLei YU
322e94a168cSLei YU**Note**: As of [ac72846][3] the linux kernel recipe name is changed to
323e94a168cSLei YU`linux-aspeed` for Aspeed based OpenBMC builds.
324e94a168cSLei YUIn the following examples, replace `linux-obmc` with `linux-aspeed` if you are
325e94a168cSLei YUon a revision later than [ac72846][3].
326e94a168cSLei YU
327e94a168cSLei YU1. devtool does not create the 'devtool' branch. Instead, it checkout the
328e94a168cSLei YU   branch specified in the recipe.
329e94a168cSLei YU   For example, on the OpenBMC v2.2 tag, `linux-obmc_4.13.bb` specifies
330e94a168cSLei YU   `dev-4.13` branch.
331e94a168cSLei YU2. If there are patches, `devtool` applies them directly on the branch.
332e94a168cSLei YU3. devtool copies the defconfig and machine-specific config into `oe-workdir`.
333e94a168cSLei YU4. devtool generates the `.config` file based on the above configs.
334e94a168cSLei YU
335e94a168cSLei YUYou can modify the code and build the kernel as usual as follows:
336e94a168cSLei YU```
337e94a168cSLei YUbitbake linux-obmc -c build
338e94a168cSLei YU```
339e94a168cSLei YU
340e94a168cSLei YU### Modify config
341e94a168cSLei YUIf you need to change the config and save it as defconfig for further use:
342e94a168cSLei YU```
343e94a168cSLei YUbitbake linux-obmc -c menuconfig
344e94a168cSLei YU# Edit the configs and after save it generates
345e94a168cSLei YU# .config.new as the new kernel config
346e94a168cSLei YU
347e94a168cSLei YUbitbake linux-obmc -c savedefconfig
348e94a168cSLei YU# It will save the new defconfig at oe-workdir/linux-obmc-<version>/defconfig
349e94a168cSLei YU```
350e94a168cSLei YU
351e94a168cSLei YU### Test linux kernel
352e94a168cSLei YUAfter build, you can flash the image to test the new kernel.
353e94a168cSLei YUHowever, it is always slow to flash an image to the chip.
354e94a168cSLei YU
355e94a168cSLei YUThere is a faster way to load the kernel via network so you can easily test
356e94a168cSLei YUkernel builds.
357e94a168cSLei YU
358e94a168cSLei YUOpenBMC kernel build generates `fit` image, including `kernel`, `dtb` and
359e94a168cSLei YU`initramfs`.
360e94a168cSLei YUTypically we can load it via tftp, taking Romulus as an example:
361e94a168cSLei YU1. Put `build/tmp/deploy/images/romulus/fitImage-obmc-phosphor-initramfs-romulus.bin`
362e94a168cSLei YU   to a tftp server, name it to `fitImage`
363e94a168cSLei YU2. Reboot BMC and press keys to enter uboot shell;
364e94a168cSLei YU3. In uboot:
365e94a168cSLei YU   ```
366e94a168cSLei YU   setenv ethaddr <mac:addr>  # Set mac address if there it is unavailable
367e94a168cSLei YU   setenv ipaddr 192.168.0.80  # Set BMC IP
368e94a168cSLei YU   setenv serverip 192.168.0.11  # Set tftp server IP
369e94a168cSLei YU   tftp 0x83000000 fitImage  # Load fit image to ram. Use 0x43000000 on AST2400
370e94a168cSLei YU   bootm 0x83000000  # Boot from fit image
371e94a168cSLei YU   ```
372e94a168cSLei YUThen you are running an OpenBMC with your updated kernel.
373e94a168cSLei YU
374e94a168cSLei YU
375e94a168cSLei YU[1]: https://github.com/openbmc/phosphor-host-ipmid
376e94a168cSLei YU[2]: https://github.com/openbmc/openbmc/blob/c53f375a0f92f847d2aa50e19de54840e8472c8e/meta-phosphor/recipes-phosphor/ipmi/phosphor-ipmi-host_git.bb
377e94a168cSLei YU[3]: https://github.com/openbmc/openbmc/commit/ac7284629ea572cf27d69949dc4014b3b226f14f
378