The document shows the steps to create Linux kernel headers of SP7350 platforms.
Table of Contents
Download Source Files
Please refer to the A Guide to Downloading and Compiling SP7350 Code for downloading and compiling the source files for the SP7350 platform.
Configure Build Environment (create linux/kernel/.config)
For example, to configure the build environment for booting from an SD card and using BusyBox for the SP7350 Ev board:
Navigate to the project's top folder and execute make config. This will open a configuration menu with customization options:
Select the board by pressing 1 for "SP7350 Ev Board."
Choose the boot device; for instance, press 5 for booting from the SD card.
Opt for the Linux root file-system by pressing 1 for “BusyBox 1.31.1.”
Choose image security by pressing 1 for building “No secure” images.
After making your selections, the system will configure the build environment. This may take several seconds to minutes depending on your computer's performance. Please wait for the process to complete.
Build Code (create linux/kernel/Module.symvers)
Once configurations are set, initiate the build process with the following command:
make
If you're not using the English version of Ubuntu, use:
LANG=C make
This command ensures that make uses English language settings. The build process will compile the code based on your configurations, typically taking a few minutes. Please be patient and let the build complete.
Create Linux Kernel-headers
Generate Linux kernel headers by running:
make headers
After completion, list the contents of the project's top folder using the ll command. The Linux kernel headers will be stored in the linux-headers-5.10.201 folder.
wellslu@scdiu3:~/Q654$ ll total 68 drwxr-xr-x 12 wellslu sp 4096 Apr 24 13:16 ./ drwxr-xr-x 31 wellslu sp 4096 Apr 24 12:58 ../ drwxr-xr-x 6 wellslu sp 4096 Nov 15 15:38 boot/ drwxr-xr-x 3 wellslu sp 4096 Apr 24 13:00 build/ -rw-r--r-- 1 wellslu sp 284 Apr 24 13:06 .config drwxr-xr-x 7 wellslu sp 4096 Mar 21 12:02 crossgcc/ drwxr-xr-x 3 wellslu sp 4096 Nov 15 15:38 firmware/ drwxr-xr-x 9 wellslu sp 4096 Apr 24 13:00 .git/ -rw-r--r-- 1 wellslu sp 14 Apr 24 13:00 .gitignore -rw-r--r-- 1 wellslu sp 1117 Nov 15 15:38 .gitmodules drwxr-xr-x 7 wellslu sp 4096 Nov 15 15:40 ipack/ drwxr-xr-x 4 wellslu sp 4096 Nov 15 15:38 linux/ drwxr-xr-x 6 wellslu sp 4096 Apr 24 13:16 linux-headers-5.10.201/ -rw-r--r-- 1 wellslu sp 23 Nov 15 15:38 Makefile drwxr-xr-x 5 wellslu sp 4096 Dec 29 13:20 optee/ drwxr-xr-x 3 wellslu sp 4096 Apr 24 13:10 out/ -rw-r--r-- 1 wellslu sp 1007 Mar 5 11:55 README.md wellslu@scdiu3:~/Q654$
Refer to content of folder: linux-headers-5.10.201
wellslu@scdiu3:~/Q654$ ll linux-headers-5.10.201/ total 736 drwxr-xr-x 6 wellslu sp 4096 Apr 24 13:16 ./ drwxr-xr-x 12 wellslu sp 4096 Apr 24 13:16 ../ drwxr-xr-x 3 wellslu sp 4096 Apr 24 13:16 arch/ -rw-r--r-- 1 wellslu sp 135525 Apr 24 13:16 .config -rw-r--r-- 1 wellslu sp 39 Apr 24 13:16 .gitignore drwxr-xr-x 4 wellslu sp 4096 Apr 24 13:16 include/ drwxr-xr-x 2 wellslu sp 4096 Apr 24 13:16 kernel/ -rw-r--r-- 1 wellslu sp 141 Apr 24 13:16 Makefile -rw-r--r-- 1 wellslu sp 1044 Apr 24 13:16 .missing-syscalls.d -rw-r--r-- 1 wellslu sp 576967 Apr 24 13:16 Module.symvers drwxr-xr-x 8 wellslu sp 4096 Apr 24 13:16 scripts/ lrwxrwxrwx 1 wellslu sp 31 Apr 24 13:16 source -> /home/wellslu/Q654/linux/kernel/ wellslu@scdiu3:~/Q654$
Install Linux kernel-headers
Before using the Linux kernel headers, copy the linux-headers-5.10.201 folder to /usr/src/ on your target board. Refer to report of ll command in Ubuntu where linux-headers has been copied to:
sunplus@ubuntu:/usr/src$ ll linux-headers-5.10.201/ total 736 drwxr-xr-x 6 4031 501 4096 Apr 24 2024 ./ drwxr-xr-x 3 root root 4096 Mar 27 21:50 ../ drwxr-xr-x 3 4031 501 4096 Apr 24 2024 arch/ -rw-r--r-- 1 4031 501 135525 Apr 24 2024 .config -rw-r--r-- 1 4031 501 39 Apr 24 2024 .gitignore drwxr-xr-x 4 4031 501 4096 Apr 24 2024 include/ drwxr-xr-x 2 4031 501 4096 Apr 24 2024 kernel/ -rw-r--r-- 1 4031 501 141 Apr 24 2024 Makefile -rw-r--r-- 1 4031 501 1044 Apr 24 2024 .missing-syscalls.d -rw-r--r-- 1 4031 501 576967 Apr 24 2024 Module.symvers drwxr-xr-x 8 4031 501 4096 Apr 24 2024 scripts/ lrwxrwxrwx 1 4031 501 31 Apr 24 2024 source -> /home/wellslu/Q654/linux/kernel sunplus@ubuntu:/usr/src$
Remove the soft link named source in /usr/src/linux-headers-5.10.201/ as it's unnecessary.
Create a soft link named build at /lib/modules/5.10.201/ pointing to /usr/src/linux-headers-5.10.201:
sunplus@ubuntu:/usr/src/linux-headers-5.10.201$ sudo rm source sunplus@ubuntu:/usr/src/linux-headers-5.10.201$ sudo ln -s /usr/src/linux-headers-5.10.201 /lib/modules/5.10.201/build sunplus@ubuntu:/usr/src/linux-headers-5.10.201$ ll /lib/modules/5.10.201/build/ total 736 drwxr-xr-x 6 4031 501 4096 Mar 27 21:53 ./ drwxr-xr-x 3 root root 4096 Mar 27 21:50 ../ drwxr-xr-x 3 4031 501 4096 Apr 24 2024 arch/ -rw-r--r-- 1 4031 501 135525 Apr 24 2024 .config -rw-r--r-- 1 4031 501 39 Apr 24 2024 .gitignore drwxr-xr-x 4 4031 501 4096 Apr 24 2024 include/ drwxr-xr-x 2 4031 501 4096 Apr 24 2024 kernel/ -rw-r--r-- 1 4031 501 141 Apr 24 2024 Makefile -rw-r--r-- 1 4031 501 1044 Apr 24 2024 .missing-syscalls.d -rw-r--r-- 1 4031 501 576967 Apr 24 2024 Module.symvers drwxr-xr-x 8 4031 501 4096 Apr 24 2024 scripts/ sunplus@ubuntu:/usr/src/linux-headers-5.10.201$
Generate kernel scripts for aarch64 and copy scripts to /usr/src/linux-headers-5.10.201
sudo apt update sudo apt install build-essential fakeroot libncurses5-dev libssl-dev ccache libncurses-dev bison flex libelf-dev wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.10.201.tar.xz tar -xf linux-5.10.201.tar.xz cd linux-5.10.201 cp /usr/src/linux-headers-5.10.201/.config ./ make oldconfig make prepare make modules_prepare make scripts sudo cp -rf scripts/ /usr/src/linux-headers-5.10.201/
Build kernel module
Change gcc version to be 12.3
sudo apt-get install gcc-12 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 12
Create a sample kernel module with hello.c and Makefile.
Content of hello.c:
#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> static int __init hello_init(void) { printk(KERN_INFO "Hello, World!\n"); return 0; } static void __exit hello_exit(void) { printk(KERN_INFO "Goodbye, World!\n"); } module_init(hello_init); module_exit(hello_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Your Name"); MODULE_DESCRIPTION("A simple Hello World Kernel Module");
Content of Makefile:
obj-m += hello.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
Build module:
sunplus@ubuntu:~/code/module-temp$ make make -C /lib/modules/5.10.201/build M=/home/sunplus/code/module-temp modules make[1]: Entering directory '/usr/src/linux-headers-5.10.201' CC [M] /home/sunplus/code/module-temp/hello.o MODPOST /home/sunplus/code/module-temp/Module.symvers CC [M] /home/sunplus/code/module-temp/hello.mod.o LD [M] /home/sunplus/code/module-temp/hello.ko make[1]: Leaving directory '/usr/src/linux-headers-5.10.201'
It will get hello.ko and you can probe this module with insmod command. You will see this module with lsmod command.
sunplus@ubuntu:~/code/module-temp$ sudo insmod hello.ko sunplus@ubuntu:~/code/module-temp$ lsmod Module Size Used by hello 16384 0 galcore 794624 0 edt_ft5x06 32768 0 sp7350_rng 16384 0 rng_core 24576 1 sp7350_rng
Another way to build kernel module with DKMS. For introduction of DKMS in ubuntu, please refer to below link:
dkms - Dynamic Kernel Module Support
Install DKMS
sudo apt install dkms
Create a sample DKMS module:
sudo mkdir -p /usr/src/mymodule-1.0 cd /usr/src/mymodule-1.0 sudo su echo -e "obj-m += mymodule.o\nall:\n\tmake -C /lib/modules/\$(uname -r)/build M=\$(PWD) modules\nclean:\n\tmake -C /lib/modules/\$(uname -r)/build M=\$(PWD) clean" > /usr/src/mymodule-1.0/Makefile echo -e "#include <linux/init.h>\n#include <linux/module.h>\nstatic int __init mymodule_init(void){return 0;}\nstatic void __exit mymodule_exit(void){}\nmodule_init(mymodule_init);\nmodule_exit(mymodule_exit);\nMODULE_LICENSE(\"GPL\");" > /usr/src/mymodule-1.0/mymodule.c echo -e "PACKAGE_NAME=\"mymodule\"\nPACKAGE_VERSION=\"1.0\"\nBUILT_MODULE_NAME[0]=\"mymodule\"\nDEST_MODULE_LOCATION[0]=\"/updates/dkms/\"\nAUTOINSTALL=\"yes\"" > /usr/src/mymodule-1.0/dkms.conf exit
Add ,build and install DKMS module to system
sunplus@ubuntu:/usr/src/mymodule-1.0$ sudo dkms add -m mymodule -v 1.0 Creating symlink /var/lib/dkms/mymodule/1.0/source -> /usr/src/mymodule-1.0 sunplus@ubuntu:/usr/src/mymodule-1.0$ sudo dkms build -m mymodule -v 1.0 Kernel preparation unnecessary for this kernel. Skipping... Building module: cleaning build area... make -j4 KERNELRELEASE=5.10.201 -C /lib/modules/5.10.201/build M=/var/lib/dkms/mymodule/1.0/build.... cleaning build area... sunplus@ubuntu:/usr/src/mymodule-1.0$ sudo dkms install -m mymodule -v 1.0 mymodule.ko: Running module version sanity check. - Original module - No original module exists within this kernel - Installation - Installing to /lib/modules/5.10.201/updates/dkms/ depmod... sunplus@ubuntu:/usr/src/mymodule-1.0$ sudo modprobe mymodule sunplus@ubuntu:/usr/src/mymodule-1.0$ lsmod Module Size Used by mymodule 16384 0 hello 16384 0 galcore 794624 0 edt_ft5x06 32768 0 sp7350_rng 16384 0 rng_core 24576 1 sp7350_rng
Appendix: List of target headers in Makefile within Q654_code_folder/build/
headers: @KERNELRELEASE=$(shell cat $(LINUX_PATH)/include/config/kernel.release 2>/dev/null) @if ! [ -f $(LINUX_PATH)/.config ]; then \ echo File \'$(LINUX_PATH)/.config\' does not exist!; \ exit 1; \ fi @if ! [ -f $(LINUX_PATH)/Module.symvers ]; then \ echo File \'$(LINUX_PATH)/Module.symvers\' does not exist!; \ exit 1; \ fi rm -rf linux-headers-$(KERNELRELEASE) mkdir -p linux-headers-$(KERNELRELEASE) cp -f $(LINUX_PATH)/.config linux-headers-$(KERNELRELEASE) cp -f $(LINUX_PATH)/Module.symvers linux-headers-$(KERNELRELEASE) $(MAKE_ARCH) $(MAKE_JOBS) -C $(LINUX_PATH) CROSS_COMPILE=$(CROSS_COMPILE_FOR_LINUX) mrproper $(MAKE_ARCH) $(MAKE_JOBS) -C $(LINUX_PATH) O=../../linux-headers-$(KERNELRELEASE) CROSS_COMPILE=$(CROSS_COMPILE_FOR_LINUX) modules_prepare $(MAKE_ARCH) $(MAKE_JOBS) -C $(LINUX_PATH) headers_install INSTALL_HDR_PATH=../../linux-headers-$(KERNELRELEASE) CROSS_COMPILE=$(CROSS_COMPILE_FOR_LINUX) rm linux-headers-$(KERNELRELEASE)/source cp -rf $(LINUX_PATH)/include linux-headers-$(KERNELRELEASE) mkdir -p linux-headers-$(KERNELRELEASE)/arch cp -rf $(LINUX_PATH)/arch/arm64 linux-headers-$(KERNELRELEASE)/arch cp -f $(LINUX_PATH)/Makefile linux-headers-$(KERNELRELEASE) cp -rf $(LINUX_PATH)/scripts linux-headers-$(KERNELRELEASE)