Skip to content

landley/aboriginal

Repository files navigation

Aboriginal Linux: We cross compile so you don't have to.

===============================================================================
--- What is it?

  Aboriginal Linux provides virtual Linux images you can boot under QEMU,
  within which you can compile and test any software you like.

  The build scripts automatically create cross compilers and bootable system
  images for various targets, such as arm, mips, powerpc, and x86.  You can
  download the resulting binaries from the website if you don't want to bother
  compiling them yourself.

  The system images provide minimal native development environments which you
  can boot under an emulator (or on real hardware if you have it) to compile
  code natively.  This includes a full native compiler (for both C and C++),
  and the (optional) ability to run the cross compiler on the host (via distcc)
  to speed up the build without reqiring the packages you're building to
  know anything about cross compiling.

--- How do I try it out?  (Quick start.)

  - Download a system-image tarball for a target that interests you.

  - Extract it and cd into the directory.

  - Run the "./run-emulator.sh" script.

    After the kernel boot messages and the output of the init script, you
    should get a shell prompt from inside the emulator.

    - Run "cat /proc/cpuinfo" to confirm the emulator is running.

    - Run "gcc -lpthread /usr/src/thread-hello2.c" (and run the resulting
      "./a.out" file) to confirm the native toolchain works.

    - Type "exit" when done.

--- What's this "target/host" business?

  The host is the system the emulator runs on.  The target is the virtual
  system running inside the emulator.

--- Do I have to care about cross compiling?

  No, you don't.  Just boot a system image under QEMU and build packages in
  there (or find some real hardware to boot your root filesystem on, and note
  that the distcc acceleration trick still works in that context too).

===============================================================================
--- What's the purpose of this project?

  Aboriginal Linux serves two purposes: practical and educational.

  The practical purpose is to provide emulated native development environments
  for every target QEMU supports.  This avoids the need for cross compiling
  by allowing you to download a bootable system image and build natively within
  it.

  Aboriginal Linux is also designed to document how to bootstrap minimal
  Linux development environments for a new target.  The build is a series of
  bash scripts, with lots of comments explaining what they do.  These scripts
  show how to make a cross compiler (and optionally how to use it to make
  a better cross compiler), how to build a root filesystem and native
  development tools, and how to package and boot the result under an emulator.
  If you don't know how something works, read the script.  If something's
  unclear, ask about it on the mailing list.

===============================================================================
--- How do I use Aboriginal Linux?

To download prebuilt binaries for each target:

    http://landley.net/aboriginal/downloads/binaries

  The "system-image" tarballs are what you need to boot a virtual target
  under QEMU.  They contain a squashfs root filesystem (including a native
  compiler toolchain), an appropriately configured Linux kernel, and shell
  scripts to invoke the the emulator with appropriate arguments.

  The cross-compiler tarballs are useful for accelerating native builds via
  distcc (using the dev-environment.sh script, explained later in this file).

  If you want to install Aboriginal Linux on real hardware (or set up a
  chroot), the root-filesystem and native-compiler tarballs are probably
  what you want.  (You may need to provide your own kernel and bootloader.)

  Various statically linked binaries are also available for each target
  (busybox, dropbear, strace...) which can be used on any appropriate target,
  not just with Aboriginal Linux.  Just download them (with wget), set the
  executable bit (chmod +x), and run them normally.

To use the build scripts to build your own binaries from source:

  Download the most recent set of build scripts from:

      http://landley.net/hg/aboriginal/archive/tip.tar.bz2

  To list available targets, do:

      ./build.sh

    We'll use "mipsel" (mips little endian) in the following examples.  Replace
    that with the target you're interested in from this list.

  To compile a system image (and all prerequisite stages) for a target:

      ./build.sh mipsel

    This calls the other stages (from download.sh through system-image.sh)
    in order, to produce a bootable system image.  The downloaded source
    tarballs are kept in the "packages" directory, all other output goes into
    the "build" directory.

    For each target, the build tars up the various build stages
    (cross compiler, native compiler, root filesystem, etc).  The last stage
    is a bootable system image configured for use with the emulator QEMU,
    in this case build/system-image-mipsel (with a corresponding tarball
    version for posterity).

  To build every supported target simultaneously (in parallel, using around
  2 gigabytes of ram and maybe 20 gigabytes of disk space):

    FORK=1 sources/more/buildall.sh

  The file "configure" contains several environment variables you can set to
  control the behavior of Aboriginal Linux, and has comments documenting what
  the all doo.  (You can persistently set them by altering this file, or
  set them temporarily in your environment before running a build.)

  For more information, see the README file in the download directory.

    http://landley.net/aboriginal/README

