This blog entry is inspired by Takis blog . This entry can be seen as the revised version of Takis blog entry with consideration to latest Eclipse and Linux Kernel versions.
Prerequisites
The steps below would work on Debian, Ubuntu and Mint Linux. I have used Linux Mint.
You need latest version of Eclipse IDE for C/C++ Developers (I have used Helios). You can download from http://www.eclipse.org/downloads/
For rest of this guide you’d need several packages that you can install using following command
1 | apt-get install git-core kernel-package fakeroot build-essential libncurses5 libncurses5-dev qemu kvm crash kexec-tools makedumpfile kernel-wedge libelf-dev asciidoc binutils-dev debootstrap genext2fs e2fsprogs |
STEP 1: Get the Kernel source using git.
Run following command to clone the kernel source into your home folder:
1 | git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git ~/linux-2.6 |
STEP 2: Create a build directory
Create build directory in /mnt directory as its the best place to keep any mountable file system.
1 | mkdir -p /mnt/build/linux-2.6 |
STEP 3: Configure kernel
First run make oldconfig, which will read the defaults from an existing .config and rewrite necessary links and files.
1 | cd ~/linux-2.6 |
2 | yes "" | make oldconfig |
Now make changes to default configure to enable debugging options using menuconfig. You can also use xconfig if you’re using X.
1 | make menuconfig O=/mnt/build/linux-2.6 |
Select “Kernel hacking” menu
Enable “Compile the kernel with debug info”
Enable “Compile the kernel with frame pointers”
STEP 4: Disable automatic build in Eclipse
Open Eclipse with CDT plugin
Kernel code is huge and we wouldn’t want to enable automatic building after every change. Go to “Window->Preferences” menu, Select “General->Workspace” and deselect “Build automatically” checkbox
STEP 5: Add kernel project in Eclipse
Create a new project. Go to File->New->Project then select C Project.
Click Next
Enter project name – I have used linux2.6
Uncheck “Use Default Location” and select the linux source directory (~/linux2.6 in my case)
Select “Empty Project” under “Makefile project” as Project Type
Select Linux GCC as Toolchain
Click Next
Keep default values in Select Configurations window
Click Finish
Now eclipse will import the kernel source into the project and index it. This will take a while. Once complete all progress bars will disappear and the UI will look similar to below:
STEP 6: Configure build properties in Eclipse
Right click on Project and click on “Properties” from context menu.
Select “C/C++ Build” in properties window.
Uncheck “Use default build command”
Set build command as – make O=/mnt/build/linux-2.6
Set build directory as – /mnt/build/linux-2.6
Now the project is ready to build. Go to the menu-bar select “Project->Build all”.
If all goes well then after some time the Linux kernel build will be completed.
STEP 7: Configure debug settings in Eclipse
Right click on Project. Click on “Debug As ..” >> “Debug Configurations”
Double Click on “C/C++ Attach to Application”
Select vmlinux binary (in my case /mnt/build/linux-2.6/vmlinux) in C/C++ Application field on Main tab
Click on Debugger tab
Select GDB Server in Debugger option under main tab
Click on Connection tab
Select TCP in Connection “Type” field
Enter localhost in “Host name or IP address” field
Enter 1234 in “Port Number” field
STEP 8: Prepare a root filesystem for testing kernel
You’d need a root filesystem in order to boot and test the kernel. I prefer not using filesystem of my host machine. Here is a recipe to build a basic 8GB root file system
01 | cd /mnt |
02 | sudo debootstrap sid sid |
03 |
04 | echo -e "rootnroot" | chroot sid passwd |
05 | echo -e "auto loniface lo inet loopbacknauto eth0niface eth0 inet dhcp" > sid/etc/network/interfaces |
06 | ln -sf vimrc sid/etc/vimrc.tiny |
07 | rm -f sid/etc/udev/rules.d/70-persistent-net.rules |
08 | echo atul > sid/etc/ hostname |
09 | echo cgroup /mnt/cgroup cgroup defaults >> sid/etc/fstab |
10 | mkdir -p sid/mnt/cgroup |
11 |
12 | BLOCKS=$(((1024*$( du -m -s sid | awk '{print $1}' )*12)/10)) |
13 | genext2fs -z -d sid -b $BLOCKS -i 1024 sid.ext3 |
14 | resize2fs sid.ext3 8G |
15 | tune2fs -j -c 0 -i 0 sid.ext3 |
16 | rm -rf sid |
Notice I have setup root password as “root”
STEP 9: Run QEMU to launch the kernel build
Use following command to startup QEMU
1 | qemu -no-kvm -s -S -kernel /mnt/build/linux-2.6/arch/x86/boot/bzImage -hda /mnt/sid.ext3 -append "root=/dev/sda" |
In case you’re using 64 bit host the use following command
1 | qemu-system-x86_64 -no-kvm -s -S -kernel /mnt/build/linux-2.6/arch/x86/boot/bzImage -hda /mnt/sid.ext3 -append "root=/dev/sda" |
At this point you’ll see a blank QEMU terminal window. The “-s” option is a shorthand for -gdb tcp::1234, i.e. open a gdbserver on TCP port
1234. The “-S” option stops the CPU to start at startup. Now QEMU is waiting for kernel to start in debug mode
STEP 10: Start Kernel in Debug mode
From the menu bar in Eclipse click on debug icon
Then click on Linux2.6 Default debug configuration to run from the drop down list.
Launching might take a while, you can see the progress a the bottom right progress bar
Once the application is ready to launch it will prompt you to open the debugging perspective. Click on Yes.
Now the Eclipse perspective will change form development to Debug
Click “Run > Step over” or press the “F6″ key to execute the kernel code line by line and examine what’s happening.
Or click “Run > Resume” or press the “F8″ key to execute the kernel code without breaks.
You can find several articles on CDT at http://www.eclipse.org/cdt/documentation.php
UPDATED:
Here is the updated URL to Taki’s blog – http://issaris.org/blog/2007/12/14/debugging-the-linux-kernel-using-eclipsecdt-and-qemu/
http://code.google.com/p/myboards/wiki/CompilingLinuxKernelUsingEclipse
2) Setting the host:
This is next stepping that after getting the Board. We need to setup a host that may suitable for your work go smoothly.
For this we suggest and the recommended is to install Ubuntu 10.04 LTS on your PC. For this go to http://www.ubuntu.com
and download the ISO, burn it on a CD and Install it on your PC.
After Successful installation you need to setup some packages for your development. The installation of this Packages
we have an automated script for you which can be downloaded from http://masterarm.googlecode.com/files/android_pkg.sh.
Now after downloading it, just execute the following commands on your Terminal.
#Go to the downloaded location (we assuming it as Downloads)
==> cd ~/Downloads
==> sudo sh android_pkg.sh
This will install some of the packages that we require for development. After that you have to download cross compiler that having a „gdb‟ in it. I suggest you to download the Code Sourcery ARM GNU Toolchain for this click the following link
http://www.codesourcery.com/public/gnu_toolchain/arm-none-linux-gnueabi/arm-2009q3-67-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2
for latest versions of Code Sourcery go to the following URL http://www.codesourcery.com/sgpp/lite/arm/portal/release1039
Now extract the the tool chain and set the path variable for follow the steps below.
$ cd ~/Downloads/
$ tar –xvf arm-2009q3-67-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 –C ~/
This will be extracted in your home folder with a name of „arm-2009q3‟.
Now download the “C/C++ ECLIPSE” from the official website www.eclipse.org .
Extract the zipped file and double click on the eclipse binary it open the eclipse IDE.
Now follow the below steps to compile the Kernel using the eclipse.
i) Create a new project by selecting FILE -> NEW -> PROJECT
ii) Select Makefile project & Other Toolchain and give a name to your project.
iii) Uncheck on the “Use default location” and click on the browse button and select the path for your kernel Source directory.
iv) Click on OK and finish button
v) Select the project just you have created from the project window left to the workspace and select properties in Project Menu Project -> properties
vi) Click on the "+" just beside the C/C++ Build at left pane and select Build Variables . At the right pane click on ADD
vii) Give a name to your variable name and select TYPE as String and in the VALUE field : “ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
mini2440_defconfig “ click on OK "
Like this you have to add on more variable for uImage. Name as you like but the "VALUE" should be "ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- uImage"
and click on "OK".
viii) Now click on the Environment in the left pane. It gives some options in right pane as shown in below.
ix) Now Click on " Select "and in the next window search for " PATH " and select it by click on the Check box as shown below and Click OK.
x) Now the PATH Environment variable is add to your project select it and click on EDIT just adjacent to it. In the next window add your cross compiler
path along with the old one by appending a colon (:<path to the cross compiler>) and click on OK.
xi)Now the final steps adding the commands to project build system. Click on the “C/C++ Build” at left pane. In the Behaviour tab in right pane
add the build options in Build ( Incremental build). Click on the Variables.
xii)Now the following window will appear. In this window select the variable that previously added (defconfig and uImage) one by one.
After selecting the two variable the field looks like below.
xiii) Till now all the setting are completed the final pending thing is to build the Project, for this select the project and Right click, in the popup window select the Build Project.
xiv) While Building (Compiling) process is going on the window will appears as below.
After the completing the compilation process successfully the windows appears like below. In the console tab the last lines are
Image arch/arm/boot/uImage is ready
Build finished
HowTo use the CDT to navigate Linux kernel source
Here are some steps that I've found to get the CDT to work well with the Linux kernel source. If you exclude some of these steps, it may still work to a large degree, but some things may not work exactly right; for example it may find the wrong include file for a C file.
Anyway, as you do these steps, I think you may understand how they assist the indexer to do a good job for the Linux kernel source.
Disclaimer: these steps were last updated for Eclipse Juno 4.2.2 + CDT 8.1.2, and originally developed for Eclipse 3.5.1 + CDT 6.0.0.
- Download and install Eclipse plus the CDT.
- Configure and build your kernel to define CONFIG_* and generate autoconf.h. This can be done before or after downloading and installing Eclipse.
- Ensure that you have the right kernel source (e.g. make sure you are on the right git branch). If you check out another branch later, that's ok, but you will need to re-index the source, and that takes about 20 minutes.
- Start up Eclipse.
- Click File->New->C Project
- Fill in a project name like my_kernel
- Uncheck the Use default location box and type in the root directory of your kernel into the Location box.
- In the Project type: pane, click the Makefile project and select Empty Project
- On the right side, select Linux GCC
- Click Advanced settings... and a Properties dialog will pop up.
- Open the C/C++ General selection on the left.
- Click on Preprocessor Include Paths
- Select GNU C in the Languages list
- Select CDT User Setting Entries in the Setting Entries list
- Click on Add.... Choose Preprocessor Macros File from the top left dropdown, Project Path from the top right dropdown, and enter "include/generated/autoconf.h" into the File text box. (Note: For kernels older than 2.6.33, the location of autoconf.h is include/linux/autoconf.h)
- Also add any other macros files you are using.
- Click on Indexer
- Checkmark the Enable project specific setttings box.
- Uncheck Index source files not included in the build
- Click on Paths and Symbols on the left.
- Select the Includes tab and then select GNU C
- Click Add...
- Click Workspace... then select your kernel's include directory
- Do another Add, Workspace and add arch/architecture/include, e.g., arch/powerpc/include
- Click the # Symbols tab
- Click Add...
- Set the name to __KERNEL__
- Set the value to 1 and click OK
- Click the Source Location tab
- Click the plus sign next to your project name.
- Select the Filter item and click Edit Filter...
- Click Add Multiple... and then select all of the arch/* directories in your kernel source that will not be used (i.e. all the ones that are not for the architecture you are using)
- Click OK and OK again to dismiss that dialog.
- Under C/C++ General, select Preprocessor Include Paths, Macros etc.
- Click the Providers tab and select CDT GCC Built-in Compiler Settings
- Uncheck Use global provider shared between projects
- Add -nostdinc to the Command to get compiler specs
- Check Allocate console in the Console View so you can see that this is working
- Click OK on the Properties dialog.
- Click Finish on the C Project dialog.
- The Project will index automatically.
- On a platter drive indexing will take upwards of 20 minutes to complete, on a SSD indexing will take about 5 minutes to complete.
Notes:
- Adding include and arch/architecture/include only gets you a couple of the common include paths. To fully index all of the kernel, you would have to add dozens of paths, unfortunately. For this reason, I advise against using PTP's remote indexing capability for the linux kernel, because what happens is that it will report thousands of errors in locating header files, and the process of reporting those errors over a possibly long-latency link, will cause the indexing to take many hours.
- If you change any of your CONFIG_* settings, in order for Eclipse to recognize those changes, you may need to do a "build" from within Eclipse. Note, this does notmean to re-build the index; this means to build the kernel, by having Eclipse invoke make (this is normally bound to the Ctrl-B key in Eclipse). Eclipse should automatically detect changes to include/generated/autoconf.h, reread the compilation #defines it uses, and reindex.
- The background color of "Quick Context View" will be dark if the Ambiance theme in Ubuntu is selected.
- First download the autoconf-to-eclipse.py script and place somewhere in your path
- autoconf-to-eclipse.py
- Create a new project of the type C project and select Makefile project/Other toolchain. Uncheck the Use default location checkbox, then enter the path to the kernel source:
- Click next and select Advanced options
- Select the C/C++ Build tab and uncheck Automated discovery of paths and symbols:
- Select the C/C++ General tab and select no indexer
- Remove the default includes from all languages and add kernel includes so that you have something like this:
When adding includes, select Add to all languages and select a workspace path:
- Select the Symbols tab and add the __KERNEL__ symbol:
Again, add to all languages:
- Press OK to return to the main eclipse window
- Exclude non-needed architectures and includes by selecting paths in the project window, right clicking and selecting Exclude from build...:
Do the same for unneeded includes
- Run autoconf-to-eclipse.py in the kernel directory, updating the eclipse project files:
- Refresh the project in the project window and enter the project properties again. Enable the indexer:
- Press OK
Eclipse will now index the kernel and after this you should be set to go. Indexing will obviously take some time, but it's saved between sessions so you can safely exit eclipse.