Skip to content
This repository has been archived by the owner on Jan 28, 2022. It is now read-only.

ldd3 project

Wang Qi edited this page May 7, 2021 · 12 revisions

Here we will use ldd3 project to verify the IDE environment.

Get the gccIDE container

Follow the instructions in Quick Guide section to setup the gccIDE container. Don't forget to create the proj-vol volume.

Add the linux kernel source

Please execute the following command with the root privilege. LDD3 project need kernel source tree to compile.

# apk add linux-lts-dev

Get the project source

% cd ~/proj
% git clone https://github.com/martinezjavier/ldd3.git
% cd ldd3

export the KERNELDIR

% export KERNELDIR=/lib/modules/5.10.29-0-lts/build/

Why we need the above KERNELDIR? If you check the Makefile in misc-modules directory. You will find the how the script setup the KERNELDIR. On some system the Makefile is smart to determine the kernel directory. On this IDE, for uname -r docker returns 5.10.25-linuxkit, while alpine linux-lts-dev returns 5.10.29-0-lts. Amazing?

# To build modules outside of the kernel tree, we run "make"
# in the kernel source tree; the Makefile these then includes this
# Makefile once again.
# This conditional selects whether we are being included from the
# kernel Makefile or not.

LDDINC=$(PWD)/../include
EXTRA_CFLAGS += -I$(LDDINC)

ifeq ($(KERNELRELEASE),)

    # Assume the source tree is where the running kernel was built
    # You should set KERNELDIR in the environment if it's elsewhere
    KERNELDIR ?= /lib/modules/$(shell uname -r)/build
    # The current directory is passed to sub-makes as argument
    PWD := $(shell pwd)

modules:
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

modules_install:
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install

clean:
        rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.mod modules.order *.symvers

.PHONY: modules modules_install clean

else
    # called from kernel build system: just declare what our modules are
    obj-m := hello.o hellop.o seq.o jiq.o sleepy.o complete.o \
             silly.o faulty.o kdatasize.o kdataalign.o jit.o
endif

Make with bear

The following is one example to generate compile_commands.json. Here, bear will run make as usual and generate compile_commands.json in the current directory.

We also run make clean to show the result clearly. Please note the generated compile_commands.json file.

% cd ~/proj/ldd3/scullc
% bear -- make
make -C /lib/modules/5.10.29-0-lts/build M=/home/ide/proj/ldd3/scullc modules
make[1]: Entering directory '/usr/src/linux-headers-5.10.29-0-lts'
  CC [M]  /home/ide/proj/ldd3/scullc/main.o
  CC [M]  /home/ide/proj/ldd3/scullc/scull-shared/scull-async.o
  LD [M]  /home/ide/proj/ldd3/scullc/scullc.o
  MODPOST /home/ide/proj/ldd3/scullc/Module.symvers
  CC [M]  /home/ide/proj/ldd3/scullc/scullc.mod.o
  LD [M]  /home/ide/proj/ldd3/scullc/scullc.ko
make[1]: Leaving directory '/usr/src/linux-headers-5.10.29-0-lts'
% make clean
$ ls 
Makefile               main.c                 scull-shared           scullc_load
compile_commands.json  mmap.c                 scullc.h               scullc_unload

Edit source file

Now you can edit the any source file under scullc directory. You can also try misc-modules directory to repeat the above process.

From the above example, Generate the compile_commands.json file with bear is easy.

insmod and rmmod

When I tried to use Docker desktop for Mac to perform the insmod command, the docker kernel refused with the "Invalid module format" response. The root cause is: Kernel from which you build your kernel module and to which you are inserting module should be of same version.

Docker desktop for Mac use kernel 5.10.25-linuxkit, gccIDE is based on alpine 3.13, the kernel version is 5.10.29-0-lts for package linux-lts-dev. Even you can build the kernel module in gccIDE. You can't install it in the docker environment. Their kernel version is simply different.

The quick solution is:

  • Create an alpine instance in virtualbox. The alpine instance shares SOME directory with the native Mac OS X.
  • Use gccIDE container which share the same SOME directory with the native Mac OS X.
  • For development job, use gccIDE and SOME directory to access the source code.
  • For kernel install and remove job, use the alpine instance and SOME directory to access the kernel module.

Now your can insmod and rmmod the kernel module you just developed.

Clone this wiki locally