前情提要

因Linux Operating System課的project需要,人生第一次編Kernel就獻給他惹,所以怕忘就順手筆記一下。

環境

使用Ubuntu 16.04 LTS i386 Desktop 要編的Kernel是3.10版

過程

一開始當然要先裝好Linux環境(我是裝Ubuntu) 然後決定你要編的Kernel,並載下來解壓縮 (Kernel source可以到https://www.kernel.org 下載) 我這邊解壓縮出來後是linux-3.10.104/

1
$ cd linux-3.10.104/

進去之後,要新增一個system call 創一個資料夾用來放我們system call的code

1
2
$ mkdir mycall
$ cd mycall

新增一個檔案helloworld.c,就是我們system call的程式

1
$ vim helloworld.c
1
2
3
4
5
#include <linux/kernel.h>
asmlinkage int sys_helloworld(void) {
    printk("kaibro ininder\n");
    return 1;
}

再來新增Makefile,用來確保我們的程式會被編譯進Kernel

1
2
$ vim Makefile
obj-y := helloworld.o

再來回上一層目錄,修改Makefile

1
2
3
4
5
6
$ cd ..
$ vim Makefile
core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
找到這行,在最後面新增 mycall/

core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ mycall/

這是為了告訴它,我們新的system call的source files在mycall資料夾裡

再來我們要新增我們的system call到system call table裡

1
2
3
4
5
// 如果是64位元系統,就是syscall_64.tbl
$ vim arch/x86/syscalls/syscall_32.tbl

在最後面新增一行,原本system call只到350號,所以這邊就填351號
351   i386  helloworld  sys_helloworld

再來修改system call header

1
2
3
4
5
6
7
$ vim include/linux/syscalls.h

在最下面(#endif前)新增一行
asmlinkage int helloworld(void);

這定義了我們system call的prototype
asmlinkage代表我們的參數都可以在stack裡取用

接著編譯kernel前要裝一些套件

1
$ sudo apt-get install libncurses5-dev

還有設定檔

1
2
3
$ sudo make menuconfig
// 這邊我都用預設的
$ sudo make oldconfig

最後就開始漫長的compile了!

1
$ sudo make

編完之後,就安裝到我們系統上

1
$ sudo make modules_install install

裝好之後沒問題,就重開機,用我們新的kernel開機

但是grub選單,預設好像是關的

所以我們要先把它打開,再重開機

重開時記得選我們編的kernel

1
2
3
4
5
6
7
8
$ sudo vim /etc/default/grub
像我一樣找到下面這兩行,前面加#,把他們註解掉
#GRUB_HIDDEN_TIMEOUT=0
#GRUB_HIDDEN_TIMEOUT_QUIET=true

然後更新
$ sudo update-grub
之後重開機就能看到選單了

最後寫個小程式來檢驗是否成功新增system call

1
2
3
4
5
6
7
#include <syscall.h>
#include <sys/types.h>
int main()
{
    int a = syscall(351);
    return 0;
}

然後執行之後,用以下這指令看kernel有沒有輸出我們想要的訊息

1
$ dmesg

如果有看到"kaibro ininder",就代表成功惹~

後記

其實一開始我是裝Fedora 但不知為何總是一直失敗 一開始是虛擬機空間開太小 後來好不容易重灌好,也編完,卻莫名無法開機 想說是編太新版的Kernel炸掉,結果重編個相同版本的Kernel還是一樣 (前前後後大概編了6次吧….) 之後就果斷改用Ubuntu…