Alex's Alliterative Adventures

Thoughts on Programming, Life, and Travel

Making an ELF in a bochs

My partner and I just spent far too many hours getting the toolchain for Waterloo’s CS452 (Real-Time Programming, aka the trains course) working on Linux. A few tears and a lot of grumbling later, we’re compiling like a bat out of hell, running bochs natively, and posting to the Eos remotely. Here’s how we did it:

Compiler
1) Using your package manager, install the “flex” and “bison” packages. (We’re not sure about this step, but it can’t hurt)

2) If you don’t already have it, use your package manager to download and install gcc 3.x. (We couldn’t compile everything with gcc 4.x) You’ll also need libc6-dev.

3) Download the following 3 files from some random website (try google):
binutils-2.14.90.0.8.tar.bz2
newlib-1.12.0.tar.gz
gcc-3.3.3.tar.bz2 (We used 3.3.3 instead of the recommended 3.3.4, since the school machines run 3.3.3)

4) Open up a terminal window and set the CC environment variable to point to gcc 3.x (which you just installed)

5) Use gcc 3.x to follow the steps at the course toolchain setup guide.

Bochs
1) Download the bochs source, bochs-2.3.tar.gz

2) Download X Windows libraries, xorg-dev

3) Configure bochs with whatever options you want.
If you want your installation to match the school’s, this is my current best guess:
./configure --enable-debugger --enable-disasm --enable-apic --enable-cpu-level=6 --enable-sse=2 --enable-sep --enable-guest2host-tlb --enable-repeat-speedups --enable-icache --enable-fast-function-calls --enable-ne2000 --enable-vbe --enable-usb --enable-pci --enable-readline --enable-show-ips
(I did this on a fresh ubuntu install, so I had to grab a copy of g++ to do this)

4) Compile bochs.

5) Modify 452mkemu and 452postemu so all of the directories are pointing to the right place on your machine. Our files now set different directories based on whether you’re running linux and which user is logged in. You’ll also need to copy any files these scripts reference (like grub.img, or the bochs BIOS) to your machine somewhere and point the scripts at them
EDIT June 13 14:58: After wasting a lot of time, we figured that bochs would start panicking once we checked our BIOS into CVS. This was, of course, because CVS decided that our BIOS was too big, and it graciously decided to take off two bytes for us. Solution: they’re not in CVS anymore! Thanks, CVS.

5) Run 452mkemu. You’ll need to change any directories in the file to match your machine’s setup, and you’ll also need to install mtools.

6) Emulate to your heart’s content. If you get a message saying that menu.lst is not found, just rebuild your kernel.

Symbolic debugging
I can’t stress enough how useful the bochs debugger becomes once you get symbolic debugging working.
We followed the instructions to generate a symbol file for bochs,  and now our makefile generates a bochs symbols file whenever it posts. I had to install gawk to make this work on linux. Here’s the secret ingredient:
nm -n $1 | grep -v '\( [aUw] \)\|\(__crc_\)\|\( \$[adt]\)' | awk '{print $1, $3}' > $2

Posting
The 452post script needs to lock a file on the school servers, and since my Linux-fu is weak, I don’t know how to make that happen remotely. I do know how to copy files to the school servers, though, and execute commands remotely. A few lines of script later, your linux install will post to the Eos machines.

Eclipse
That’s right, I went there. Sort of. Earlier today I set up an eclipse CDT project that compiled our code, start to finish. There were a few hitches: Eclipse thought that having to generate dependency files was a critical error. There were a few other similar snags. I hope we’ll be able to get it working soon so we  have a real IDE to code in, but it can still be a useful tool as a souped up text editor and CVS GUI.
EDIT June 13 15:33: Eclipse works. It’s beautiful.

The only thing that’s even mildly annoying with this whole process is that with my current setup, I’m prompted to enter my password every time I connect to the school machines, which happens 5 times when I post. If the rumours are true, I can tell SSH to connect with a stored key instead of a prompted password, which will be icing on the sweet, sweet cake.
EDIT June 13 11:41: I don’t have to enter my password anymore.

