This note outlines how you can browse the internals of the Linux kernel binary on Ubuntu or Debian. This is less fun than running "mdb -k" on Illumos and seeing the contents of kernel memory live, but at least you can view the linux binary image statically, at the same addresses as the running kernel would occupy, and with co-ordinated symbols and disassembly. (Actual addresses in your kernel may be slightly different due to later patches; to have them exactly the same you'll need to build your kernel yourself). Note that the Linux kernel code makes very heavy use of macros. Often, it's easier to see what how some code ended up compiling than chasing these macros through several layers of expansion to their definitions. Ubuntu and Debian have packages for stock kernel sources and compiled kernel image with symbols. The kernel you normally boot also comes with symbols (look in /boot/ for vmlinuz-* and System.map-*, and grep System.map for addresses of some known symbols!), but it stored compressed (hence "z" in "vmlinuz"), and gdb will not like that. My examples are from my Debian machine, running the generic stock kernel. You can always get the version of your stock kernel into your bash commands with `uname -r` (in bash, backticks immediately paste the output of the command between them into the command line). sergey@debian:~$ uname -a Linux debian 3.2.0-4-amd64 #1 SMP Debian 3.2.63-2+deb7u1 x86_64 GNU/Linux sergey@debian:~$ uname -r 3.2.0-4-amd64 Instead of my version in all of your commands you can use `uname -r` for yours. NOTE: On Ubuntu, package names vary slightly, so it's a good idea to check with "apt-cache search linux-image | grep dbg" and similar. Find and download the uncompressed kernel version with symbols: sergey@debian:~$ apt-cache search linux-image-`uname -r`-dbg linux-image-3.2.0-4-amd64-dbg - Debugging symbols for Linux 3.2.0-4-amd64 sergey@debian:~$ sudo apt-get install linux-image-3.2.0-4-amd64-dbg Find where it ended up on your system: sergey@debian:~$ dpkg-query -L linux-image-3.2.0-4-amd64-dbg | grep vmlinux /usr/lib/debug/boot/vmlinux-3.2.0-4-amd64 /usr/lib/debug/lib/modules/3.2.0-4-amd64/vmlinux Let's see how much space it takes & compare it with the actual kernel you boot: sergey@debian:~$ ls -lh /usr/lib/debug/boot/vmlinux-3.2.0-4-amd64 -rw-r--r-- 1 root root 96M Jan 12 17:34 /usr/lib/debug/boot/vmlinux-3.2.0-4-amd64 sergey@debian:~$ ls -lh /boot/vmlinuz-3.2.0-4-amd64 -rw-r--r-- 1 root root 2.8M Oct 30 08:42 /boot/vmlinuz-3.2.0-4-amd64 Now we are ready to use the above image with gdb, but let's get the source code as well. sergey@debian:~$ apt-cache search linux-source linux-source-3.2 - Linux kernel source for version 3.2 with Debian patches linux-source - Linux kernel source (meta-package) linux-source-2.6 - Linux kernel source (dummy package) sergey@debian:~$ sudo apt-get install linux-source-3.2 So, what did we just download? sergey@debian:~$ dpkg-query -L linux-source-3.2 /. /usr /usr/src /usr/src/linux-patch-3.2-rt.patch.bz2 /usr/src/linux-source-3.2.tar.bz2 /usr/share /usr/share/doc /usr/share/doc/linux-source-3.2 /usr/share/doc/linux-source-3.2/copyright /usr/share/doc/linux-source-3.2/changelog.Debian.gz /usr/share/doc/linux-source-3.2/README.Debian So we got the Linux source archive, with Debian-specific patches. It's up to us to un-archive it in /usr/src/ # cd /usr/src # tar xfj /usr/src/linux-source-3.2.tar.bz2 I usually use tar with "v" option ("tar xvfj smth.tar.bz2" or "tar xvfz smth.tar.gz") to see the files being extracted, but for the kernel that list is huge, some 57000+ files, it considerably slows unzipping! So now we can use both the vmlinux-* and the sources together. In fact, one more step is needed, as I discovered: sergey@debian:~$ gdb /usr/lib/debug/boot/vmlinux-3.2.0-4-amd64 GNU gdb (GDB) 7.4.1-debian Copyright (C) 2012 Free Software Foundation, Inc. <...skipped> Reading symbols from /usr/lib/debug/boot/vmlinux-3.2.0-4-amd64...done. (gdb) list sys_open 999 /build/linux-p4iNsg/linux-3.2.65/fs/open.c: No such file or directory. (gdb) quit So I created a symlink to my source directory tree: # mkdir /build # mkdir /build/linux-p4iNsg # cd /build/linux-p4iNsg # ln -s /usr/src/linux-3.2.65 . Restart gdb, and now we have: sergey@debian:~$ gdb /usr/lib/debug/boot/vmlinux-3.2.0-4-amd64 GNU gdb (GDB) 7.4.1-debian <...skipped> Reading symbols from /usr/lib/debug/boot/vmlinux-3.2.0-4-amd64...done. (gdb) list sys_open warning: Source file is more recent than executable. 999 SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, int, mode) 1000 { 1001 long ret; 1002 1003 if (force_o_largefile()) 1004 flags |= O_LARGEFILE; 1005 1006 ret = do_sys_open(AT_FDCWD, filename, flags, mode); 1007 /* avoid REGPARM breakage on x86: */ 1008 asmlinkage_protect(3, ret, filename, flags, mode); And now let's see disassembly with the corresponding code: (gdb) disas /m sys_open Dump of assembler code for function sys_open: 1000 { 1001 long ret; 1002 1003 if (force_o_largefile()) 1004 flags |= O_LARGEFILE; 0xffffffff810faa54 <+0>: or $0x8000,%esi 1005 1006 ret = do_sys_open(AT_FDCWD, filename, flags, mode); 0xffffffff810faa5a <+6>: mov %edx,%ecx 0xffffffff810faa5c <+8>: mov %esi,%edx 0xffffffff810faa5e <+10>: mov %rdi,%rsi 0xffffffff810faa61 <+13>: mov $0xffffff9c,%edi 0xffffffff810faa66 <+18>: jmpq 0xffffffff810fa96f End of assembler dump. Note that you can now see exactly how specific lines of code are compiled. In particular, note the amd64 calling convention in the call to do_sys_open: arguments are passed in registers, not on stack as in the 32bit ABI. You can use "disas /r" if you'd like to see exactly how the instructions are encoded. In particular, you can see the negative offsets (not actual computed addresses the disassembler is helpfully showing) in jmp-s and calls. For a more exciting adventure with reading kernel code, look at the "disas /m __switch_to", which is the scheduler function that switches from one process context (virtual memory translation table and all) to another. This switching is described in detail in pp. 105--110 of "Understanding the Linux Kernel" book by Bovet & Cesati, (http://www.amazon.com/Understanding-Linux-Kernel-Third-Edition/dp/0596005652) and a more condensed explanation can be found in http://stackoverflow.com/questions/6525905/how-does-scheduleswitch-to-functions-from-linux-kernel-actually-work