Step 0
首先先下載2.6.32.x版本的Kernel,下載下來後解壓縮
Step 1
開啟linux-2.6.32.61/arch/x86/kernel裡的syscall_table_32.S這個檔案(64位元就選syscall_table_64.S)
在裡面會看到system call的列表,拉到最底,在這裡宣告system call
.(回傳的變數型態) sys_(syscall名稱)
例: .int sys_exam_st (syscall名稱為: "exam_st" ,此後都用這個當例子)
在這邊請注意要記住新增system call的編號,在這邊的.int sys_exam_st的編號就是337
(註: 上面的例子加了3個syscall)
Step 2
開啟linux-2.6.32.61/arch/x86/include/asm裡的unistd_32.h這個檔案
在#define __NR_xxxx這排的最下面新增system call,格式如下
#define __NR_(syscall名稱) (syscall編號)
例: #define __NR_exam_st 337
接著修改下面的#define NR_syscalls後面的數字,該數字是你新增的syscall編號+1
例: #define NR_syscalls 440
(註: 上面的例子加了3個syscall,所以數字為339+1=340)
Step 3
開啟linux-2.6.32.61/include/linux裡的syscalls.h這個檔案
在最下面的#endif 上面加上system call,格式如下
asmlinkage (回傳的變數型態) sys_(syscall名稱)(引入的變數);
例: asmlinkage int sys_exam_st(int PID);
引入的變數看需求而定,這邊是讀入一個int
而當你有需要用到自定義的struct(如同上圖的sys_project_test使用了prcs_info這個原本kernel裡面沒有的struct)
在上面的struct列表加上自定義的struct
例: prcs_info;
(註: struct內部變數的定義將在Step 6提到)
Step 4
接下來回到linux-2.6.32.61,開啟這邊的Makefile檔案
找到core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block 這行程式碼(可以用ctrl+s搜尋"core-y")
在後面加上接下來放置syscall程式檔的資料夾名稱
例:
core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ exam_st/
(資料夾名稱可以自由定義,不一定要和system call名稱一樣,不過注意這邊最後一定要加上"/")
Step 5
接下來回到linux-2.6.32.61,新增一個資料夾,名稱為剛剛定義的資料夾名稱
Step 6
進入該資料夾,新增一個檔案(文字文件),名稱為"資料夾名稱.c"例: exam_st.c
打開檔案,撰寫syscall程式碼(可用圖片下面的程式碼為例,不過這個引入兩個變數,跟剛才定義的有所不同)
例:
asmlinkage int sys_exam_st(int PID){
int num = 0;
(下略)
.
.
.
.
return num;
}
(註: 自定義的struct內容也在這邊做定義)
Step 7
新增一個檔案(文字文件),名稱為"Makefile"
開啟檔案,在裡面打上 obj-y := "(syscall的檔案名稱).o"
例: obj-y := exam_st.o
Step 8
接著進入compile kernel的步驟
開啟command-line interface,進入linux-2.6.32.61
例: cd ......./linux-2.6.32.61
設定核心選項 (只有在第一次compile kernel 前設定)
輸入make menuconfig
出現藍色的選單畫面, 我們可以勾選所需要的功能和模組,進行設定
或者也可以載入已經設定好的設定檔, 也就是 .config 檔
( 可預先將 .config 檔放在 kernel 目錄下, 此檔可從 live CD 取得, 或者網路下載 )
在確定已將 .config 檔放到 kernel 目錄下之後
選取 "Load an Alternate Configuration File" 將它載入
顯示 .config 按下確定
選取 "Save an Configuration File" 儲存之後, 選取 EXIT 離開設定畫面
(又或是直接選擇"Save an Configuration File",將會直接產生預設的.config檔)
(若沒有另外特別的需求設定,建議選擇預設的設定)
接著輸入make clean
刪除之前的編譯好的程式碼(xxx.o)
等待一段時間後,完成後大致上為下圖
這邊要注意,若沒有root權限,要在前面加上sudo,輸入密碼後才能執行
此步驟將會執行非常久的時間(約1小時),可以放著執行一陣子後再回來
完成後大致上為下圖
輸入make modules
這邊也是要等待一段時間(十幾分鐘,可以放著執行一陣子後再回來
完成後大致上為下圖
輸入make modules_install
完成後大致上為下圖
輸入make install
完成後大致上為下圖
可以在上面的grub列表看到安裝了2.6.32.61版的kernel
Step 8.5
接下來重開機,在開機選單
選擇Advanced options for ubuntu
列表為各個版本的kernel
選擇ubuntu, with Linux 2.6.32.61
(可以看到下面有舊的版本的Linux 2.6.32.61.old,當再一次編譯2.6.32.61版本的kernel時,系統會幫你保存上次修改的版本)
Step 9
開機後,到桌面新增一個檔案(文字文件),名稱自由定義 "xxx.c"
例: test1.c
開啟檔案,輸入下列程式碼如下圖
看到紅框的部分,syscall()格式如下
syscall( "syscall編號" , 第一個引數 , 第二個引數 , ...)
例: syscall(337, 33)
(int sys_exam_st(int PID),這邊可以看到只使用一個引數 int PID)
開啟command-line interface,進入test1的位置
輸入 gcc -o "編譯完成後的執行檔名稱" "編譯的檔案"
例: gcc -o test1 test1.c
Step 10
執行剛剛編譯好的檔,確認system call是否正確執行
上圖的 201 即為system call回傳的結果