2017年5月4日 星期四

增加一個System Call 到Linux Kernel (v4.x)



確認你的一些套件有update到最新

$ sudo apt-get update
$ sudo apt-get upgrade



看你目前的 kernel 版本
$ uname -r















Kernel Archive 下載 kernel source
我下載的是目前較為穩定的 " 4.10.14 " kernel
你可以選擇你自己要的 kernel ~不一定要跟我一樣
























解壓縮下載下來的 linux-4.10.14.tar.xz 檔案
$ sudo su  //進入 root 模式
# tar -xvf linux-4.10.5.tar.xz -C /usr/src  //把檔案解壓縮到 /usr/src 目錄底下



先來建立資料夾
# cd /usr/src/linux-4.10.14  //把目錄轉到剛剛下載下來的kernel檔案夾裡
/usr/src/linux-4.10.14# mkdir hello  //在裡面創建一個名叫 hello 的資料夾
/usr/src/linux-4.10.14# cd hello  //進到 hello 資料夾裡



寫一個 hello.c
/usr/src/linux-4.10.14/hello# vim hello.c
//hello.c
#include <linux/kernel.h>
asmlinkage long sys_hello(void){
    printk("Hello World!\n");
    return 0;
}



在同一個目錄下再寫 Makefile
/usr/src/linux-4.10.14/hello# vim Makefile
請在 Makefile 裡面寫以下這樣
obj-y := hello.o



接著在 linux-4.10.14 目錄下改 Makefile
告訴你的compiler,新的 system call 可以在 hello 目錄中找到
/usr/src/linux-4.10.14/hello# cd ..  //往前移動一個目錄
/usr/src/linux-4.10.14# vim Makefile  //打開目錄下的 Makefile 



你可以在裡面找到一行 如下我括起來的地方


























請你在後面補上 hello
這樣 kernel 在編譯時才會到你的 hello 目錄
改成下面這樣
core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/ hello/



接著因為我的系統是 64 位元的 ((我想大部分的人都是))
所以我要去修改 syscall_64.tbl 檔
/usr/src/linux-4.10.14# cd arch/x86/entry/syscalls
/usr/src/linux-4.10.14/arch/x86/entry/syscalls# vim syscall_64.tbl



請你在最後一行添加上你的 system call ~ 
然後請把編號記住 等一下會用
<註:你會發現下面突然跳到500多號,那是放x32的東西,我們要擺在300多號那邊>





























接著編輯 syscalls.h 檔
將我們 syscall 的原型添加進檔案的最後一行 (#endif之前)
/usr/src/linux-4.10.14/arch/x86/entry/syscalls# cd ../../../..  //倒退四個目錄
/usr/src/linux-4.10.14# cd include/linux
/usr/src/linux-4.10.14/include/linux# vim syscalls.h
























最後就要準備編譯核心啦~~
先把會用到的套件安裝
$ sudo apt-get install fakeroot build-essential kernel-package
libncurses5 libncurses5-dev
//這個套件可以用來幫我們 build 出 kernel-package























選擇第二個 ~ 保持本地版本就好




接著我們來把 kernel 的 config (組態) 複製出來
/usr/src/linux-4.10.14# cp /boot/config-`uname -r` ./.config

然後 make menuconfig 來設定組態
/usr/src/linux-4.10.14 $ make menuconfig

會跑出以下畫面讓你設定 configuration

但是我的目的只是要加一個 system call
所以我直接 "按兩下 ESC 離開"
如果你有要做其他設定 可以去 google 看看



然後就可以 compile 你的 kernel 了
/usr/src/linux-4.10.14# make-kpkg clean  //先清理殘留的package
/usr/src/linux-4.10.14# fakeroot make-kpkg -j 4 --initrd
kernel_image kernel_headers
//-j 4 的意思是用四顆核心來跑 會比較快好 前提是你的核心要有4個哦 不然key進去後你的系統會死當
//等編譯完後會產生 kernel 的 image 和 headers


<註:如果你在編譯的時候出現 "fatal error: openssl/opensslv.h: No such file or directory" 錯誤訊息的話,表示你的 SSL 庫有缺失,請你先安裝下面套件後再重新編譯吧~>
$ sudo apt-get install python-pip python-dev libffi-dev libssl-dev libxml2-dev libxslt1-dev libjpeg8-dev zlib1g-dev

//再重下指令編譯
/usr/src/linux-4.10.14# fakeroot make-kpkg -j 4 --initrd
kernel_image kernel_headers



接著就等他編譯完吧 ~
根據電腦效能不同 需要的時間不一定 但是你可以先去睡個覺了



































等了好久終於跑完了~
他會在 /usr/src 路徑下產生了這個 kernel 的 image 和 headers
我們要用指令安裝他們
/usr/src $ sudo dpkg -i linux-image-4.10.14_4.10.14-
10.00.Custom_amd64.deb
/usr/src $ sudo dpkg -i linux-headers-4.10.14_4.10.14-
10.00.Custom_amd64.deb

//安裝完以後就重開機吧
/usr/src $ reboot




重開機以後 在用指令查看你的 kernel 版本有沒有變新的
$ uname -r
















可以看到 kernel 版本變成新的




最後來測試我們新加入的 system call 吧
$ vim hello.c
/*hello.c*/
#include <linux/kernel.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <stdio.h>
int main(){
    long int sys = syscall(332); //使用我們剛剛新增的 system call
    printf("sys_hello returned %ld\n", sys);  //print 出他的回傳值,若回傳-1代表出錯囉
    return 0;
}
//編譯 hello.c
$ gcc -g -Wall hello.c -o hello

//執行他
$ ./hello
















看到它回傳 0 就代表成功了




你可以使用 dmesg 指令來看 kernel 內的訊息
$ dmesg

























看到 kernel 裡面成功 printk 出了 Hello World! 字串

沒有留言:

張貼留言