The VirtualBox Homepage
has more information about virtualbox and about using virtualbox.
You will store the virtualbox machine image and the Linux kernel source
code in a subdirectory in
/local on your assigned machine.
Even though you can only run virtualbox on the machine on which
you are assigned (since it is the only one, and should be the only one, with
your virtualbox machine in
/local), you can ssh into your CS lab
machine from any other CS lab machine (or anywhere else) and run
For example, if the PC's name is ginger, then you would type the following to connect (-X enables X forwarding, use -Y if ssh'ing from MAC-OSX):
ssh -X your_account_name@gingerThe
-Xoption enables X forwarding in a secure way.
If you ssh in from outside cs, I'd recommend running virtualbox in non-gui mode and not doing X forwarding, as it can be very slow.
% ssh -X cs45X@ginger
/localthat you and your partner will share. For example, if my working_dir is named tia_n_pal:
% mkdir /local/tia_n_pal % chmod 700 /local/tia_n_pal
% cp -r /scratch/vm/ubuntu-12.04.3-NOINITRD /local/tia_n_pal/.
% ssh -X cs45X@ginger
$ cd /local/you_n_partner/ $ virtualbox (ignore the "Error opening file for reading: Permission denied" error)
The starting point .vbox VM contains a single linux kernel to boot. As you add more kernels, you can select the particular kernel you want to boot from the grub menu using the arrow keys and Enter.
$ screen # start a screen session $ vboxheadless -s "ubuntu-12.04.3-NOINITRD" # run virtualbox in non-gui mode Cntrl-a d # detach from the screen session (machine keeps running)note: this will always boot the default kernel (specified in the grub menu) (and it takes about 1 minute to boot). If the default kernel is not the one you want to boot, you can change the default kernel:
(1) in /etc/default/grub, set GRUB_DEFAULT to the number kernel entry you want: GRUB_DEFAULT=0 # the default kernel is the one in entry 0 # change it to be the entry you want as the default (0,1,2,...) you can list the kernels in which entry: grep menuentry /boot/grub/grub.cfg (2) then run: sudo update-grub
After the kernel boots in your VM you can log into the console window. However, it will be easier to work on your virtual machine by ssh'ing into it. To do this specify port number 10022 and the CSmachine on which you are running virtualbox. There is one user account (swatcs) with the starting point VM, its password (swatcs.45):
ssh -p 10022 swatcs@ginger
The virtualbox image is set up with a single user account:
swatcs. The password is
You can change any of your user account passwords, by running the
passwd command. You can also add new users to the system
$ sudo sync $ sudo sync $ sudo halt -p # halt and power downTo reboot your kernel:
$ sudo sync $ sudo sync $ sudo reboot
Getting a copy of the Linux Source
These steps only need to be done once (or whenever you want to grab
a fresh copy of the code):
$ cp /local/vm/linux-18.104.22.168.tar.bz2 /local/you_n_partner/.
$ cd /local/you_n_partner $ tar xjf linux-22.214.171.124.tar.bz2
$ cd linux-126.96.36.199 $ cp /scratch/vm/config-noinitrd .config $ make menuconfig # just choose Exit with the arrow keys
export CONCURRENCY_LEVEL=4 # anything higher than 4 doesn't help
# NOTE: make-kpkg clean wipes out everything that has been compiled before. # For the very first build you need to do this step, but for subsequent # builds you may want to not do it, and only if package builds are # failing in odd ways try doing a make-kpkg clean to re-build # everything from scratch ("from scratch" takes ~5 minutes) $ cd /local/you_n_partner/linux-188.8.131.52 $ fakeroot make-kpkg clean
# NOTE: in the linux .config file is a variable that is set to # append a local name to your kernel version (in this example # it is set to "-lab3", you can change this in the .config file # for other lab assignment builds # CONFIG_LOCALVERSION="-lab3" # Anytime you change .config, you need to re-run make menuconfig # # (a clean build will take about 5 minutes): $ fakeroot make-kpkg --revision=1.0 kernel_image # if you add new kernel header files, or change existing ones, you need # to build a kernel headers package that contains your changed files too: $ fakeroot make-kpkg --revision=1.0 kernel_headersmake-kpkg creates files named:
../linux-image-184.108.40.206-lab3_1.0_amd64.deb ../linux-headers-220.127.116.11-lab3_1.0_amd64.debYou also can list both kernel_image and kernel_headers in a single make-kpkg command line.
$ fakeroot make-kpkg --revision=1.0 kernel_image kernel_headers
# To remove a previous version of an installed package, on your VM dpkg -r linux-image-18.104.22.168-lab3
export CONCURRENCY_LEVEL=4 # anything higher than 4 doesn't help
From the top-level linux source directory (cd /local/you_n_partner/linux-22.214.171.124), do:
make bzImageIf the build is failing in odd ways (not due to errors in files you have changed), then you can try doing a make clean (and make dep) and try make bzImage again. However, it may be easier to do an Option 1 rebuild at this point.
# you don't always need to do this, but if you have changed include files # things don't seem to be getting built correctly do: $ make clean # do this only if you have added or removed #includes from existing # source or header files (you need to rebuild the dependencies in # this case): $ make depRemember that if you change .h files you need to copy them over to your VM if test programs there need to use these .h files. You can do this by hand, but again, it is often easier to just rebuild the kernel_headers package, remove the old one, and install the new version.
# (a) from your CS machine, copy the kernel packages to your VM: # (I'm using ginger as an example CS machine name) $ scp -P 10022 linux-image-126.96.36.199-lab3_1.0_amd64.deb swatcs@ginger:. $ scp -P 10022 linux-headers-188.8.131.52-lab3_1.0_amd64.deb swatcs@ginger:. # (b) Next, from within your VM, install the packages: # from root's home directory (or wherever you scp the files) $ sudo dpkg -i linux-image-184.108.40.206-lab3_1.0_amd64.deb $ sudo dpkg -i linux-headers-220.127.116.11-lab3_1.0_amd64.deb note: ignore this error message when installing the headers package (it is not really an error): Error! Your kernel headers for 2.6.34-lab3 cannot be found. # (c) reboot your VM and choose your new kernel from the grub menu $ sudo sync; sudo sync; sudo reboot # (d) login and verify that the new version of your kernel rebooted # check both the name of the kernel (does it have the -lab3 extention) # and the build date (is it a new build or old one) $ uname -a # note: If this is a re-install of a kernel package # that you have already installed (i.e. the same -lab3 flag as an # installed kernel package), you need to first remove the # old package(s), before you do the dpkg -i of the new ones: $ dpkg -r linux-image-18.104.22.168-lab3 # Use the -I option to dpkg to list info about the package file, # including its name (used in the -r option) $ dpkg -I linux-image-22.214.171.124-lab3_1.0_amd64.deb
# (a) from your CS machine, copy the kernel bzImage and System.map files to your VM: (I'm using ginger as an example CS machine name) $ cd /local/you_n_partner/linux-2.6.32 $ scp -P 10022 System.map swatcs@ginger:. $ scp -P 10022 arch/x86_64/boot/bzImage swatcs@ginger:. # (b) ssh into your VM and install the bzImage and System.map files # (replace the vmlinux... executable in /boot with the bzImage # be careful that you are replacing the right one...using mv -i will # give you a chance abort before overwriting the wrong one) $ ssh -p 1022 swatcs@ginger $ ls -l # verify dates on bzImage and System.map files you scp'ed over $ sudo mv -i bzImage /boot/vmlinux-126.96.36.199-lab3 $ sudo mv -i System.map /boot/System.map-188.8.131.52-lab3 # (c) run update-grub $ sudo update-grub # (d) sync, halt and then reboot into your new kernel $ sudo sync $ sudo sync $ sudo reboot # if rebooting is failing, first try booting into the cs45 kernel and then do: $ sudo sync $ sudo sync $ sudo halt -p # turn off and then back on the VM and boot your kernel
I suggest that you use git to do this:
Make sure to include in your git repo
only the linux source and header files that you modify for the current
lab assignment, and not the entire linux kernel source tree, which will eat
up your account quota. These are the files that you will submit for
each lab assignment, and the ones that you cannot recover. If you
accidentally delete other kernel files (ones you aren't changing), you can
always get a copy of them from the linux source starting point.
If you lose files you have modified, then can then get a back-up from
your git repo.
$ ssh -p 10022 swatcs@gingerUse scp to transfer files between your VM and your CS machine. Here are some examples (and yes, it is -P for scp and -p for ssh):
$ scp -P 10022 file.c swatcs@ginger:. $ scp -P 10022 *.c swatcs@ginger:. # copy a bunch of .c files $ scp -P 10022 -r dirname swatcs@ginger:. # recurively copy a directoryFrom your VM you can scp to your CS user account. Here are some examples:
$ scp file username@machinename:/home/username/cs45/labs/lab2/. $ scp file cs45username@machinename:/local/you_n_partner/lab2/.
printk output goes to the console and to log files on your VM in /var/log/kern.log and /var/log/syslog. You can open them in vim to printk output. Also, running tail -f on one of these files will let you see printk output as your kernel runs:
$ tail -f /var/log/kern.logIf your kernel crashes, it is likely that some of the printk output has not yet been written to the log files. As a result, you may want to jot down the last printk output on the console before rebooting. Also, be very careful about where you put printk calls; you don't want them on a code path that is executed many times per second.
printk output should also show up on the console window. If not, run this command, and then it should:
sudo dmesg -n 7
Click on your virtual machine instance in the VirtualBox Manager window (your VM should not be running), and choose Settings. Select the "Serial Ports" tab, choose Port 1, and enter the following and the choose OK:
(1) Check the "Enable Serial Port" box (2) Choose COM1 for "Port Number" (3) Choose HostPipe for "Port Mode" (4) Check the "Create Pipe" box (5) Enter /local/me_and_pal/serial in the "Port/File Path" box (where /local/me_and_pal/ is the name of your subdirectory /local on on your machine in which your virtualbox image and linux source are)
kgdboc=ttyS0,115200 kgdbwait # The result will look something like: linux /boot/vmlinux/.... \ ... rw kgdboc=ttySO,115200 kgdbwaitThen hit F10 to continue to boot. Your VM will continue booting but not finish, printing a message:
kgdb: Waiting for connection from remote gdb..." message
socat -d -d /local/me_and_pal/serial PTY: # you should see output like this: 2014/01/31 14:13:24 socat N opening connection to AF=1 "/local/me_n_pal/serial" 2014/01/31 14:13:24 socat N successfully connected from local address AF=1 "qp\xEE\x7E" 2014/01/31 14:13:24 socat N successfully connected via 2014/01/31 14:13:24 socat N PTY is /dev/pts/16 2014/01/31 14:13:24 socat N starting data transfer loop with FDs [3,3] and [4,4]Note: the /dev/pts/16 part will likely be different, and use the one that yours lists as the target in gdb.
Do not terminate socat; it needs to be running in the background to use the pseudo terminal to connect gdb.
$ cd /local/me_and_pal/linux-184.108.40.206/ $ gdb ./vmlinux ... ... Reading symbols from /local/me_and_pal/linux-220.127.116.11/vmlinux...done. (gdb) target remote /dev/pts/16 # or whatever the number is from socat Remote debugging using /dev/pts/16 kgdb_breakpoint () at kernel/kgdb.c:1718 1718 wmb(); /* Sync point after breakpoint */At this point you can use gdb commands to debug your kernel code: set breakpoints in your kernel functions, step and next through the execution of code, print variables, ...
$ vi .config CONFIG_LOCALVERSION="-lab3" # change -lab3 string to whatever you'd like $ make menuconfig # just choose Exit with the arrow keys
# in your virtual machine edit the file /etc/default/grub $ sudo vi /etc/default/grub # add the size of physical memory you want to GRUB_CMD_LINE_LINUX: GRUB_CMDLINE_LINUX="mem=512m" # run update-grub and reboot cat out /proc/meminfo to see the change sudo update-grub sudo sync sudo sync sudo reboot
fakeroot make-kpkg --initrd --revision=1.0 --append-to-version -lab2 kernel_image fakeroot make-kpkg --initrd --revision=1.0 --append-to-version -lab2 kernel_headers