To boot a system image under QEMU:

    cd build/system-image-mipsel
    ./run-emulator.sh

  Each system image contains a root filesystem image (for use as a virtual
  hard drive), a kernel configured for use with QEMU, and a run-emulator.sh
  shell script to boot those two files together under QEMU.

  After the kernel boot messages scroll by, you should have a shell prompt
  inside qemu.  Try "cat /proc/cpuinfo" to confirm it's not the same as your
  host.  Try "cc /usr/src/hello.c" to build some of the included example
  code.  Type "exit" to shut it down.

  The environment variable QEMU_EXTRA can supply extra command line arguments
  to the emulator.  The environment variable KERNEL_EXTRA can supply extra
  command line arguments to the Linux kernel running under the emulator.

To set up a more powerful virtual build environment:

    cd build/system-image-mipsel
    ./dev-environment.sh

  The dev-environment.sh script is a wrapper around run-emulator.sh that does
  two things to give you a better development environment:

  1) Make sure the emulator allocates at least 256 megs of physical memory.

     Set the environment variable QEMU_MEMORY to the desired number of
     megabytes if you'd like more.  (Note that some targets can't support more
     than this, in which case the emulator will print out an error message
     instead of launching the virtual system.)

  2) Mount lots of writeable space on /home in the virtual system.

     The script creates a 2 gigabyte sparse file on the host named hdb.img,
     formats it ext3, and tells the emulator to mount it on /home.

     This keeps the existing hdb.img if it already exists, so its contents
     persist between dev-environment.sh invocations.  If you need more space
     than 2 gigabytes, you can supply your own hdb.img.

  2) Hook up distcc to call out to the cross compiler on the host, to speed
     up your builds by moving the heavy lifting of compilation outside the
     emulator.

     This only happens if you have both distccd and the appropriate cross
     compiler is in your host system's $PATH.  (Install distcc on the host,
     and downloaded the appropriate cross compiler tarball and add its "bin"
     subdirectory to your $PATH).  If both are available, the script launches
     a private instance of distccd and configures the virtual system to use
     distcc to call out to the cross compiler.

     The reason this doesn't re-introduce the complexity of cross compiling is
     because the build still only has a single context, and thus behaves like
     a fully native build.  Configure, make, preprocessing, and linking all
     still run natively inside the emulator.  Using distcc means the build
     sends preprocessed source out through the network and gets compiled .o
     files back, but it neither knows nor cares whether the servers it's
     connecting to are cross compiling or native compiling, as long as they
     produce the right output.

To automatically build more software packages inside the emulator:

    ./native-build.sh mipsel hello-world.hdc output_dir

  Aboriginal Linux supports automated builds via a two stage process.
  Get a control image, then launch a system image with it.

  1) Obtain a control image.

     The scripts in sources/native-build (such as hello-world.sh and
     static-tools.sh) create build control filesystem images.  For example,

       sources/native-build/hello-world.sh hello-world.hdc

     These are squashfs formatted filesystem images that contain extracted
     source code, plus a shell script to build that code and upload it to
     the host (via ftp).

     You're encouraged to create your own control images using the existing
     native-build scripts as a model.  The images the existing scripts create
     are available in the downloads/binaries directory.

  2) Use native-build.sh to launch that control image under the emulator.

     This is another wrapper script, this time around dev-environment.sh
     (which is in turn a wrapper script around run-emulator.sh).

     This wrapper does two things:

     1) Launch an ftp daemon, and inform the virtual system where to find it
        via the FTP_HOST and FTP_PORT environment variables.  This lets the
        emulated target system upload files to the host via "ftpput".

        Launching an FTP daemon requires busybox in the $PATH on the host, and
        uses the busybox nc and ftpd applets to provide an ftp server.  (We
        can't use an arbitrary one on the host because different ftp daemons
        understand different command line options.)

        You can set the environment variables $FTP_HOST and $FTP_PORT to point
        it at an existing FTP daemon.  If either variable is set, the script
        won't launch a new FTP daemon.  (Note that the default value for
        $FTP_HOST is 10.0.2.2, which is QEMU's tunnel through to the host
        system's 127.0.0.1.)

     2) Launch the emulated development environment with a control image, to
        be mounted on /mnt by the init script.

        Basically this adds "-hdc filename" to the QEMU_EXTRA environment
        variable to supply a third virtual disk to the emulator, then calls
        ./dev-environment.sh as normal.

        The Aboriginal Linux init script (sbin/init.sh) checks for the
        existence of /mnt/init, and runs that if it exists instead of
        providing an interactive shell prompt.  (It waits three seconds for
        you to press a key if you do want a shell prompt, in which case you
        can launch /mnt/init yourself when you're done.)

        When /mnt/init exits, the virtual system shuts down and exits the
        emulator, just like typing "exit" at the interactive shell prompt.

To cross compile stuff on the host:

  If you already do cross compiling, and would like to use this project's cross
  compiler to build something else, just add its "bin" subdirectory to the
  $PATH, and use the build tools prefixed with the target name:

    PATH=$(pwd)/build/cross-compiler-mipsel/bin:$PATH
    mipsel-gcc -static hello.c -o hello
    qemu-mipsel hello

  If you don't do cross compiling already, this project isn't going to teach
  you how, and in fact recommends you just don't go there.  We cross compile
  so you don't have to.