TianoCore and coreboot, again

It has been over two years since the last time I worked on TianoCore for coreboot. These days I had some free time to spend and I used it to continue the project. I updated my code to the latest versions of coreboot and TianoCore and got it to work again in QEMU.

Here’s a "screenshot" and a few words on what it’s all about.

Hacking coreboot and libpayload

After some quiet time, I picked up a project I started a while ago: Hacking coreboot and libpayload on FreeBSD.

Building coreboot

On FreeBSD, building coreboot requires a toolchain built from the GNU sources. If the stock toolchain is used, the build process dies with this error:

CC      build/stage0.init
/usr/home/phs/sandbox/coreboot-v3/build/arch/x86/stage0_i586.o(.text+0xf): In function `_stage0':
: relocation truncated to fit: R_386_16 gdtptr
gmake: *** [/usr/home/phs/sandbox/coreboot-v3/build/stage0.init] Error 1

The solution is to build a compiler as described here and here and then set the $CROSS environment variable accordingly, e.g. like this:

$ export CROSS=/opt/bin/i386-unknown-linux-gnu-

Note that the above requires that this patch is applied. After that, build the bios.bin binary using GNU make.

$ gmake menuconfig
$ gmake

Building libpayload

Compiling libpayload is trickier than building coreboot as the build files assume that the world is Linux. First, sh is not always bash. Second, the header and library search paths are screwed up as they don’t include /usr/local subdirectores. Third, the gettext library is installed as libgettextlib.so on FreeBSD and must be linked against the program explicitly. And finally, the install(1) tool has different parameters than on Linux. Oh, and there are no stdarg.h and stddef.h headers.

I’ve hacked around those issues, the Mercurial repository is available at https://phs.subgra.de/hg/libpayload.

Qemu and Coreboot on FreeBSD/amd64

Today I tried to boot FreeBSD inside Qemu, using coreboot. I already wrote a short guide on how to do this, but I only tested it on a FreeBSD/i386 host. Now I’m trying to do the same thing, except this time the host is a FreeBSD/amd64 system.

I encountered several problems and I’m going to describe them along with the workarounds here.

First, the devel/dev86 port I created was marked as running on i386 only. I initially did this because I wasn’t sure if the software would run on amd64, but after testing it I can say that it does work. So the port needs a little tweaking, namely this line

ONLY_FOR_ARCHS= i386

needs to be extended to

ONLY_FOR_ARCHS= i386 amd64

or maybe even removed completely.

Second, the RomCC utility used in the coreboot build process crashes, apparently due to a change in GCC 4 as opposed to GCC 3.4 used in older versions on FreeBSD. It crashes in a function called “free_basic_block” and the workaround is this:

Index: util/romcc/romcc.c
===================================================================
--- util/romcc/romcc.c  (revision 3088)
+++ util/romcc/romcc.c  (working copy)
@@ -15083,6 +15083,8 @@

static void free_basic_block(struct compile_state *state, struct block *block)
{
+       return;
+
      struct block_set *edge, *entry;
      struct block *child;
      if (!block) {

Third, the linker on FreeBSD/amd64 does not understand the -m32 flag. So I needed a cross compiler for i386. Warner Losh has an entry in his blog that describes how to cross build FreeBSD. I don’t need all of FreeBSD but only the compiler, so I use this:

$ cd /usr/src
$ export TARGET=i386
$ export TARGET_ARCH=i386
$ make toolchain

This gives me an i386 cross compiler in /usr/obj/i386/usr/src/tmp/usr/bin that I need to use to compile coreboot. I did this to tell the GNU make utility to use the cross compiler:


gmake CC=/usr/obj/i386/usr/src/tmp/usr/bin/gcc


There is one outstanding problem: Qemu crashes when I try to use coreboot as a BIOS replacement. It may have to do with the version of Qemu I’m using right now. I’ll try to use an older version later this afternoon to see if it solves the problem.

Using Qemu 0.9.0 with the required patches (see the Qemu Build Tutorial) made the problem go away and I’m now able to boot FreeBSD/i386 8-CURRENT inside Qemu, using coreboot and ADLO. I’ve uploaded a complete archive of the port files to the coreboot wiki, see this link.