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 comments11 Comments so far
Leave a reply
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
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?
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 🙁
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..
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…
[…] 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 […]
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.
Thanks for the tip, Denver. Consider the course staff to be officially pestered.
Out of curiosity, what brings your advice to this doorstep?
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.
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
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