Federico Fuga

Engineering, Tech, Informatics & science

Kernel Development with Clion

19 Aug 2024 21:35 CEST

The linux kernel

The context and the problem

For one of my customer I’m developing a board with an ARM cpu (Allwinner A33 for instance) and running linux.

My duties includes modifying the UBoot bootloader, the linux kernel and all the software stack, included the Qt Application.

The environment is built using buildroot and uses a ready made compiler so that I don’t need to build the compiler every time I need to rebuild everything. Indeed, the whole building for one of the two firmware flavours we are using, takes around 20-30 minutes on my Ryzen with 64Gb Ram. But the crosscompiler is not installed systemwide, and is only decompressed and used by the buildroot builder during the build phase, and it is also packed in the SDK blob in make sdk phase. So the crosscompiler is in an /opt/arm-something/bin/ path.

Short story short, modifying the kernel and drivers without the aid of a smart IDE is doable but sometime a bit slow and unconfortable.

I’m using Clion as my day-to-day IDE, and I’m so customized using it that I find myself using clion’s keybinding even in Kate, Sublime or other editors.

Clion supports Makefile projects, so it is definitely easy to setup the kernel development environment with standard compiler. But with cross compilers it is not so obvious and you need to take further steps.

Some important prerequisite

If you can use the system crosscompiler, it is only matter of installing it in the PATH and ensure the correct variable is passed to Clion in the correct way. But in my system it was not the case, because my compiler is not the only cross compiler with a specific prefix I’m using. Indeed I may have different flavours of arm-linux-gnueabihf-gcc, for example if I am using different sysroots.

So the important part here is one: there seems to have some bug in clion, so that you can’t specify a path to your arm-linux-gnusomething- toolchain, and it is not preprocessed as expected. So, you need the compiler is reachable from your PATH, but you can use a different crosscompiler in your specific path to compile and link and everything.

I repeat: if you are using arm-linux-gnueabihf-gcc in a local path, just install some arm-linux-gnueabihf-gcc compiler systemwide.

The Makefile is smart enough to use your SDK compiler, while clion is able to preprocess the setup, compile the kernel and driver and generate and load all cross references so it can spot errors and all the nice stuff that makes our life so easy.

The normal setup

Then you need a few step to load the project.

First, open the project as a Makefile project.

Import the new system crosscompiler if necessary, in the Build, execution, deploy > Toolchains section of the settings. Your crosscompiler will be the system arm-linux-gnueabihf-gcc or whatever you are using.

Configure the Makefile: In the Build, execution, deploy > Makefile section, add a few lines in the following sections:

  • Build Options: --makefile=Makefile ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=../install DEPMOD=/opt/arm-buildroot-linux-gnueabihf_sdk-buildroot/sbin/depmod. This will install the modules outside the project directory (note the double-dots), otherwise clion will be stuck in a deadloop, due to the linking to the kernel sources that will be the parent directory of install!

  • Pre-configuration commands: ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- yourboard_defconfig this will instruct clion to configure the project with your board default configuration, allowing it to understand what files to parse

  • Make targets arguments: --makefile=Makefile V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- this will tell clion to add these arguments to any target command.

  • build target can be set to “all” or to any target that will build anything you need, for example, zImage or modules.

Makefile settings screen

Add as many targets as you want in the execution menu. I have 5 Makefile targets, named “defconfig”, “zImage”, “modules”, “clean”, “install_modules”. This way I can click on the dropdown run box and compile as needed. But clicking on “build all” should be enough if you have configured your Makefile properly.

Run targets screen

This should make your IDE usable.