/vscode-kernelmod-guide

A guide on developing linux kernel module with vscode and clangd

Visual Studio Code for Linux kernel module guide

This repository shows a guide on developing linux kernel module with vscode and clangd. This guide was made possible with amezin's vscode-linux-kernel. Some of the steps in this guide is arch specific.

Prerequisites

  1. Make sure you have clangd installed on your system:

    # arch as example
    $ sudo pacman -S clangd
    
  2. Make sure you have clangd vscode extension installed.

  3. Get a copy of your current kernel's source code [archwiki] and BUILD it. Building the kernel is necessary as the compilation database we wanted (compile_commands.json) can only be generated with the existence of kernel compile command files (*.cmd).

    # arch as example
    # install asp tool
    $ sudo pacman -S asp
    $ asp update linux
    $ asp export linux
    

    This gives you a directory named linux under your cwd and it contains the PKGBUILD script and the config for the kernel:

    linux
    ├── PKGBUILD
    └── config
    

    Now sync the build dependencies and get the kernel source with makepkg:

    $ makepkg --syncdeps --nobuild
    # sync depends, get the source but not build
    

    Note that makepkg might complain about some unknown GPG key, simply receive it:

    $ gpg --recv-keys --keyserver hkps://keys.openpgp.org XXXXXXXXXXXXXXXXXX
    

    Cloning the kernel source might take a significant amount of time, when finished you should get a directory structure as below:

    linux
    ├── archlinux-linux
    ├── config
    ├── keys
    ├── PKGBUILD
    └── src
    

    Where src/archlinux-linux would be the full kernel source. optionally, mv it to linux directory for convenience:

    $ mv ./src/archlinux-linux ./archlinux-linux-x.x.xx
    .
    ├── archlinux-linux-x.x.xx
    ├── config
    └── PKGBUILD
    
    
    

    Note that the kernel source already contains a proper .config file so no further configuring is needed unless with other needs, so just cd into the source directory and make it:

    $ cd archlinux-linux-x.x.xx
    $ make -j$(nproc)
    

    This will take around 20 minutes for a modern PC.

  4. Now after the building is done, use the python script provided in the kernel source to generate the compilation database for the kernel: (check if your cwd is archlinux-linux-x.x.xx)

    $ python ./scripts/clang-tools/gen_compile_commands.py
    

    This will gives you the database compile_commands.json under the kernel source directory archlinux-linux-x.x.xx.

    Generating this compilation database is important since clangd would look for this compilation database under all parent directories of the current active file. After completed this step, say you followed into the header file <linux/module.h> which is under archlinux-linux-x.x.xx/include/linux, clangd will happily accept archlinux-linux-x.x.xx/compile_commands.json and keep working. Without this you would get a hell BUNCH of errors.

  5. Finally, optionally export a shell parameter for the kernel source directory:

    export KDIR=/path/to/linux/archlinux-linux-x.x.xx
    

Workspace configurations

Now all the preparations are done and time for setting up our workspace for developing kernel module.

  1. Clone this repository recursively with its submodule vscode-linux-kernel under your workspace directory (say it's mymodule)

    $ cd mymodule
    $ git clone --recursive https://github.com/xuwd1/vscode-kernelmod-guide.git
    

    And you should get a directory structured as below:

    vscode-kernelmod-guide
    ├── .clangd
    ├── README.md
    └── vscode-linux-kernel
        ├── c_cpp_properties.json
        ├── generate_compdb.py
        ├── LICENSE
        ├── README.md
        ├── settings.json
        └── tasks.json
    
  2. cp the .clangd file to mymodule and $KDIR. This file is a clangd configuration file for suppressing some unwanted clangd errors complaining about unknown compiler driver options. These errors occur because that there are many gcc-specific compiler options in the generated compile commands and clangd (or to be precise, clang) just simply don't understand them. Trying to solve this problem by setting clangd option --query-driver will be in vain and thus our workaround is just remove those gcc-specific options.

  3. Build your module at least once for compile command files for your modules, say you have a C source file mymodule/hello.c , and what we want is the files named hello.o.cmd and hello.mod.o.cmd that would be generated by running:

    $ make -C $KDIR M=$PWD modules
    

    Note that your source files don't need to contain any useful things in this step as what we all want is just the compile command files.

  4. Finally, use amezin's script to generate the compilation database for your project:

    $ python3 ./vscode-kernelmod-guide/vscode-linux-kernel/generate_compdb.py -O $KDIR $(pwd)
    

    This generates the compile_commands.json under mymodule.

  5. Now you are good to go. clangd should be working just fine parsing either your own codes or the kernel source. Beware that you will need to repeat from step 3 whenever your project's file structure or the Makefile is changed.