-
Notifications
You must be signed in to change notification settings - Fork 0
ldd3 project
Here we will use ldd3 project to verify the gccIDE. We have three goals.
- Compile ldd3 project on alpine 3.13.
- Edit ldd3 project with gccIDE.
- Install/remove compiled module on alpine.
If you just want to compile the ldd3 project, please follow these steps.
You need either alpine 3.13 docker container or gccIDE docker container before the following steps.
% docker pull alpine:3.13
Please run the following commands with the root privilege in the new container.
- LDD3 project need kernel source tree to compile, on alpine, the package is
linux-lts-dev
. -
musl-dev
andlinux-headers
package provides header files required by compilation process.
# apk add linux-lts-dev musl-dev linux-headers
You need a normal user/group for the following commands. Using root is not a good idea.
% cd ~/proj
% git clone https://github.com/martinezjavier/ldd3.git
% cd ldd3
% 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. In the following Makefile, you will find how the script setups the KERNELDIR. On some system the Makefile is smart to determine the kernel location. On my Docker desktop for Mac, uname -r
returns 5.10.25-linuxkit
, while the package linux-lts-dev
believes it's 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
Now you can compile the ldd3 project as a whole project. During the compilation process, some sub-project may warn you. You can ignore them.
% cd ~/proj/ldd3
% make
Or you can just compile sub-project in the sub-directory.
$ cd ~/proj/ldd3/misc-modules
% make
If you want to edit the ldd3 project, please follow these steps. Remember the previous steps is also needed, edit/compile is a cycle.
Follow the instructions in Quick Guide section to set up the gccIDE. Don't forget to create the proj-vol
volume.
The following is the example to generate compile_commands.json
for scullc
. Here, bear will run make as usual and generate compile_commands.json
in the current directory. See here to know more about compile_commands.json
.
We also run make clean
to clean the result. Here we only concern 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
Now you can edit any source file under scullc
directory. You can also verify the Code completion, Find definition/declaration and find references. Please repeat the above process for other sub-directory to taste the support provided by gccIDE.
You can see generating the compile_commands.json
file with bear is easy. CMake also supports generating the compile_commands.json
.
The compile_commands.json
should be enough, In case you need, please copy and paste the following content into .ccls
file in project root directory ~/proj/ldd3
. Actually, the following parameters were extracted from compile_commands.json
by myself. Strictly speaking, the following step is not necessary if you successfully generate the compile_commands.json
. It's just the last remedy in case you need it.
gcc
%h
%c -std=gnu89
-DMODULE
-DCC_USING_FENTRY
-D__KERNEL__
-isystem
/usr/lib/gcc/x86_64-alpine-linux-musl/10.2.1/include
-I
/lib/modules/5.10.29-0-lts/build/arch/x86/include
-I
/lib/modules/5.10.29-0-lts/build/arch/x86/include/generated
-I
/lib/modules/5.10.29-0-lts/build/include
-I
/lib/modules/5.10.29-0-lts/build/arch/x86/include/uapi
-I
/lib/modules/5.10.29-0-lts/build/arch/x86/include/generated/uapi
-I
/lib/modules/5.10.29-0-lts/build/include/uapi
-I
/lib/modules/5.10.29-0-lts/build/include/generated/uapi
--gcc-toolchain=/usr
If you want to insmod / rmmod the developed module in docker environment you will fail. You can edit/compile the kernel module in docker environment. But you can't install/remove modules in docker environment. Even run docker with docker run --privileged
options, you will fail again.
When I tried to use Docker desktop for Mac to perform the insmod command, the docker kernel refused with the "Invalid module format"
. The root cause is: the Kernel from which you build your kernel module and to which you are inserting module should be of the same version. See LDD3 Page 26 for more detail.
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 the new module in the docker environment. Their kernel version is simply different.
The quick solution is:
- Create an alpine VM in virtualbox.
- For development job, use gccIDE to access the source code.
- For kernel install and remove job, use the alpine VM to access the kernel module.
-
ldd3 project on GitHub can help us to share the code between alpine VM and gccIDE.
- You can also use VirtualBox shared folders to share the code.
The idea behind this solution is to change the target kernel version to pass the kernel version dependency check. Now you can insmod and rmmod the kernel module you just developed.