"It's a dangerous business, Frodo, going out of your door. You step into the road, and if you don't keep your feet, there is no knowing where you might be swept off to."
—Bilbo, The Fellowship of the Ring by J. R. R. Tolkein, Book 1, Chapter 3
Welcome to Advanced Operating Systems! We're going to start by compiling Linux from source. Even if you've done this kind of thing before, this studio will get you the source code and resources that this class depends on, along with additional experience working with the Raspberry Pi platform.
In this studio, you will:
Please complete the required exercises below, as well as any optional enrichment exercises that you wish to complete.
As you work through these exercises, please record your answers, and when finished email your results to firstname.lastname@example.org with the phrase Welcome To Linux Studio in the subject line.
Make sure that the name of each person who worked on these exercises is listed in the first answer, and make sure you number each of your responses so it is easy to match your responses with each exercise.
Once you have successfully booted into Linux, you can use the command
uname to get a variety of information about the currently
running system, such as the current kernel version or the date on which
the currently running kernel was compiled. As the answer to this exercise,
copy and paste the output of the command "
To save hours of time, and avoid potential freezing of your Raspberry Pi during
long-running local compiles, we will
be cross-compiling the kernel using a university-managed server
shell.cec.wustl.edu) and machines in the Linux Lab.
First log into
shell.cec.wustl.edu via ssh using your wustl key.
Create a folder called
linux_source to keep all of your source code organized.
Move into your new folder and issue the following commands, each of
which may take several minutes to finish:
tar -xzf raspberrypi-kernel_1.20160506-1.tar.gz
This has the effect of downloading a specific version of the
Raspberry Pi 3 Linux distribution, which is the version that
this course was developed with. Newer versions exist, which we won't
use for class but you can pursue on your own time if you'd like. Once
the files finish unpacking you'll have a new directory, which we
suggest renaming as something simpler with the
command. We renamed ours linux, which is what the
rest of these instructions will assume you've done as well.
Move into your new linux directory, and issue the
make kernelversion, which will tell you which Linux
kernel version you've just checked out. As the answer to this exercise, copy the output of
First, go to kernel.org/pub/linux, which is the public Linux source code repository, and click through "kernel", "projects", and then "rt". You will need to use the answer to the previous exercise in order to find the correct source code patch that matches the version of the Linux kernel that you're using. For example, if you have source code version "4.0.7", then you will move to the directory "4.0" and get "patch-4.0.7-rt11.patch.gz". (Warning: do NOT use the file that starts with "patches", the patch file contains the complete, current version of the patch, while the patches file contains data necessary to update from the last issued version of the rt patch.)
Move into your
linux_source directory and use
wget to obtain the
appropriate patch file ending in gz. To apply the patch, move into your
linux source code directory (the one with arch, drivers, init, etc.)
and issue the following command: (you will need to change version numbers)
zcat ../patch-4.0.7-rt11.patch.gz | patch -p1
zcat command works like the
cat command, but
does so for compressed files. If you just issue the command
zcat ../patch-4.0.7-rt11.patch.gz by itself you'll see
that the source code patch is actually stored in
The vertical bar character pipes the output of
another program called
patch, which just applies each individual
diff to the appropriate files in the source code directory.
If no errors are reported, then proceed to the next step. Leave this answer blank.
module add raspberry (this adds the cross-compiler to your PATH variable)
KERNEL=kernel7 (this is used by some build scripts)
Note that in some terminal environments (depending on how you have set up
your account on
shell.cec.wustl.edu) you may need to do this using the set command:
make -j8 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2709_defconfig
To reiterate, if you were building a general purpose kernel, you wouldn't use the previous two commands. They're setting a default configuration for Raspberry Pi . Next, we want to set custom configuration options. Issue the command:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
After a moment, you'll get a kernel configuration menu. As you can see, there are a _lot_ of options. For now, we're just going to do two things. First, we will enable the RT_PREEMPT patch we applied previously. Go into "Kernel Features", and then select "Preemption Model". If the patch was applied correctly, you'll have the option "Fully Preemptible Kernel (RT)", which you should select.
Next you'll add your own unique identifier to the kernel you build.
Navigate to "Local version" under "General setup". The local version
string you specify here will be appended to the output of the
uname command. If you applied the default Raspberry Pi
configuration correctly, this should be set to "
-v7". Go ahead
and add your own unique identifier, though recall that
already gives you the kernel version number, the day and time the kernel was
compiled, as well as other info.Warning: do not include a space in the
local version string- this will break the build script when you run
sudo make modules_install in the future.
As the answer to this exercise, find a neat sounding option and use the "H" key to bring up a short description. Provide the option's name, a short summary, and the option's symbol. Once you're done, exit the configurator and be sure to answer "Yes" when asked to save your changes.
Because kernel compiles are
computationally intensive, you should not run them on the
and instead should run the
qlogin command to log into a Linux Lab host
to run your compilations.
Once you are logged into one of the Linux Lab machines, confirm that you are still in
linux_source/linux directory (or if not
cd into it).
Then, issue the following commands to cross-compile the kernel:
module add raspberry
make -j8 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs
The compile will take several minutes. Once it's done, issue the following command:
This will create a directory that the cross-compiler will use to store the kernel modules that it creates. You will later transfer these to your Raspberry Pi. Then issue the command:
make -j8 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
Leave this answer blank.
linux_sourcethat will serve as a place to organize your code. Move inside your
linux_sourcedirectory and create a directory called
liband another directory called
boot. The naming is important, because the Pi's version of sftp will only transfer entire directories if the source and destination folders have the same name. From your
linux_sourcedirectory run the following commands:
sftp [your wustl key]@shell.cec.wustl.edu
get -r modules/lib/
get -r linux/arch/arm/boot/
quit (to get back to your Pi)
Back up your directories
/boot, because you will
be modifiying their contents. To do this, we used
sudo cp -r /lib ~/Desktop/lib_backup and a similar
/boot. You should be in
linux_source directory. If not navigate there and
run the following commands:
sudo cp -rd * /lib/
sudo cp boot/dts/*.dtb /boot/
sudo cp boot/dts/overlays/*.dtb* /boot/overlays
sudo cp boot/dts/overlays/README /boot/overlays
sudo ./mkknlimg boot/zImage /boot/$KERNEL.img
At this point, your new kernel is installed. When you reboot, you'll be running your very own, custom kernel.
Go ahead and reboot now. If everything went OK,
the new system should look and feel the same as before. You can verify
that your new kernel is running with the command
In particular, the build date should be today, the version string should
include the local version string you specifed during configuration, and
your Linux source code version with
the characters "rt" should appear, which indicates that the PREEMPT_RT patch
has been applied.
As the answer to this exercise, copy the output of
Congratulations! You've just compiled an operating system from source!
make -jN where N is the number of cores you want to use to compile
sudo make modules_install install
That's all there is to it! The
install targets will
automatically and correctly install the new kernel on the common
Linux distributions. In the base source code directory there's a file called
README which contains compilation and installation instructions for a wide
range of scenarios.
For a sufficently powerful machine, building a new kernel is pretty painless. Our lab's 16 core, 3.2Ghz Intel machines take about 15 minutes to compile and install.