Now that the OpenPower sources are available, it's possible to build custom firmware images for OpenPower machines. Here's a little guide to show how that's done.
The build process
OpenPower firmware has a number of different components, and some infrastructure to pull it all together. We use buildroot to do most of the heavy lifting, plus a little wrapper, called op-build
.
There's a README file, containing build instructions in the op-build git repository, but here's a quick overview:
To build an OpenPower PNOR image from scratch, we'll need a few prerequisites (assuming recent Ubuntu):
sudo apt-get install cscope ctags libz-dev libexpat-dev libc6-dev-i386 \ gcc g++ git bison flex gcc-multilib g++-multilib libxml-simple-perl \ libxml-sax-perl
Then we can grab the op-build
repository, along with the git submodules:
git clone --recursive git://github.com/open-power/op-build.git
set up our environment and configure using the "palmetto" machine configuration:
. op-build-env op-build palmetto_defconfig
and build:
op-build
After a while (there is quite a bit of downloading to do on the first build), the build should complete successfully, and you'll have a PNOR image build in output/images/palmetto.pnor
.
If you have an existing op-build tree around (colleagues working on OpenPower perhaps?), you can share or copy the dl/
directory to save on download time.
The op-build
command is just a shortcut for a make
in the buildroot tree, so the general buildroot documentation applies here too. Just replace "make
" with "op-build
". For example, we can enable a verbose build with:
op-build V=1
Changing the build configuration
Above, we used a palmetto_defconfig
as the base buildroot configuration. This defines overall options for the build; things like:
- Toolchain details used to build the image
- Which firmware packages are used
- Which packages are used in the petitboot bootloader environment
- Which kernel configuration is used for the petitboot bootloader environment
This configuration can be changed through buildroot's menuconfig UI. To adjust the configuration:
op-build menuconfig
And busybox's configuration interface will be shown:
As an example, let's say we want to add the "file
" utility to the petitboot environment. To do this, we can nagivate to that option in the Target Packages section (Target Packages → Shell and Utilities → file), and enable the option:
Then exit (saving changes) and rebuild:
op-build
- the resulting image will have the file
command present in the petitboot shell environment.
Kernel configuration
There are a few other configuration targets to influence the build process; the most interesting for our case will be the kernel configuration. Since we use petitboot as our bootloader, it requires a Linux kernel for the initial bootloader environment. The set of drivers in this kernel will dictate which devices you'll be able to boot from.
So, if we want to enable booting from a new device, we'll need to include an appropriate driver in the kernel. To adjust the kernel configuration, use the linux-menuconfig
target:
op-build linux-menuconfig
- which will show the standard Linux "menuconfig" interface:
From here, you can alter the kernel configuration. Once you're done, save changes and exit. Then, to build the new PNOR image:
op-build
Customised packages
If you have a customised version of one of the packages used in the OpenPower build, you can easily tell op-build
to use your local package. There are a number of package-specific make variables documented in the buildroot generic package reference, the most interesting ones being the _VERSION
and _SITE
variables.
For example, let's say we have a custom petitboot tree that we want to use for the build. We've committed our changes in the petitboot tree, and want to build a new PNOR image. For the sake of this example, the git SHA petitboot commit we'd like to build is 2468ace0
, and our custom petitboot tree is at /home/jk/devel/petitboot
.
To build a new PNOR image with this particular petitboot source, we need to specify a few buildroot make variables:
op-build PETITBOOT_SITE=/home/jk/devel/petitboot \ PETITBOOT_SITE_METHOD=git \ PETITBOOT_VERSION=2468ace0
This is what these variables are doing:
PETITBOOT_SITE=/home/jk/devel/petitboot
- tellsop-build
where our custom source tree is. This could be a git URL or a local path.PETITBOOT_SITE_METHOD=git
- telslop-build
thatPETITBOOT_SITE
is a git tree. If we were using agit://
URL forPETITBOOT_SITE
, then this variable would be set automaticallyPETITBOOT_VERSION=2468ace0
- tellsop-build
which version of petitboot to checkout. This can be any commit reference that git understands.
The same method can be used for any of the other packages used during build. For OpenPower builds, you may also want to use the SKIBOOT_
* and LINUX_
* variables to include custom skiboot firmware and kernel in the build.
If you'd prefer to test new sources without committing to git, you can use _SITE_METHOD=local
. This will copy the source tree (defined by _SITE
) to the buildroot tree and use it directly. For example:
op-build SKIBOOT_SITE=/home/jk/devel/skiboot \ SKIBOOT_SITE_METHOD=local
- will build the current (and not-necessarily-committed) sources in /home/jk/devel/skiboot
. Note that buildroot has no way to tell if your code has changed with _SITE_METHOD=local
. If you re-build with this, it's safer to clean the relevant source tree first:
op-build skiboot-dirclean
Thanks for the post, it's really helpful. Now that I've built the palmetto.pnor image, how do I load it onto a Palmetto?
Thanks!