Debugging real hardware can be a difficult task, especially given the plethora of platforms and architectures
that are available today. Providing an example that could realistically hope to address even a fraction
of these was never likely to be easy – at least until tools such as UM Linux, qemu and other kernel
virtualization technologies became available. Now, it’s possible to trivially debug certain kinds of kernel
problem safely and without the risk of a system crash, by using an emulator.
There are various types of emulation technology available that can be used to run the Linux kernel in all
manner of simulated environments. One of the most straightforward to use is the User Mode (UM) kernel
since it’s now built right into the mainstream Linux kernel and available as a compile time option
when building a new Linux kernel. User Mode Linux (UML) runs the Linux kernel as a regular application
process. It simulates hardware such as clocks and interrupts using signals and does not talk directly
to real hardware. Nonetheless, it is still a Linux kernel and is useful for testing certain features.
Now, start to debug.Let's step by step.
1. Get the source
You need to start by getting a kernel tree (generally, the more recent, the better): Unpack the tree, which will end up in linux-2.6.24 in this case
host% wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.24.tar.bz2 --15:02:55-- http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.24.tar.bz2 => `linux-2.6.24.tar.bz2' Resolving www.kernel.org... 204.152.191.5, 204.152.191.37 Connecting to www.kernel.org|204.152.191.5|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 40,845,005 (39M) [application/x-bzip2] 100%[====================================>] 40,845,005 633.10K/s ETA 00:00 15:04:00 (622.07 KB/s) - `linux-2.6.24.tar.bz2' saved [40845005/40845005]
host% bunzip2 linux-2.6.24.tar.bz2 host% tar xf linux-2.6.24.tar host% cd linux-2.6.24
2. Configure
Start with the UML default configuration, which will compile and boot. If you need to make changes, then do that later using menuconfig or xconfig.host% make defconfig ARCH=um host% # now make menuconfig or xconfig if desired host% make menuconfig ARCH=umIf you don't start with a defconfig, then the kernel build will be that of the host (it will find a config file in /boot), which will be very wrong for UML and will produce a UML that lacks vital drivers and won't boot.
Note - it is vitally important to put "ARCH=um" on every make command while building UML, or to "export ARCH=um" to put ARCH in your environment. This causes the kernel build to build UML, which is a separate Linux architecture. Not doing so will cause the kernel build to build or configure a native kernel. If you should forget, clean the pool like this to get rid of all traces of whatever building you did, and start over.
host% make mrproper host% make mrproper ARCH=um3.Building
Now, you can start the buildxbw@ubuntu-fs:~/debug-kernel/linux-2.6.32.21$ gdb ./linux GNU gdb 6.8-debian Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "i486-linux-gnu"... (gdb) run debug Starting program: /home/xbw/debug-kernel/linux-2.6.32.21/linux debug 'debug' is not necessary to gdb UML in skas mode - run 'gdb linux'host% make ARCH=umWhen this finishes, you will have a UML binary called "linux".host% ls -l linux -rwxrwxr-x 2 jdike jdike 18941274 Apr 7 15:18 linuxIt's so large because of the debugging symbols built in to it. Removing those will shrink the UML binary to roughly the size of a native kernel.Now, you are ready to boot your new UML.
4. run
xbw@ubuntu-fs:~/debug-kernel/linux-2.6.32.21$ ./linux Locating the bottom of the address space ... 0x10000 Locating the top of the address space ... 0xc0000000 Core dump limits : soft - 0 hard - NONE Checking that ptrace can change system call numbers...OK Checking syscall emulation patch for ptrace...OK Checking advanced syscall emulation patch for ptrace...OK Checking for tmpfs mount on /dev/shm...OK Checking PROT_EXEC mmap in /dev/shm/...OK
................................................
Console initialized on /dev/tty0 console [tty0] enabled Initializing software serial port version 1 console [mc-1] enabled Couldn't stat "root_fs" : err = 2 Failed to initialize ubd device 0 :Couldn't determine size of device's file VFS: Cannot open root device "98:0" or unknown-block(98,0) Please append a correct "root=" boot option; here are the available partitions: Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(98,0) 09c5bed8: [<0805997a>] dump_stack+0x1c/0x22 09c5bef0: [<08071fc2>] panic+0x3c/0xdb 09c5bf20: [<080498c5>] mount_block_root+0x1f2/0x208 09c5bf78: [<08049927>] mount_root+0x4c/0x54 09c5bf9c: [<08049a42>] prepare_namespace+0x113/0x13a 09c5bfa4: [<080493df>] kernel_init+0xbb/0xc7 09c5bfb4: [<080651ef>] run_kernel_thread+0x37/0x3f 09c5bfe0: [<080589e3>] new_thread_handler+0x57/0x7e 09c5bffc: [<00000000>] 0x0
...................................................
5. Debug kernel
........................................