L4Ka Project

Building ...

Copyright (C) 2002-2003, University of Karlsruhe
Maintained by Joshua LeVasseur <jtl does-not-exist.ira uka de>

[ Building the PowerPC Kernel ]

This document describes the procedure to create the build environment
for a PowerPC kernel.  An outline of the steps:
1. build a PowerPC version of the binutils
2. build a PowerPC version of gcc
3. create and initialize the Pistachio build directory and its Makeconf.local

This document also describes how to configure, build and use the psim
simulator with the PowerPC Pistachio kernel.

You will be creating cross-platform tools, so these directions are 
neutral towards the architecture of your build host.

Tested build configurations:
- ia32 Debian Linux (gcc-2.95.3, gcc-3.0.3, gcc-3.2, gcc-3.2.1)
- PowerPC Debian Linux (gcc-2.95.3, gcc-3.03)
- MacOS 10.2 using gcc 3.2 as the native compiler 
  (binutils-2.13, binutils-2.13.2.1, gcc-3.2.1, gdb-5.2.1, gdb-5.3)


[ First steps ]

Choose an installation directory for the compiler and binutils.  Name the 
directory after your version of gcc, so that you can maintain multiple
gcc installations (the L4 build processes generally let you choose a tool
chain by prefix, not postfix).  gcc and binutils will install bin, include, 
lib, and other subdirectories into your install directory.


[ Building bintutils ]

1. Unpack the binutils source.
2. Change into the binutils source directory.
3. If using MacOS X:
   a. Use at least binutils-2.13.2.1, for out-of-the-box compilation.
   b. You must use gcc 3 (sudo gcc_select 3).  gcc 2 will generate bad code in
      ld.
   c. If using an older binutils, modify gas/config/tc-ppc.c, 
      line 5110 (in function md_apply_fix3), and change 
      'valueT value = * valP' to 'unsigned long long value = * valP'.
4. Configure binutils to install its binaries in your chosen install 
   directory, and to support the PowerPC processor:
      ./configure --prefix=${YOUR_INSTALL_DIR} --target=powerpc-elf
5. Execute 'make'
6. If building under MacOS X, you must use gcc 3.  gcc 2 will generate
   bad code.  For older binutils, gcc 3 will fail to compile the whole thing.  
   When it fails, cd into the ld directory, and type make.  Change back to the 
   parent directory.
7. Execute 'make install'


[ Building gcc ]

0. Be sure that binutils is installed in your installation directory; gcc
   will use elements of binutils.
1. Unpack the gcc source.
2. If you use a version compatible with Josh's gcc performance patch,
   then apply the patch.
3. Create a gcc build directory.
4. Change into the gcc build directory.
5. If using MacOS X 10.2, execute 'gcc_select 3'
6. Configure your gcc build:
      ${YOUR_GCC_SOURCE_DIR}/configure --target=powerpc-elf --enable-languages="c,c++,objc" --with-gnu-as --with-gnu-ld --prefix=${YOUR_INSTALL_DIR}
7. Edit the Makefile:
   a. If using MacOS X, append -no-cpp-precomp to CFLAGS
   b. Remove all subdirs from the TARGET_CONFIGDIRS rule
   c. Disable the install-info: rule (you can disable it by renaming it)
8. Add the bin dir of your installation directory to your path, so that 
   the build process can execute tools from your binutils.
9. Run 'make'
10. Run 'make install'


[ Creating the Pistachio Build Environment ]

