Controlling Open Firmware with -prom-env
Open Firmware has a concept of environment configuration variables
that are used to control the boot flow and other behavior of the firmware.
On ppc64 systems, these variables are normally stored in the NVRAM of the
machine (as defined in the LoPAPR specification, chapter 8.4.1.1, “System
NVRAM Partition”), so that they are persistent between reboots - at least
on real systems. With QEMU, the emulated NVRAM has got to be backed with a
real file on the host, of course, to make the contents persistent. This can
be done with the parameter -drive if=pflash,file=filename,format=raw
of
QEMU, for example.
Now, if the backing file via pflash is not used, the contents of the NVRAM
can be created by QEMU dynamically. QEMU features a dedicated parameter called
-prom-env
for setting the configuration variables in NVRAM. This works with
all the OpenBIOS based machines in QEMU (like the mac99 or
g3beige machine) since a long time already, but since version 2.8
has been released in last December, QEMU now also supports this option for the
pseries machine, i.e. it can now also be used to control the boot
behavior of the SLOF firmware of an sPAPR guest. So this is a good point in
time to have a closer look at this parameter to explain how it can be used
with the pseries machine…
The supported environment variables and their values can be listed by
typing printenv
at the SLOF firmware prompt:
Many of the configuration variables are either only useful for debugging (like “fcode-debug?”), or even only there without real functionality since the IEEE 1275 standard mandates that they’ve got to be available (like “oem-logo”), but the implementation of the intended functionality did not make much sense in SLOF.
Some other configuration variables are really useful, though. For example,
if you want to avoid that SLOF boots automatically (so you can do some things
at the firmware prompt before running the OS), you can start QEMU with
-prom-env 'auto-boot?=false'
to disable the auto-boot feature. Of course you
could also hit the “s” key during boot to drop to the firmware prompt, but this
can be quite annoying if you’re doing multiple things in parallel and thus you
easily miss the very right point in time. Using the configuration variable is
much more convenient.
Another very useful trick is that you can execute arbitrary Forth code during
the boot process with the -prom-env parameter! The likely obvious way is to use
the “nvramrc” variable. For example, if you start QEMU with the parameters
-prom-env 'use-nvramrc?=true' -prom-env 'nvramrc=." Hello World!" cr'
, SLOF
will print “Hello World!” during the boot process, followed by a carriage
return. But there is another way for executing Forth code, which I personally
prefer if I do not have to boot an OS afterwards (since you do not have to
set two variables in this case): You can override the boot-command
variable, which also contains Forth code. For example using the parameters
-prom-env 'boot-command=." Hello World!" cr'
will print “Hello World” during
the boot process, too, just at a little bit later point in time. This can
also be useful to run firmware reboot tests: When you run QEMU with
-prom-env 'boot-command=reset-all'
, the firmware will reboot automatically
each time instead of booting an operating system. Or use
-prom-env 'boot-command=power-off'
to shut down the VM automatically at
the end of the firmware boot process.
Something else that bugged me for a long time was the behavior of the
input selection in SLOF. When you boot your pseries guest with
a VGA graphics card, SLOF always automatically uses the emulated USB keyboard
as input device. But if you want to debug the VGA or USB code in the firmware
for example, it is much more convenient if you can interact with the firwmare
via the serial console (aka. hvterm). So now that QEMU supports the
-prom-env parameter for the pseries machine, too, I’ve recently added
some code to SLOF that forces the firmware to stay with the serial input
instead of switching to the emulated USB keyboard. You can control the behavior
now with the “direct-serial?” configuration variable. If you start QEMU
with the parameters -nographic -vga std -prom-env 'direct-serial?=true'
for
example, you can still interact with the firmware in the terminal window even
though the firmware detected a graphics card and USB keyboard. (Note: This
new feature is currently only available in the development version of SLOF,
but it will be part of the SLOF release that will be shipped with QEMU version
2.9)