In preparing your machines for class we had to customize your kernels. In fact, we had to compile a kernel module (and just for good measure we complied a complete kernel) to get your machines to work the way we wanted to get them to work. To understand what we did, let's discuss the ways in which kernels can be customized.
There are two popular ways to write an Operating System kernel nowadays:
This is the approach used in Minix and Mac OSX, for example.
This is the approach taken in Linux.
As we've mentioned before, the /proc file system does not actually appear on a disk device. Instead, it represents the state of a number of processes. Each process maintaining a file in proc responds to the kernel file system operations: read, write, open, close, etc. The processes present a view of the running operating system as if it is a file. Some of the files are read-only (they give information about the system). Some of the files can be written, allowing appropriate users (usually just root) to modify parameters of the system.# echo 32768 > /proc/sys/fs/file-max
Here is a sampling of the kinds of things that can be changed:
Device drivers are another element that makes monolithic kernels similar to microkernels. Device drivers all use a set of common interfaces to let the kernel communicate with a device. When a new particular device of some kind (such as a SCSI disk) is to be interfaced to a Linux OS for the first time, a driver must be written that allows it to work. Then the driver must be incorporated into a kernel for the device to be actually used by a running Linux machine.
It is not surprising that a new driver would need to be added to a Linux machine during its lifetime.
Many devices correspond to files in /dev. Network interfaces are the biggest exception to this rule. Every device file has a major and minor number. These are used to keep track of the location of device information in kernel tables.
The major number identifies the driver associated with the device.
The minor (or unit) number (usually) keeps track of the individual
device of that type. Executing ls -l
will show you
the device major and minor numbers.
The two broad groups of device files are block and character devices. Block devices transfer data on read or write in a group of bytes (usually a multiple of 512). Character devices can be read or written one byte at a time.
Some device drivers correspond to virtual devices. Consider for example PTY (pseudo-TTY) that are used to keep track of users who log in over the network. The actual device being used is the network interface, but having an abstraction layer corresponding to a terminal device for the login is quite convenient.
New device files are not created in the same way as regular files.
One uses mknod
to create a device. Debian and RedHat
provide a script called /dev/MAKEDEV to provide an easy
interface to using mknod
. Check out its man page.
Nemeth notes that all Unix operating systems have device naming conventions that help one understand what device is being used. Some system's conventions are extremely detailed, some are relatively spartan. The following Linux device naming conventions hold:
patch
program using a patch file that tracks the
differences between the kernel before installation of the device and
the kernel after installation of the device. The patch
program will apply the changes to modify the kernel appropriately
(if it really matched the before state). Then you
have to recompile your kernel (see below).
A kernel module is a program compiled separately from the kernel that can be dynamically loaded to extend the capabilities of the kernel.
Although properly installing a working kernel module will never cause your kernel to have problems, it's often the case that the first time you install a module it won't be installed properly or it just won't work. So don't install a module the first time on a production system running full-tilt.
Loadable kernel modules are usually stored in
/lib/modules/version, where version is
the version number of the Linux kernel. This can be found
by executing uname -r
.
The program lsmod
will list the installed modules.
You install an LKM (loadable kernel module) by executing
insmod modulename [parameters ...]
Modules can be unloaded using rmmod
. If the number of
references to the module (as shown by lsmod
is
not 0, however, executing rmmod
will not actually
have any effect.
The program modprobe
knows about module dependencies,
options, and installation/removal procedures and can be used to more
sanely manage installation and removal of modules. The file
/etc/modules.conf gives modprobe
the configuration information it needs to operate properly.
Running modprobe -c
will generate a file
/etc/modules.conf that contains configuration information
for all modules installed at the time of its running.
To recompile the kernel you must engage in the following steps:
make xconfig
or
make menuconfig
.
This can be done by editing the file
/usr/src/linux{-version-info}/.config or by
executing make menuconfig
, which lets you
change those parameters you want to. Don't even
think of running make config
. It will
ask you about every single configuration parameter
without letting you go back and change any choices you've
already made. Don't even think about it!
make xconfig
runs a menuconfig like program
under X. Use it if you have access to an X terminal.
Here is a sample of config file nonsense:
Each entry specifies some configuration option. You should change those options that are necessary to achieve the desired output. How do you know which options to change? Consult documentation, google, and/or the source (the kernel code).CONFIG_M686=y CONFIG_X86_GOOD_APIC=y CONFIG_X86_INVLPG=y
make dep
This updates kernel makefile dependencies.
make clean
This throws out any crufty .o
files
bzImage is a compressed kernel image. This usually takes a while.
make modules
This compiles any modules that are available to your kernel
make modules_install
This installs the modules you made in the appropriate place.
/boot/vmlinuz
Or to some other bootable kernel name
This provides a static list of all locations of externally callable kernel functions.
/boot/grub/grub.conf
to add a configuration line
for the new kernel.
/sbin/lilo
to install
the newly reconfigured boot loader.
My more specific admonition: Don't mess with workin' code.
This advice is to be ignored by you while you have access to your machines. Please try out more stuff than you need to.
Most notably:
No Linux distribution we're aware of supports serial consoles out of the box with just a config change. This, of course, is ridiculous for a system touted as being ideal for the server market.