2011-09-16

Linux kernel debug - Eclipse

I have needed to establish a comfortable Linux kernel debugging environment. I chose Eclipse for it. My host operating system is Mac OS X, I'm developing in a virtual Linux computer. It made this quite tricky. The following image shows the development and debugging environment:


I have my kernel source on my Mac. It is helpful, if you just want to check something fast, and you don't want to start any virtual machine. This directory tree is shared via HGFS+. It is VmWare's shared filesystem. The make works inside the VM, and procedures kernel's output to a directory, located inside it. I needed this output for Eclipse, so I shared it via NFS. The setup of this file sharing techniques is outside this post. The debugged kernel is running in a Qemu machine inside the VmWare Linux.

1. Kernel setup
You have to enable KGDB: kernel debugger. Inside that section select Use kgdb over the serial console. Additionally you need minimal debug info, for this select Compile kernel with debug info and Compile kernel with the frame pointers!

2. Eclipse preparation
After installing Eclipse, you'll have to install C/C++ GDB Hardware Debugger from Eclipse Marketplace.
To able to indexing Linux kernel, Eclipse'll need more memory than it is enabled for it by default. To change this:

  1. Right click to Eclipse.app and select Show package contents
  2. Select Contents/MacOS
  3. Edit eclipse.ini
  4. Change the -Xmx... line to -Xmx650M

3. Adding Linux kernel to Eclipse
  1. Select New and Project... from the File menu
  2. Select C/C++ from the list, and click to C Project
  3. Fill out Project name. In my case it is ITSSv6 Kernel
  4. Uncheck Use default location and select root directory of your kernel source
  5. Select Linux GCC and click to Next
  6. Click to Advanced settings
  7. On the Resources pane:
    1. Set Text file encoding to ISO-8859-1
  8. On the C/C++ Build pane:
    1. Uncheck Use default build command
    2. Edit Build command: ssh [USER]@[VMWARE_IP] make [MAKE_FLAGS] (If you want to build to a separate directory, do not forget to add the O=[DIR]!)
    3. I'm building Linux kernel as a part of a complex system. If you want to setup custom make targets (instead of all and clean), you'll able to do that on the Behavior tab.
  9. On the C/C++ General / Code Analysis pane:
    1. Linux kernel do not fit for code analysis rules. If you don't want a lot of yellow and red signs in your code, check Use project settings and uncheck almost all of the Warning/error categories!
  10. On the C/C++ General / Indexer pane:
    1.  Uncheck Index source files not included in the build
  11. On the C/C++ General / Path and Symbols pane:
    1. On the Includes tab select GNU C. Add the following include directories:
      1. Main include directory of your toolchain / compiler (via NFS from VmWare Linux)
      2. Kernel's include/
      3. Kernel's arch/[YOUR_ARCH]/include
    2. On the Symbols tab, and define __KERNEL__ with value 1.
    3. On the Location tab select Filter inside your project's source. Click to Edit filter, and add (Add multiple...) your unwanted architectures, typically your unused arch/* directories.
  12. OK, OK, OK, ... :)
  13. From the option menu (after right-click on the name of the project in the Project Explorer), select Indexer, and Rebuild index! It takes a long time!
  14. Finally build your kernel!
At this point you should have a built, indexed Linux kernel inside Eclipse. Code-competition, and other helpful features are available for development. :)


4. Setup Linux to execute debugger
You have to generate a disk image, which contains a loader, some simple applications (i.e. a shell), init scripts, and the kernel modules. Sorry, but it is outside the scope of this post.
In the loader (i.e. grub), you must add kgdbwait kgdboc=ttyS0,115200 to kernel command line!

5. Start Qemu
If you want to enable bridged networking inside Qemu, you find a good howto here. To start Qemu:

The serial console, emulated by Qemu, will be redirected to a TCP connection on port 4444.


6. Setup debugger in Eclipse


First of all, you have to write a tiny script, which executes gdb via a ssh connection. Copy-paste the following, and save into a file:

The contents of the eclipse-debug.sh file:

It maps the path mismatch between Mac and WmWare Linux.

  1. In the Run menu select Debug configurations...
  2. Select GDB Hardware Debugging on the left side, and click to New!
  3. Fill out name. In my case it is ITSSv6 KGDB HW Debug.
  4. At C/C++ Application select the build vmlinux file. You should find it at the NFS shared build directory.
  5. At Project select your project. In my case it is ITSSv6 Kernel.
  6. I recommend to check Disable auto build, and manage rebuild manually.
  7. At GDB Command select the previously saved script which calls eclipse-debug.sh!
  8. At Command set select Standard!
  9. At Protocol version select mi!
  10. Uncheck Verbose console mode and Use remote target (it refers to JTAG)
  11. On the Startup tab:
    1. Uncheck Reset and delay seconds and Halt
    2. Edit Initialization command textbox: target remote localhost:4444
  12. On the Source tab you'll have to invert the mapping handled by eclipse-debug.sh:
    1. Select Add
    2. Select Path Mapping
    3. Add two mappings, with the inverted logic as before
  13. Apply. And you're ready! :)
At this point, you're ready to debug Linux kernel from Eclipse. Unfortunately this complex architecture sometimes freezes Qemu or gdb. Before start always check it with ps!


0 comments:

Post a Comment

 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Top WordPress Themes