|  | GETTING_STARTED | 
|  | Barret Rhoden | 
|  |  | 
|  | Last thorough update: 2013-02-07 | 
|  |  | 
|  |  | 
|  | 1. Overview | 
|  | --------------------- | 
|  | In this document, I outline what steps I go through to set up my development | 
|  | environment.  Some devs use other setups, and they can put sections farther | 
|  | down in this document describing their steps. | 
|  |  | 
|  | Due to the nature of different workflows and different Linux distros, you'll | 
|  | need to do some configuration of your environment.  Things won't magically work | 
|  | out of the box. | 
|  |  | 
|  |  | 
|  | 2. Need help? | 
|  | --------------------- | 
|  | First off, if you get stuck, email someone.  You can join our mailing list by | 
|  | sending an email to akaros-request@lists.eecs.berkeley.edu.  Send your messages | 
|  | to akaros@lists.eecs.berkeley.edu.  Or just email me (brho@cs), though the | 
|  | mailing list is a more scalable method in the long run. | 
|  |  | 
|  | Alternatively, you can poke your head in #akaros on irc.freenode.net.  I'm | 
|  | usually idling in there (alone), and if I'm at my computer, I'll respond. | 
|  |  | 
|  |  | 
|  | 3. From Download to Hello World | 
|  | --------------------- | 
|  | I'll describe how to get x86 working.  RISCV is similar. | 
|  |  | 
|  | The first step is to configure the kernel.  config, menuconfig, and some of the | 
|  | other KBuild targets work.  Defconfig gives you a default configuration.  For | 
|  | example, to config for 64-bit x86: | 
|  |  | 
|  | $ make ARCH=x86 defconfig | 
|  |  | 
|  | Alternatively, you can run menuconfig to customize what settings you want: | 
|  |  | 
|  | $ make ARCH=x86 menuconfig | 
|  |  | 
|  | For x86, you can choose between 32 and 64 bit when you make menuconfig.  This | 
|  | selection must match your cross compiler make command.  The default is 64 bit. | 
|  |  | 
|  | There are a lot of other settings when you make config, and you should browse | 
|  | through to decide what you want to enable/disable. | 
|  |  | 
|  | Most everyone wants KFS turned on (Filesystems --> KFS filesystem).  This is | 
|  | the in-memory filesystem that the kernel uses.  The kernel build scripts will | 
|  | look at the "KFS/Initramfs paths" string and take any of those directories and | 
|  | add them to a CPIO archive that will eventually become the root filesystem when | 
|  | Akaros runs. These settings are set by default when you do a 'make defconfig'. | 
|  |  | 
|  | There are also settings for ext2.  If you turn on ext2 support, you need to | 
|  | point to an img file that has been formatted with ext2 and has files in it.  If | 
|  | you aren't messing with filesystems at all, feel free to ignore this.  It's an | 
|  | in-memory filesystem, like KFS (linked to the end of the kernel), so you won't | 
|  | gain much by using it for now. | 
|  |  | 
|  | 3.1 Cross compiler (and glibc) | 
|  | ---------- | 
|  | The second step is to build the cross compiler, which lives in | 
|  | tools/compilers/gcc-glibc | 
|  |  | 
|  | $ cd tools/compilers/gcc-glibc | 
|  |  | 
|  | In this directory, you first need to set up your Makelocal file.  There is a | 
|  | template to work from. | 
|  |  | 
|  | $ cp Makelocal.template Makelocal | 
|  |  | 
|  | You need to set your INSTDIRS to some place where you want the cross compiler | 
|  | installed.  I have a directory named ros-gcc-glibc for this. | 
|  |  | 
|  | You also need to add bin directories to your PATH where the cross compiler will | 
|  | be installed.  This will vary based on your value for INSTDIRS.  For instance, | 
|  | my path contains: | 
|  |  | 
|  | /home/brho/classes/ros/ros-gcc-glibc/install-x86_64-ros-gcc/bin | 
|  |  | 
|  | You can also set up MAKE_JOBS, so you don't over or under load your system when | 
|  | building.  I have a 2 core laptop, so I use MAKE_JOBS := 3 | 
|  |  | 
|  | At this point, you can build (for example): | 
|  |  | 
|  | $ make x86_64 | 
|  |  | 
|  | This might take a while (10-20 minutes for me on a 2007 era laptop). | 
|  |  | 
|  | Just to double check everything installed correctly, you should be able to run | 
|  | x86_64-ros-gcc from your shell. | 
|  |  | 
|  | Now, you have a cross compiler ready, and you can start to build Akaros. | 
|  |  | 
|  | 3.2 Kernel | 
|  | ---------- | 
|  | cd back into the repo root. | 
|  |  | 
|  | Like the cross compiler, the kernel has its own Makelocal. | 
|  |  | 
|  | $ cp Makelocal.template Makelocal | 
|  |  | 
|  | This file is used to set up custom make targets that are not part of the | 
|  | default Makefile, but fit nicely into your personal workflow. This file is not | 
|  | under version control and can me made to contain just about anything. | 
|  |  | 
|  | Now you're ready to build the kernel: | 
|  |  | 
|  | $ make | 
|  |  | 
|  | So the kernel built, but you can't do much with it, and you probably have no | 
|  | programs. | 
|  |  | 
|  | Notice that we didn't have to set the ARCH variable this time.  The make system | 
|  | knows what architecture we are set up for and will always build for that | 
|  | architecture until a new ARCh is selected (i.e. via 'make ARCH=xxx defconfig' | 
|  | etc.) | 
|  |  | 
|  | 3.3 Userspace | 
|  | --------- | 
|  | To build userspace and test programs: | 
|  |  | 
|  | $ make tests | 
|  |  | 
|  | You now have programs and libraries, and need to put them in KFS.  To do this, | 
|  | we provide a 'fill-kfs' make target. | 
|  |  | 
|  | $ make fill-kfs | 
|  |  | 
|  | The 'fill-kfs' target copies your cross compiler's shared libraries and all | 
|  | test binaries into the first "KFS/Initramfs path" you set during configuration | 
|  | (or kern/kfs/lib if you just kept the default). | 
|  |  | 
|  | Now that you've changed the contents of KFS's source, remake the kernel.  You | 
|  | should see something like | 
|  | Building initramfs: | 
|  | Adding kern/kfs to initramfs... | 
|  | before the kernel links.  If you don't see this, then you probably didn't | 
|  | actually fill KFS properly. | 
|  |  | 
|  | 3.4 Busybox | 
|  | --------- | 
|  | Busybox provides our shell and some basic utilities.  You almost certainly want | 
|  | to build and install busybox. | 
|  |  | 
|  | Userspace programs like busybox need to be compiled with the cross compiler and | 
|  | then have their binaries copied to kern/kfs/bin.  Since most everyone wants | 
|  | busybox and we have a few patches of our own, we have support for automatically | 
|  | building and installing it to KFS. | 
|  |  | 
|  | For the default build (x86_64): | 
|  |  | 
|  | $ cd tools/apps/busybox | 
|  | $ make [x86_64|riscv] | 
|  | $ cd - | 
|  |  | 
|  | And you should be set.  Check kfs to make sure everything installed.  You | 
|  | should get sane results from: | 
|  |  | 
|  | $ ls -l kern/kfs/bin | grep cat | 
|  | lrwxrwxrwx 1 brho brho       7 Jan 23 09:19 cat -> busybox | 
|  |  | 
|  | You can customize your busybox installation, including the install prefix, the | 
|  | .config file, and make jobs.  Check out the makefile in tools/apps/busybox for | 
|  | details. | 
|  |  | 
|  | Now that you've changed KFS, don't forget to remake the kernel. | 
|  |  | 
|  | 3.5 Building and Loading a Virtual Machine Image | 
|  | --------- | 
|  | At this point, you probably have a runnable kernel with programs in KFS.  It | 
|  | should be sitting at obj/kernel/akaros-kernel.  When running in a VM, you can | 
|  | either run the kernel directly from qemu, or put it in a virtual machine image | 
|  | file. | 
|  |  | 
|  | If you don't want to bother with the image, skip this section.  I tend to run | 
|  | my images off an image file, since qemu acts more like hardware (as far as | 
|  | multiboot goes).  The downside is the boot up is slower, especially if you have | 
|  | a large kernel (>100MB).  It also takes some effort to set up the VM image. | 
|  |  | 
|  | If you are still reading, you'll need an image file that looks like a hard disk | 
|  | to boot qemu off of.  I put one similar to mine at: | 
|  | http://akaros.cs.berkeley.edu/files/hdd268mb.img | 
|  |  | 
|  | It's around 268MB (256MiB, or whatever).  If you want to make your own, check | 
|  | out Documentation/howtos/make-bootable-grub-hdd.txt.  That's actually the | 
|  | original document I made back when I first figured it out back in 2009, which | 
|  | has been updated again in 2013.    In between, I wrote it up online at | 
|  | http://www.omninerd.com/articles/Installing_GRUB_on_a_Hard_Disk_Image_File, | 
|  | which has some other tidbits in the comments.  Both methods still use grub1. | 
|  |  | 
|  | Anyway, I put that img in AKAROS-ROOT/mnt/, and make a folder next to it: | 
|  | AKAROS-ROOT/mnt/hdd.  mnt/hdd is the mount point where I mount hdd.img (Note I | 
|  | don't call it hdd64mb.img on my dev machine). | 
|  |  | 
|  | Personally, I always have hdd.img mounted.  Some of the other devs have make | 
|  | targets that mount and umount it.  Whenever I reboot my development machine, I | 
|  | run a script (as root) that mounts the image file and sets up a few things for | 
|  | networking.  I put a script I use for this in scripts/kvm-up.sh.  You'll likely | 
|  | want to copy it to the directory *above* the akaros root directory and edit it | 
|  | accordingly. Feel free to comment out the networking stuff.  That's for using | 
|  | networking in qemu. | 
|  |  | 
|  | Now that your image file is mounted at mnt/hdd, you'll want to copy your | 
|  | freshly built kernel to the root of the image.  I have a make target in my | 
|  | makelocal for this, so that whenever I do a make kvm, it builds the kernel and | 
|  | copies it to my hdd.img. | 
|  |  | 
|  | I added edited versions of my KVM (and USB) make targets to the | 
|  | Makelocal.template.  Uncomment the KVM one (at least). | 
|  |  | 
|  | Incidentally, I also have the following in my Makelocal, so that make (and make | 
|  | all) also make kvm: | 
|  |  | 
|  | all: kvm | 
|  |  | 
|  | Now, make kvm.  You should be able to see the new kernel in mnt/hdd/ (do an ls | 
|  | -l and check the timestamp). | 
|  |  | 
|  | 3.6 Running Qemu | 
|  | --------- | 
|  | Here is the command I use to run qemu/kvm.  It's evolved over the years, and it | 
|  | will vary based on your linux distribution.  Don't run it just yet: | 
|  |  | 
|  | $ qemu-system-i386 -s -enable-kvm -cpu phenom -smp 8 -m 2048 -nographic -monitor /dev/pts/3 -net nic,model=e1000 -net tap,ifname=tap0,script=no mnt/hdd.img | 
|  |  | 
|  | If you skipped making a virtual machine image, replace "mnt/hdd.img" with | 
|  | "-kernel obj/kern/akaros-kernel". | 
|  |  | 
|  | The -monitor is the qemu monitor, which is a CLI for qemu.  Pick a | 
|  | tab/terminal/pty in Linux that you will only use for qemu monitoring, and enter | 
|  | 'tty'.  Whatever it tells you, put in place of /dev/pts/3.  I've been using the | 
|  | same tab for about 4 years now.  In that tab, enter 'sleep 999999999'.  Qemu | 
|  | will still access it, but you won't have to worry about bash trying to handle | 
|  | your inputs. | 
|  |  | 
|  | -nographic allows qemu to work in the terminal you run qemu from, instead of | 
|  | spawning off a fake cpu crt/monitor. | 
|  |  | 
|  | If you don't have networking set up (including the tun/tap stuff from | 
|  | kvm-up.sh), remove the -net commands/options. | 
|  |  | 
|  | Fell free to pick different values for the number of cpus and RAM (8 and 1024 | 
|  | in the example). | 
|  |  | 
|  | Once you finally run it, you can stop the VM by entering 'q' to the qemu | 
|  | monitor (or just killing the process)..  Other help commands from the monitor | 
|  | include 'info cpus', 'info registers', 'x', and 'help'. | 
|  |  | 
|  |  | 
|  | 3.7 Running on Hardware | 
|  | --------- | 
|  | I have a few bootable USB sticks with grub set up to run Akaros.  The make usb | 
|  | target (example in Makelocal.template) will copy freshly made kernels to your | 
|  | USB device.  You'll need to adjust those paths according to your distro.  My | 
|  | usb sticks are usually /dev/sdc, for instance (some odd USB device in the last | 
|  | couple of years has taken over /dev/sdb.  Probably something to do with udev | 
|  | changing over the years). | 
|  |  | 
|  | Anyway, you'll need to mess around a bit to get that working.  Or I can dd one | 
|  | for you (I have 4GB disks in my office that I use).  If you make your own, the | 
|  | critical part is getting grub to pick the right device (from what I remember), | 
|  | and its fairly similar to installing grub on any old hard drive (since it's | 
|  | just a bloc device).  Much easier than a hard disk image file. | 
|  |  | 
|  |  | 
|  | 3.8 Hello World | 
|  | --------- | 
|  | So now you can run the kernel.  It's time to edit a program (or make your own). | 
|  | In this, I'll go through my workflow for making changes. | 
|  |  | 
|  | $ vi tests/hello.c | 
|  | (edit, save) | 
|  |  | 
|  | $ make tests | 
|  | (new version in obj/tests/hello) | 
|  |  | 
|  | $ make fill-kfs | 
|  | (updates kfs) | 
|  |  | 
|  | $ make | 
|  | (rebuilds kernel with the new KFS) | 
|  |  | 
|  | $ qemu... | 
|  |  | 
|  | (following commands are in Akaros) | 
|  | Shift-G (to get to the kernel monitor) | 
|  |  | 
|  | ROS(Core 0)> bb (to run busybox) | 
|  |  | 
|  | / $ hello | 
|  | (Should print your message) | 
|  |  | 
|  |  | 
|  | 3.9 Other Dev Workflow stuff | 
|  | --------- | 
|  | One thing to note is that while we use dynamic linking for libc, parlib | 
|  | libraries are statically linked with applications.  In fact, nowadays *all* | 
|  | Akaros programs need to be linked againt parlib (used to be that single-core | 
|  | processes (SCPs) didn't need it). | 
|  |  | 
|  | The makefiles won't notice if you change a file in parlib and then remake a | 
|  | binary.  So if you edit user/parlib/uthread.c for example, tests/pthread_test | 
|  | won't get rebuilt.  Here's what I do: | 
|  |  | 
|  | $ vi user/parlib/uthread.c (make awesome change) | 
|  |  | 
|  | $ touch tests/pthread_test.c ; make tests | 
|  |  | 
|  | This will force the rebuild of pthread_test.  Older, untouched binaries (e.g. | 
|  | block_test), won't get rebuilt.  I actually want this in some cases (different | 
|  | versions of parlib when I'm running certain tests).  Anyway, just pay attention | 
|  | to what you're building.  There's not much output in the console, so you should | 
|  | be able to see what's going on all the time.  (unlike when building glibc...). | 
|  |  | 
|  | Oh, and don't forget to: | 
|  |  | 
|  | $ make fill-kfs | 
|  |  | 
|  | to make sure you run the new pthread_test. | 
|  |  | 
|  | Additionally, when switching between 32 and 64 bit x86, make objclean before | 
|  | filling KFS.  This is the easiest way to make sure you get the appropriate | 
|  | libraries loaded in KFS. | 
|  |  | 
|  | Early on as a dev, there are lots of times where you accidentally don't run the | 
|  | right program (or kernel) and won't understand why your change isn't happening. | 
|  | A few printk("WTF\n")'s later, you realize you didn't have the hdd.img mounted, | 
|  | or you didn't fill KFS, or you didn't relink your binaries, or you forgot to | 
|  | save all files in vi (and not just the current buffer).  But after doing a | 
|  | couple hello worlds, you're set. | 
|  |  | 
|  | Alternatively, you could have a make target to run qemu, which also touches all | 
|  | binaries (or otherwise enforces a rebuild), auto-fills KFS, remakes the kernel, | 
|  | and mounts/copies/unmounts your hdd.img.  Kevin's sim repo has stuff like this, | 
|  | so check it out if that's what you're into.  (I think it is at | 
|  | http://akaros.cs.berkeley.edu/ros-sim.tar.gz).  Personally, I'm not that into | 
|  | it, since I like to keep track of what is going on under the hood, esp if I | 
|  | want to do something a little differently (like with testing ext2, having | 
|  | different versions of parlib with some binaries, or being picky about my | 
|  | mount/umounts). | 
|  |  | 
|  |  | 
|  | 4. RISCV | 
|  | --------------------- | 
|  | TODO. | 
|  |  | 
|  | For now, you need a 64 bit distro to build the RISCV stuff, so I don't do it | 
|  | very often.  I'll eventually sync up with Andrew and we'll get this part sorted | 
|  | out. | 
|  |  | 
|  |  | 
|  | 5. Other Developer's Stuff | 
|  | --------------------- |