If there are more cool tricks to make coding a kernel a little bit easier, please leave a comment.

11 comments

11 Comments so far

  1. Alexei Karpenko June 15th, 2008 1:34 am

    Hey Alex,

    Thank you for making those instructions! It makes compiling indeed much faster. Not sure Bill is going to like us using a debugger though 😛

    Here is a simple 452post script for your local computer:
    ——————
    #!/bin/bash

    REMOTEHOST=fe06-solaris.student.cs.uwaterloo.ca
    USERNAME=your_username_here

    # Read arguments
    TITLE=$1
    shift
    KERNEL=$1
    shift

    # Transfer with compression (seems faster)
    tar -cjf post.tar.bz2 $KERNEL $*
    scp post.tar.bz2 $USERNAME@$REMOTEHOST:cs452/post/

    # Post on remote server
    ssh $REMOTEHOST -l $USERNAME cd cs452/post \&\& tar -xjf post.tar.bz2 \&\& 452post $TITLE $KERNEL $*
    ——————

    Just make sure that you create a cs452/post/ folder on your UW account.

    Later,
    Alexei

  2. Alex June 15th, 2008 2:45 pm

    We were just straight-up copying our files without compression, so I tried adding some tar magic to our special sauce. When posting 4 modules to the servers, we averaged around 2.7s without compression, and something like 3.1s with :O A cool experiment, though. I wonder if the balance will shift when we start uploading more modules?

  3. Alexei Karpenko June 15th, 2008 3:14 pm

    Hmm, perhaps. Your connection speed is probably a factor too. With my connection (Rogers Hi-Speed, heh…), compressed is faster by about 3 seconds.

    It would be nice to combine scp and ssh into one single ssh call so that the connection isn’t established and reestablished twice. But my Linux Fu is not strong enough 🙁

  4. Alex June 15th, 2008 3:22 pm

    That would definitely do it. I’m working from the labs, and I’m plugged in at something like 1GB/s 😛

    Yeah, my thoughts exactly. I’m really new to linux too. I wonder if it’s possible to have an always-open ssh session in the background… I also read something something about mount a remote directory as a drive that might speed up the scp. I guess that I have something to play with once we hand in this assignment 😉

    Are you using eclipse? It’s like living in the lap of luxury..

  5. Alexei Karpenko June 15th, 2008 7:07 pm

    Yes, I have remote directory set up, it’s pretty nice to work with remote files. It might be faster to use that, so I should give it a try. A friend told me also that “rsync -e ssh” is faster than scp in his experience, so that might be also worth considering.

    As for IDE, I have been using GEdit but might try Anjuta soon. My computer is pretty slow with Eclipse, unfortunately…

  6. […] at 1Gbit in the labs, so bandwidth isn’t the bottleneck. I followed Alexei’s lead and compressed our files: tar -cjf files.tar.bz2 $FILES scp files.tar.bz2 $LOGIN@$SERVER ssh $LOGIN@$SERVER tar -xjf […]

  7. Denver Gingerich June 25th, 2008 7:54 pm

    The reason you couldn’t compile everything with GCC 4 is likely that you need to update your Makefile to use new library paths. I described how to update these paths in a past uw.cs.cs452 newsgroup post:

    http://groups.google.com/group/uw.cs.cs452/browse_thread/thread/5dab31bbcd7df344/6fe6e79853215517

    Unfortunately, the course staff haven’t updated the cross-compilation page yet. If someone wishes get it updated, I suggest pestering the course staff every once in a while until it’s done.

    It would be nice if someone could confirm that this works with the latest GCC (currently 4.3.1). I would suggest using the latest versions of all the tools, but I suppose if you don’t want to deal with any unforeseen compile problems when you switch back to the school servers, then you’d want to use the versions they use. In practice, such compile problems almost never occur.

  8. Alex June 26th, 2008 12:58 am

    Thanks for the tip, Denver. Consider the course staff to be officially pestered.

    Out of curiosity, what brings your advice to this doorstep?

  9. Denver Gingerich June 26th, 2008 8:32 am

    I saw your post on uw.cs.cs452, read this blog post, and then remembered that I had run into this problem before and fixed it. I regularly read uw.cs.cs452 to see if there are any problems people are running into that I’ve seen before so I can help them out.

    With CS 452, a lot of time can be spent seeking out the information needed to do a particular thing (like implementing a PS/2 mouse driver, for example). Spending time finding these things does not seem useful, especially when it’s been found before and it’s not integral to the point of the course. So if I can make this information available (since I found it in the past, for example) then it will make the lives of future CS 452 students much less painful.

    By the way, you should add OpenID support to your blog. Among other things, this would allow you to let OpenID-authenticated users post without moderation.

  10. Simon July 5th, 2008 10:25 pm

    I would rather run everything locally so that a computer without Internet connection (or extremely slow connection in my case) can still work. So I have created a script for mounting the floppy image, copying the modules and kernel, recreating grub’s menu.lst, and umounting the floppy. It uses sudo as I couldn’t figure out how to mount arbitary image file as users.

    ———————————————————
    #!/bin/bash
    sudo modprobe loop
    sudo mount -o loop otherfloppy.img /mnt/floppy
    EMUDIR=/mnt/floppy
    MENU=$EMUDIR/grub/menu.lst

    if [ -e $MENU ] ; then
    rm $MENU || exit 1
    fi

    if [ ! -e $MENU ] ; then
    touch $MENU
    fi

    TITLE=”$1″
    shift

    if [ “x$TITLE” = x ] ; then
    echo “Usage: $0 title kernel [modules]”
    exit 1
    fi

    gawk ‘BEGIN { inside = 0; } /^title ‘”$TITLE”‘$/ { inside = 1; next } /^title / { inside = 0; } { if (!inside) print; }’ $MENU.tmp
    mv $MENU.tmp $MENU

    KERNEL=”$1″
    shift
    if [ “x$KERNEL” = x ] ; then
    echo “Usage: $0 title kernel [modules]”
    exit 1
    fi

    if [ ! -e “$KERNEL” ] ; then
    echo “Kernel $KERNEL does not exist. Aborting”
    exit 1
    fi

    cp $KERNEL $EMUDIR
    KERNEL=`basename “$KERNEL”`

    if [ -e $MENU.prepend ] ; then rm $MENU.prepend ; fi
    echo “title $TITLE” >> $MENU.prepend
    echo “root (fd0)” >> $MENU.prepend
    echo “kernel /$KERNEL” >> $MENU.prepend

    MODULE=”$1″
    shift
    while [ “x$MODULE” != x ]; do
    if [ ! -e “$MODULE” ] ; then
    echo “Module $MODULE does not exist. Aborting”
    exit 1
    fi
    cp $MODULE $EMUDIR
    MODULE=`basename “$MODULE”`
    echo “module /$MODULE” >> $MENU.prepend
    MODULE=”$1″
    shift
    done

    cat $MENU >> $MENU.prepend
    mv $MENU.prepend $MENU
    sudo umount /mnt/floppy

    ——————————————————-
    I resized the file image as it is too small.

    $ resize2fs otherfloppy.img 2M

  11. Alex July 5th, 2008 11:53 pm

    If you just use the script that posts to the emulator, don’t run the script that posts to the school machines, copy over the bios/floppy images/etc (once!), and run the 452mkemu script (once!) on your machine, I think that you shouldn’t need an internet connection to work.

    Also, if you’re playing around with bochs on your home machine, you can boost the IPS (instructions per second) in the 452mkemu script to make bochs a lot snappier

Leave a reply

*