Linux kernel 5.0 增加 System Call

Download kernel source code

我用的 kernel source code 是從 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git clone 的,寫這篇的版本是 5.0.0-rc3

1
$ git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git linux-stable

Add system call

首先在 kernel source code root 建立一個資料夾 mysyscall/

1
2
$ cd linux-stable
$ mkdir mysyscall

新增 mysyscall/hello.c、加入新的 system call sys_hello()(不可免俗的來 hello world 一下):

mysyscall/hello.c
1
2
3
4
5
6
#include <linux/kernel.h>

asmlinkage long sys_hello(void) {
printk("Hello Kernel World!\n");
return 0;
}

新增 mysyscall/Makefile 編譯 hello.c

mysycall/Makefile
1
obj-y := hello.o

修改 Makefile 下面這行:

Makefile
1
core-y		+= kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/

加入 mysyscall/

Makefile
1
core-y		+= kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/ mysyscall/

接下來將 system call 加入 system call header file,在 include/linux/syscalls.h 最下面 #endif 前加入以下這行。

include/linux/syscalls.h
1
asmlinkage long sys_hello(void);

最後在 system call table 加入新 entry。我是 64bit,system call table 在 arch/x86/entry/syscalls/syscall_64.tbl

arch/x86/entry/syscalls/syscall_64.tbl
1
2
3
4
5
6
330	common	pkey_alloc		__x64_sys_pkey_alloc
331 common pkey_free __x64_sys_pkey_free
332 common statx __x64_sys_statx
333 common io_pgetevents __x64_sys_io_pgetevents
334 common rseq __x64_sys_rseq
335 64 hello sys_hello

加在 64bit 區域的最後面,335 是新 system call 的編號。後面還有 500 多編號的是 32bit 的 system call。

Build and install

改完後當然是 compile 跟安裝啦!

1
2
3
4
$ make menuconfig       # 如果之前設定過可以不用
$ make # 可以加 -j N 來平行編譯
$ sudo make modules_install
$ sudo make install

make 後就可以去睡個覺惹~(無誤)

Call new system call

經過「build、install、打不開、改一改 config 再 build、還是打不開…」的千山萬水(?)後,終於用新 kernel 成功開機,來用新 system call say hello 吧!

hello.c
1
2
3
4
5
6
7
8
9
#include <unistd.h>
#include <sys/syscall.h>
#include <stdio.h>

int main() {
long ret = syscall(335); // 335 是剛剛的 system call 編號
printf("sys_hello return %d\n", ret);
return 0;
}

執行正常會看到:

1
sys_hello return 0

在 kernel 裡用 printk() 印出的訊息可以用指令 dmesg(需要 root 權限)看到:

1
2
3
4
[    3.211745] AVX2 version of gcm_enc/dec engaged.
[ 3.211748] AES CTR mode by8 optimization enabled
[ 3.459866] IPv6: ADDRCONF(NETDEV_CHANGE): ens3: link becomes ready
[ 81.608954] Hello Kernel World!

以上是在 Linux kernel 5.0.0 加個新 system call 的方式,基本上 4.x 也差不多(5.0 好像是因為 4.x 版本號太多才跳的…)

所謂的千山萬水(??)…

數不清重編又重開了幾次……

kernel 的 config 我是用原本系統裡,為了縮短編譯時間再 make menuconfig 拔掉很多不需要的設定,畢竟只是用個 VM 編那麼多硬體 driver 是要幹嘛……但拔到不該拔的就打不開啦哈哈哈……

再來是我想在 host OS 上 build、裝進 VM 裡開,試圖搬 kernel、system map、module 然後做 initramfs,但不知為何這麼幹就是開不起來,同樣的 code 在 VM build 然後 install 就開起來了……應該是裝的時候有東西沒弄好……Orz

最後……先 NFS 吧~(喂