1. Change into the kernel subdir of the pistachio source tree.
2. Choose a pistachio PowerPC build directory (but don't create it).
3. Run 'make BUILDDIR=${YOUR_PISTACHIO_PPC_BUILD_DIR}'
4. Change into the build directory.
5. Run 'make menuconfig' to configure the kernel:
   a. Under the 'Hardware' menu, select PowerPC as your 'Basic Architecture'.
   b. For the 'Processor Type', probably choose the IBM750.
   c. Enable the kernel debugger.
   d. If you use a stock gcc compiler, and didn't apply Josh's performance
      patch, then under 'Code Generator Options', enable the 'SYSV_ABI' 
      boolean.
6. Step 5 should have generated a Makeconf.local file in your build directory.
   Edit the Makeconf.local file.
   a. If you want to study intermediate files generated by gcc, then
      update CFLAGS:
        CFLAGS += -save-temps
   b. Tell the build system how to find your compiler and binutils.  Add a
      TOOLPREFIX variable:
        TOOLPREFIX=$(YOUR_INSTALLATION_DIRECTORY)/bin/powerpc-elf-
7. Build the kernel: execute 'make'


[ Building psim ]

psim is an integral component of gdb.  psim requires gdb to be built for the 
target powerpc-unknown-eabi.

1. Change into the gdb source directory.
2. Fix the three psim bugs described below.
3. Configure gdb:
      ./configure --enable-sim-powerpc --target=powerpc-unknown-eabi --prefix=${YOUR_GDB_INSTALLATION_DIR}
4. If using MacOS X, edit the toplevel Makefile, and append -no-cpp-precomp
   to the CC=gcc definition.
5. Execute 'make'
6. Execute 'make install'

The default psim has an interrupt delivery bug.  I submitted a
patch to the gdb maintainers.  But as of gdb 5.3, psim still has the bug.
You must patch psim's interrupt delivery mechanism to support SMP and/or device 
simulation.  The culprit file is sim/ppc/interrupts.c and the function is
external_interrupt() located at the bottom of the file.  Replace that function
with:

INLINE_INTERRUPTS\
(void)
external_interrupt(cpu *processor,
                   int is_asserted)
{
  interrupts *ints = cpu_interrupts(processor);
  if (is_asserted) {
    ints->pending_interrupts |= external_interrupt_pending;
    if (cpu_registers(processor)->msr & msr_external_interrupt_enable)
      schedule_hardware_interrupt_delivery(processor);
  }
  else
    ints->pending_interrupts &= ~external_interrupt_pending;
}


Another bug lurks in psim, related to OpenFirmware emulation.  For the
kernel to boot, you must fix the function chirp_emul_nextprop() 
in the file sim/ppc/emul_chirp.c.

Look for the statement: 
    next_prop = device_next_property(prev_prop);

Change to:
    if( *previous == '\0' )
	next_prop = prev_prop;        /* Return the first property! */
    else
	next_prop = device_next_property(prev_prop);


And yet another bug in psim, regarding Open Firmware page hash initialization.
In file sim/ppc/hw_htab.c, function htab_decode_hash_table(), look for:
    if ((htab_ra & INSERTED32(*htabmask, 7, 15)) != 0) {
	device_error(parent, "htaborg 0x%lx not aligned to htabmask 0x%lx",
		(unsigned long)*htaborg, (unsigned long)*htabmask);
    }

and change to:
    if ((htab_ra & (htab_nr_bytes-1)) != 0) {
	device_error(parent, "htaborg 0x%lx not aligned to htabmask 0x%lx",
		(unsigned long)*htaborg, (unsigned long)*htabmask);
    }



[ Running psim ]

Give this a try:
  powerpc-unknown-eabi-run -e chirp -m 604 -f psim.tree ofppc-loader

Where ofppc-loader is the boot loader, a product of the user-level application 
build.  You generally can't directly run the kernel.  The kernel requires 
some degree of initialization from the boot loader.

And where psim.tree contains:
------------ psim.tree -----------------
/#address-cells 1
/openprom/init/register/msr 0x9032
/openprom/options/oea-memory-size 0x4000000
/openprom/options/smp 4
/openprom/options/use-stdio? true
/cpus/cpu@0/clock-frequency 100000000
/cpus/cpu@0/bus-frequency 100000000
/phb@0xf0000000/#address-cells 3
/phb@0xf0000000/#size-cells 2
/phb@0xf0000000/ranges nm0,0,0,f0000000 0xf0000000 0x0f000000
/phb@0xf0000000/device_type pci
/phb/opic@0/reg 0 0 nm0,0,10,f0f00000 0x40000
/phb/opic@0/interrupt-ranges 0 0 0 9
/phb/opic@0/device_type open-pic
/phb/opic@0/timer-frequency 4666667
/phb/opic@0 > intr0 int /cpus/cpu@0
/phb/opic@0 > intr1 int /cpus/cpu@1
/phb/opic@0 > intr2 int /cpus/cpu@2
/phb/opic@0 > intr3 int /cpus/cpu@3
/iobus@0xe0000000/com@0xe0000000/reg 0xe0000000 8
/aliases/com /iobus@0xe0000000/com@0xe0000000
------------ psim.tree -----------------