Tuesday, July 4, 2017

Porting UEFI to XXX, step 1

I've decided to do the actual blogging for this project *in* the repo itself. See https://github.com/andreiw/ppcnw-edk2/blob/master/README.md. After all, markdown is convenient enough and using Blogger on the G4 is p-a-i-n-f-u-l.

So it turns out that blogging about something after the fact is pretty tough. I really wanted to blog about my PoC port of UEFI to the OpenPower ecosystem, but it's incredibly difficult to go back and try to systematize something that's been a few years back.

So let's try this again. This time, our victim will be a G4 12" PowerBook6,8 with a 7447A. That's a 32-bit PowerPC. Now, I'll go in small steps and document *everything*. For added fun, we'll begin porting on the target itself, at least until that gets too tedious.

First, I updated to the latest (and last) Debian 8 (Jessie).

Now let's clone the tree.

$ git clone https://github.com/tianocore/edk2

Setup the UEFI environment.

$ cd edk2
$ . edksetup.sh

Now we need to get the BaseTools building.

pbg4:~/src/edk2/BaseTools/ make
make -C Source/C
make[1]: Entering directory '/home/andreiw/src/edk2/BaseTools/Source/C'
Attempting to detect ARCH from 'uname -m': ppc
Could not detected ARCH from uname results
GNUmakefile:36: *** ARCH is not defined!.  Stop.
make[1]: Leaving directory '/home/andreiw/src/edk2/BaseTools/Source/C'
GNUmakefile:25: recipe for target 'Source/C' failed
make: *** [Source/C] Error 2

Ok. Let's fix that. We'll first need a Source/C/Include/PPC/ProcessorBind.h file.

ProcessorBind.h I've derived from another 32-bit CPU, like IA32 or ARM. This contains type definitions, mostly. It's boilerplate. In case there are multiple coding conventions for your architectures and it's not obvious which one you should be using, you might wish to specify what the EFIAPI attribute will be. Like, on x86 Windows-style cdecl is used, regardless of how you build the rest of Tiano. On most architectures an empty define is fine.

Now appropriately hook it into Source/C/Makefiles/header.makefile.

--- a/BaseTools/Source/C/Makefiles/header.makefile
+++ b/BaseTools/Source/C/Makefiles/header.makefile
@@ -43,6 +43,10 @@ ifeq ($(ARCH), AARCH64)
 ARCH_INCLUDE = -I $(MAKEROOT)/Include/AArch64/
 endif
+ifeq ($(ARCH), PPC)
+ARCH_INCLUDE = -I $(MAKEROOT)/Include/PPC/
+endif

Fix the ARCH detection in Source/C/GNUmakefile.

--- a/BaseTools/Source/C/GNUmakefile
+++ b/BaseTools/Source/C/GNUmakefile
@@ -31,6 +31,9 @@ ifndef ARCH
   ifneq (,$(findstring arm,$(uname_m)))
     ARCH=ARM
   endif
  ifneq (,$(findstring ppc,$(uname_m)))
    ARCH=PPC
  endif

Ok, ensure you have the libuuid headers (Debian uuid-dev) and g++. And...

You are done. This gives you the tools need to help build UEFI. Now we need to teach the build system about PowerPC...