Tools To Work With Modules

  • lsmod - Shows currently loaded modules.

  • modinfo - Shows module information and parameters. Note that parameters can also be found in =/sys/module/*/parameters/.

  • dmesg - Show the kernel’s ring buffer. Note that this is the first thing to explore when trying to suppress annoying output on the console dmesg -D.

  • cscope - Need a way to search through the whole kernel tree for something? This program does a good job of that.

  • insmod - Insert (register) a module into a running kernel.

  • modprobe - Often a better way to load a kernel module. For example, this allows the module to take parameters with modprobe modname modopt=modoptarg

  • rmmod - Pull (unregister) a module out of the running kernel.

Creating A Module

Here is a simple module that does nothing much but show the most basic ingredients of a module.

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>

MODULE_AUTHOR("Chris X Edwards <mrproper AT>");
MODULE_DESCRIPTION("Just testing.");

static int __init simple_init(void)
  printk(KERN_DEBUG "Hello world!\n");
  return 0;

static void __exit simple_exit(void)
  printk(KERN_DEBUG "Simple module exiting.\n");


The printk messages will show up in the ring buffer (check dmesg) when the module is registered and unregistered.

Assuming the desired kernel headers exist, this can be compiled with the following Makefile.

obj-m += simple.o
MBUILDPATH ?= /lib/modules/$(shell uname -r)/build
        make -C $(MBUILDPATH) M=$(PWD) modules
        make -C $(MBUILDPATH) M=$(PWD) clean

Traditional Kernel Compiling

  • Get the kernel you want from If you’re very serious about this try something like:

    git clone git://

    This will make a directory called linux so make sure there isn’t one of those already extant.

    Since I’m not a kernel developer, my preferred technique for getting the most suitable kernel is to go to and just choose the one listed as "stable". Copy the URL for the tar.xz version into the clipboard and paste that into the following.

    # K=
    # wget -qO- ${K} | tar -xvJf - -C /usr/src/
  • Go to the source directory

    cd /usr/src/linux

    If this doesn’t exist, it’s nice to fix that with a symlink.

    cd /usr/src/ ; ln -s linux-3.14.4 linux
  • I have no idea what this really does.

    make mrproper

    I suspect it cleans up old temp files and directories. Make file says, "Delete the current configuration, and all generated files". This is probably seldom necessary unless you’ve really made a mess of things. I think the weird target name comes from the name of the "Mr. Clean" product as it is marketed outside the USA. Weird.

  • This should invoke the curses (text menu) kernel options selector.

    make menuconfig

    This program is very sensitive, for example:

    Your display is too small to run Menuconfig!
    It must be at least 19 lines by 80 columns.

    Also, too big with a "medium" font causes problems. The advantage to menuconfig is that it works fine over SSH. It works fine in screen sessions even if its border glyphs become garbled. You can also try this which can produce better output in some cases.

    make nconfig

    There is also one for tcl/Xwindows.

    make xconfig

    The nice thing about xconfig is that help text for each selectable item is shown by default.

    There are other alternatives like make config for the unrelenting, unforgiving Q & A script. I can never imagine a case where this is useful since you will have to answer around 1000 questions.

    Currently my favorite strategy is to use an existing configuration as the basis of my compiling effort. The reason for this is because the kernel’s default choices are so hopelessly stupid that any kernel I have previously worked on will be much closer to sensible than any default one. (Seriously, makes me wonder if make randconfig is the where the default comes from.) To use an old configuration, just copy the .config file from some other compiling effort, maybe the last version you used, into the desired kernel source directory. Then run this.

    make oldconfig

    If you don’t have an old config that you like, you can try to answer questions sensibly based on what is running at the moment on this system.

    make localmodconfig

    Now the hundreds of questions will involve all the ambiguous things that the previous configuration does not address. This basically entails new features mostly. I find that it’s good to go through each one and make sure it says "N". If it says "Y" check that it’s not some corporate ego module for some extremely exotic device that you will never own. I will say it seems like Linux is getting better about this, but there is still a shocking number of default things in the kernel that can’t be used by more than 1 in a million users. It’s very weird. It’s like in 2003 the thinking was turn everything on! And in the last 10 years there’s been a push to rethink that. The result? A mess. Anyway, after the using your old kernel as a basis and answering the questions about new stuff, then run make menuconfig and target the stuff you are really concerned about (building an NFS server? Turn on NFS serving, etc.)

  • Store config info to a file for future use. I rename mine to .config.xed or something because it’s easy for these to get automatically overwritten. It is true too that make install does seem to put a copy in the /boot directory which can be helpful. Also there is a kernel option for having these settings available from the kernel itself. Why not? It’s a lot of work setting one of these up just right - it’s good not to lose that.

  • make dep; make clean; make zImage Just kidding. These days, just do make. Should take care of things.

  • In the past I would have moved the kernel into place myself. However, today I generally trust

        make install

    to do sensible things. It copies the kernel into /boot/ along with the .config files and maybe other things. It also renames the kernel from whatever wrong thing it is in the source tree to something like /boot/vmlinuz-3.14.4-xed. It then makes a symlink to that called /boot/vmlinuz. It also takes the files of those names that were there before and renames them with .old on them. This is nice because then you can set up a GRUB rule to boot vmlinuz by default and vmlinuz.old as a second choice. Then if your kernel meddling does not go well, you can revert to the previous kernel. If for some reason you do not want the installation to put things in the normal place, you can use something like this.

    INSTALL_PATH=/xen/kernels/install make install
    While this renaming works pretty well, it can be a good idea to save a version of the kernel to some other kind of backup name. This way if you make two stupid kernel configurations in a row and the old and current ones are unbootable, you can still go back and get back in.
  • It used to be that you needed to run lilo to get the new kernel to work but now, if the GRUB profile points to the right place and you’ve put a good kernel in it, you’re good to go.

Full instructions for compiling a kernel are in the README file that ships with the source.


Sometimes you need to use arcane and mysterious kernel options/parameters to get things to boot correction. Since there’s not exactly a man vmlinuz opportunity, this official list of kernel parameters is useful.


The most maddening lack of an important feature in the Linux kernel is the ability to actually read the error messages that can occur during an aborted boot.

Here is a good link of various things to try.

I usually make sure that CONFIG_BOOT_PRINTK_DELAY=y is set and then add boot_delay=200 to the boot parameters. But this has been known to totally not work one bit. There are other tricks involving network output and serial output, both of which are a massive pain just to read the screen, but that’s what it takes.