一、實驗內容
1.閱讀並分析Linux內核源碼,深入了解Linux內核中系統調用內部數據結構;
2.編寫一個新系統調用的響應函數,函數的名稱和功能由實驗者自行定義;
3.將新的系統調用函數嵌入到Linux內核中;
4.編寫應用程序以測試新的系統調用並輸出測試結果。
二、實驗目的
1.熟悉Linux系統調用;
2.深入了解Linux操作系統中系統調用的實現機制和執行過程。
三、設計思路和流程圖
新增的系統調用可以自行定義,比如我增加一個選擇排序的系統調用。
新增系統調用 select_sort ,用於對數組進行選擇排序,對應的系統調用函數為 sys_select_sort 。
1.設置新增系統調用的名稱及編號
修改文件 arch/i386/kernel/syscall_table.S

2.設置系統調用的具體內容
因為我新增的函數沒有用到頭文件,所以沒有添加頭文件。后面的實驗如果需要,可在include/linux目錄下添加。
在kernel目錄下新建文件 select_sort.c ,實現函數 sys_select_sort 。

宏asmlinkage定義在linux/linkage.h中,表示函數的參數通過棧傳遞,而不是寄存器,所有的系統調用都遵循這種參數傳遞方式。
3.使該系統調用在編譯時可見
修改文件kernel/Makefile

4.加上系統調用號的宏定義
修改文件include/asm-i386/unistd.h

注意:NR_syscalls表示的值應該是最大的系統調用號加一
5.加上函數sys_select_sort的聲明
修改文件include/linux/syscalls.h

如果之前添加了頭文件,則還要注意在這里包括頭文件。
6.重新編譯內核
參照實驗一。
這個實驗主要是系統調用函數內部的實現,但要注意細心實驗,不能遺漏步驟
四、主要數據結構及說明
在指導手冊中使用了結構體,放在頭文件里,但是我沒有采用這種大眾的方法。
我的系統調用中采用的是線性順序表——數組。
使用選擇排序的方法對數組進行排序,每次選出其中最小的元素,然后與前面的元素進行交換。
最后的數組元素按照從小到大的順序進行排序。
五、源程序並附上注釋
1.系統調用函數的實現(select_sort.c)
選擇排序,主要是兩步,一是選出最小的元素,二是交換,程序如下。
#include<linux/linkage.h>
#include<linux/types.h>
asmlinkage int sys_select_sort(int *a,const int n)
{
int temp,temp1,min,i,j;
for(i=0;i<n-1;i++)
{
temp=i;
min=*(a+i);
for(j=i+1;j<n;j++)
{
if(*(a+j)<min)
{
temp=j;
min=*(a+j);
}
}
if(i != temp)
{
temp1=*(a+i);
*(a+i)=*(a+temp);
*(a+temp)=temp1;
}
}
return 0;
}
2.測試程序
#include<stdio.h>
#include<sys/syscall.h>
#include<unistd.h>
#define n 9
int main()
{
int a[n]={43,23,2,33,65,12,6,12,16};
int i=0;
//print the array before sorting
printf("%s\n","Before sorting:");
for(i=0;i<n;i++)
{
printf("%d ",a[i]);
}
printf("%s","\n");
syscall(320,a,n);//system call
//print the array after sorting
printf("%s\n","After sorting:");
for(i=0;i<n;i++)
{
printf("%d ",a[i]);
}
printf("%s","\n");
return 0;
}
六、程序運行結果及分析
測試程序編譯運行結果如下

七、實驗體會
通過新增系統調用可以學到很多linux基本命令的使用,比如,使用vi打開文件,然后i修改文件,:wq保存文件並退出,等等。
新增系統調用后需要重新編譯安裝內核,然后重啟才能生效,如果因為某些原因,重啟時不能進入內核,那么可以選擇進入之前的內核對新的內核進行修改。
這個實驗是為下一個做鋪墊的,循序漸進逐步提高,加油!
