You don't have javascript enabled. Good luck! :(

This is a test

You’ll find this post in your _posts directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run jekyll serve, which launches a web server and auto-regenerates your site when a file is updated.

To add new posts, simply add a file in the _posts directory that follows the convention YYYY-MM-DD-name-of-post.ext and includes the necessary front matter. Take a look at the source for this post to get an idea about how it works.

Jekyll also offers powerful support for code snippets:

def print_hi(name)
  puts "Hi, #{name}"
end
print_hi('Tom')
#=> prints 'Hi, Tom' to STDOUT.

Check out the Jekyll docs for more info on how to get the most out of Jekyll. File all bugs/feature requests at Jekyll’s GitHub repo. If you have questions, you can ask them on Jekyll Talk.

  May 4, 2017     WenYuan     Linux  UPDATE:

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

我的系統環境

  • 作業系統: Lubuntu 16.04
  • Kernel 版本: 4.8.0-49-generic


更新系統

  • 更新
sudo apt-get update
sudo apt-get upgrade
  • 查看你當前的 Kernel 版本
uname -r

picture01


下載 Kernel Source

Kernel Archive 下載 kernel source 我下載的是當時較為穩定的 “ 4.10.14 “ kernel 你可以選擇你自己要的 kernel , 不一定要跟我一樣

image


下載完後請進行解壓縮

# 進入 root 模式

sudo su

# 把檔案解壓縮到 /usr/src 目錄底下

tar -xvf linux-4.10.5.tar.xz -C /usr/src


建立資料夾

# 把目錄轉到剛剛下載下來的 kernel 檔案夾

cd /usr/src/linux-4.10.14

# 在裡面創建一個名叫 hello 的資料夾

mkdir hello

# 把目錄轉到 hello 資料夾

cd hello


建立一個 hello.c

vim hello.c

hello.c 的內容

/* hello.c */
#inlcude <linux/kernel.h>
asmlinkage long sys_hello(void){
    printk("Hello world!\n");
    return 0;
}


於同一個下再建立一個 Makefile

vim Makefile

Makefile 的內容

obj-y := hello.o


接著在 linux-4.10.14 目錄下改 Makefile 告訴你的 compiler ,新的 system call 可以在 hello 目錄中找到

# 把目錄轉回去

cd /usr/src/linux-4.10.14

# 打開此目錄下的 Makefile

vim Makefile

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

image alt

請你在後面補上 hello 這樣 kernel 在編譯時才會到你的 hello 目錄 改成下面這樣

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


接著因為我的系統是 64 位元的 ((我想大部分的人都是)) 所以我要去修改 syscall_64.tbl 檔

cd arch/x86/entry/syscalls
vim syscall_64.tbl

請你在最後一行添加上你的 system call 然後請把編號記住, 等一下會用

註:你會發現下面突然跳到500多號,那是放x32的東西,我們要擺在300多號那邊

image alt


接著編輯 syscalls.h 檔 將我們 syscall 的原型添加進檔案的最後一行 (#endif之前)

# 把目錄轉回去

cd /usr/src/linux-4.10.14

cd include/linux
vim syscalls.h

image


編譯 kernel

先把會用到的套件安裝好

# 這個套件可以幫我們 build 出 kernel-pakage

sudo apt-get install fakeroot build-essential kernel-package libncurses5 libncurses5-dev

image alt

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


把 kernel 的 config 複製出來

# 把目錄轉回去

cd /usr/src/linux-4.10.14

cp /boot/config-`uname -r` ./.config

然後用 make menuconfig 來設定組態

make menuconfig

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

image alt

但是我的目的只是要加一個 system call 所以我直接 “按兩下 ESC 離開” 如果你有要做其他設定再自行添加


然後就可以 compile 你的 kernel 了

# 清理殘留的 pakage

make-kpkg clean

# 編譯 kernel

fakeroot make-kpkg -j 4 --initrd kernel_image kernel_headers
# 等編譯完後會產生 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

# 再重新下指令編譯

fakeroot make-kpkg -j 4 --initrd kernel_image kernel_headers

編譯完成

編譯完成後會在 /usr/src 路徑下產生了這個 kernel 的 image 和 headers ,我們要用指令安裝他們

# 轉目錄

cd /usr/src

# 安裝 kernel image

sudo dpkg -i linux-image-4.10.14_4.10.14-10.00.Custom_amd64.deb

# 安裝 kernel headers

sudo dpkg -i linux-headers-4.10.14_4.10.14-10.00.Custom_amd64.deb

# 安裝完後就重開機

reboot


重開機後再看看你的 kernel 版本有沒有變新

# 查看 kernel version

uname -r

image alt


測試 system call

# 建一個 hello.c

vim hello.c

hello.c 的內容如下

/* hello.c */
#include <linux/kernel.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <stdio.h>

int main(){
    /* 使用我們剛剛新增的 system call */
    long int sys = syscall(332);
    
    /* print 出 syscall 的回傳值, 若為 0 則代表成功 */
    printf("sys_hello returned %ld\\n", sys);
    
    return 0;
}
# 編譯 hello.c

gcc -g -Wall hello.c -o hello

# 執行

./hello

image alt

看到回傳 0 則代表成功囉


使用 dmesg 來查看 kernel 內的訊息

dmesg

image alt

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