Reputation: 5989
I'm trying to build a simple kernel module for arm64 machine from my x86_64 machine. The target and host are both using ubuntu 20.04 as OS. First I tried building a simple kernel module for the host (x86_64) using this Makefile. By the way, uname -r
gives 5.4.0-77-generic in my case.
obj-m += chr_drv_ex1.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
The program builds and runs ok.
Now I want to try it for arm64 ubuntu 20.04 machine target (I have a virtual machine). One idea is to copy the /lib/modules/5.4.0-77-generic/build directory from the arm64 machine and use the folder as the -C option for my cross-compile. But I soon found that this 'build' directory a symbolic link to /usr/src/linux-headers-5.4.0-77-generic and many files or directories there are also symbolic links to those under /usr/src/linux-headers-5.4.0-77. So I need to copy the /lib/modules/5.4.0-77-generic, /usr/src/linux-headers-5.4.0-77 and /usr/src/linx-headers-5.4.0-77-generic. And this doesn't seem nice.
So my question is: how should I provide the -C option (where build scripts are located) in this case? Can I just install linux-headers-5.4.0-77 and linux-headers-5.4.0-77-generic in my host system and use them? (I tried it but I have this compile error:
make ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu- -C /lib/modules/5.4.0-77-generic/build M=/home/ckim/pprj/qemu_test/test_ldd modules
make[1]: Entering directory '/usr/src/linux-headers-5.4.0-77-generic'
CC [M] /home/ckim/pprj/qemu_test/test_ldd/chr_drv_ex1.o
In file included from ./include/linux/types.h:6,
from ./include/linux/limits.h:6,
from ./include/linux/kernel.h:7,
from /home/ckim/pprj/qemu_test/test_ldd/chr_drv_ex1.c:1:
./include/uapi/linux/types.h:5:10: fatal error: asm/types.h: No such file or directory
5 | #include <asm/types.h>
| ^~~~~~~~~~~~~
compilation terminated.
make[2]: *** [scripts/Makefile.build:271: /home/ckim/pprj/qemu_test/test_ldd/chr_drv_ex1.o] Error 1
make[1]: *** [Makefile:1762: /home/ckim/pprj/qemu_test/test_ldd] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-5.4.0-77-generic'
make: *** [Makefile:4: all] Error 2
Upvotes: 0
Views: 1282
Reputation: 5989
@Tsyvarev told me in his comment that I should actually build the kernel and the -C
option should point to the kernel build directory. So here is what I did with a little more search. (Thanks @Tsyvarev!)
Suppose you are in the directory where you have your kernel module *.c source program (chr_drv_ex1.c here) and the Makefile, and I have copied /boot/config-5.4.0-77-generic from a virtual machine that I'm making the kernel module for to ./u20_config. To get the .config file for the currently running kernel, see here.
sudo apt install linux-source-5.4.0 (/usr/src/linux-source-5.4.0 is installed)
tar -xf /usr/src/linux-source-5.4.0/linux-source-5.4.0.tar.bz2
cd linux-source-5.4.0
cp ../u20_config .config (u20_config is from ubuntu-20.04 VM)
make ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu- -j`nproc`
cd ..
make (this builds kernel module and app, see Makefile)
And this is the Makefile I used (test_chr_drv is the application using the driver).
export CROSS_COMPILE:=aarch64-none-linux-gnu-
export ARCH:=arm64
obj-m += chr_drv_ex1.o
export KDIR:=linux-source-5.4.0
all: test_chr_drv
make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KDIR) M=$(PWD) modules
clean:
make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KDIR) M=$(PWD) clean
rm -f test_chr_drv
test_chr_drv: test_chr_drv.c
$(CROSS_COMPILE)gcc $^ -o $@
Upvotes: 0