Quick Start to Rebuild Linux Kernel
This chapter describes
- How to upgrade and rebuild Linux Kernel from Linux 4.x to Linux 5.x in Debian 10.10.
- How to enable and disable new Linux Device Module.
Rebuild Linux Kernel
Download and install Debian 10.10
to your device, becasue its Linux Kernel version is 4.x, we need to upgrade to Linux Kernel 5.x. In my case I choose debian-live-10.10.0-amd64-xfce.iso
.
Check the current Linux Kernel version.
# uname -a
config-4.19.0-17-amd64
Upgrade the essential packages for wireless capture
$ sudo apt-get update && sudo apt-get upgrade
$ sudo apt-get install -y openssh-server vim net-tools usbutils pciutils
$ sudo apt-get install -y build-essential libncurses-dev bison flex libssl-dev libelf-dev
$ sudo apt-get install -y git fakeroot ncurses-dev xz-utils bc
$ sudo apt-get install -y software-properties-common rsync
$ sudo apt-get install -y libncurses5-dev gcc grub2 wget dwarves tree curl
$ sudo service sshd restart
Add apt repository to support linux-image-5.10.0
$ sudo add-apt-repository 'deb http://deb.debian.org/debian buster-backports main'
$ sudo apt-get update
$ sudo apt-get install linux-image-5.10.0-0.bpo.7-amd64
$ sync reboot
After rebooted. Check current Linux version to make sure its Linux Kernel 5.10
# uname -a
Linux vultr.guest 5.10.0-0.bpo.7-amd64 #1 SMP Debian 5.10.40-1~bpo10+1 (2021-06-04) x86_64 GNU/Linux
Add apt repository to support firmware-misc-nonfree
(Optional)
$ sudo add-apt-repository 'deb http://ftp.de.debian.org/debian stretch main non-free'
$ sudo apt-get update
$ sudo apt-get install firmware-misc-nonfree
$ sync; sudo reboot
Rebuild Linux kernel
$ sudo apt-get update ; sudo apt-get upgrade; sudo apt autoremove
$ sudo apt-cache search kernel | grep source | grep 5.10
linux-source-5.10 - Linux kernel source for version 5.10 with Debian patches
$ sudo apt-get install linux-source-5.10
$ sudo cp /usr/src/linux-source-5.10.tar.xz .
$ sudo chgrp ed linux-source-5.10.tar.xz
$ sudo chown ed linux-source-5.10.tar.xz
$ tar xvf linux-source-5.10.tar.xz
$ cd linux-source-5.10/
$ cp /boot/config-$(uname -r) .config
$ scripts/config --set-str SYSTEM_TRUSTED_KEYS ""
Revise CONFIG_DEBUG_INFO_BTF to avoid build error
CONFIG_DEBUG_INFO_BTF=n
Compile and Install the Kernel
$ sudo add-apt-repository 'deb http://http.us.debian.org/debian/ buster main contrib non-free'
$ sudo make -j $(nproc) V=99 deb-pkg 2>&1 | tee build.log | grep -i error
$ cd ..
As the result, there are around four deb files.
$ ls -lah | grep deb
-rw-r--r-- 1 ed ed 7.7M Jul 8 23:56 linux-headers-5.10.40_5.10.40-5_amd64.deb
-rw-r--r-- 1 ed ed 50M Jul 8 23:58 linux-image-5.10.40_5.10.40-5_amd64.deb
-rw-r--r-- 1 ed ed 893M Jul 9 00:25 linux-image-5.10.40-dbg_5.10.40-5_amd64.deb
-rw-r--r-- 1 ed ed 1.1M Jul 8 23:57 linux-libc-dev_5.10.40-5_amd64.deb
Install
$ sudo dpkg -i linux-image-5.10.40_5.10.40-5_amd64.deb
$ sudo dpkg -i linux-headers-5.10.40_5.10.40-5_amd64.deb
$ sync
$ sudo reboot
Verification
$ uname -a
$ Linux ed-pc 5.10.40 #5 SMP Thu Jul 8 21:17:59 CST 2021 x86_64 GNU/Linux
Linux Kernel Module
Hello, World
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
Build the module
$ make
make -C /usr/src/linux-headers-5.10.40/ M=/home/ed/hello modules
make[1]: Entering directory '/usr/src/linux-headers-5.10.40'
CC [M] /home/ed/hello/hello.o
MODPOST /home/ed/hello/Module.symvers
LD [M] /home/ed/hello/hello.ko
make[1]: Leaving directory '/usr/src/linux-headers-5.10.40'
Project Layout (As a result)
$ tree
.
├── hello.c
├── hello.ko
├── hello.mod
├── hello.mod.c
├── hello.mod.o
├── hello.o
├── Makefile
├── modules.order
└── Module.symvers
0 directories, 9 files
Verification
$ make test
[ 5163.936243] hello: loading out-of-tree module taints kernel.
[ 5163.936708] Hello world !
hello 16384 0
hello 16384 0 - Live 0x0000000000000000 (OE)
[ 5360.557612] Bye !
Proc Filesystem
📝 Functions:
⮚ struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent);
⮚ static inline struct proc_dir_entry *proc_create(const char *name, umode_t mode,struct proc_dir_entry *parent, const struct file_operations *proc_fops);
⮚ unsigned long copy_to_user(void __user * to, const void * from, unsigned long n);
⮚ int copy_from_user_toio(volatile void __iomem * dst, const void __user * src, size_t count);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
~~ TBD ~~
Accessing IO Port
#include <linux/ioport.h>
struct resource *request_region(unsigned long first, unsigned long n, const char *name);
void release_region(unsigned long start, unsigned long n);
- Port-mapped I/O (PMIO)
- Memory-mapped I/O (MMIO)
Framwbuffer
- Function
seq_file interface
BPF
Precondition
$ sudo apt-get install clang
Hello, BPF
a.c
int f(int x) {
return x + 1;
}
Make
$ clang -c -S -emit-llvm a.c # < = a.ll (LLVM IR)
$ clang -c -S -target bpf a.c # < = a.s (eBPF)
$ clang -c -target bpf a.c # < = a.o (eBPF bytecode)
$ objcopy -I elf64-little -O binary a.o a.bin # < = Extract eBPF bytecode
Coredump
Appendix
Tag Linux Kernel Code
An example to tag kernel code for x86 system.
$ wget https://git.kernel.org/torvalds/t/linux-5.14-rc1.tar.gz
$ tar xvf linux-5.14-rc1.tar.gz
$ cd linux-5.14-rc1/
$ make ARCH=x86 cscope tags
for more detail, please check linux kernel make tag variable