1. 寫在前面
?系統(tǒng)調(diào)用是操作系統(tǒng)提供給用戶程序調(diào)用的一組“特殊”接口茎匠。通過這組“特殊”接口举户,用戶程序可以獲得操作系統(tǒng)內(nèi)核提供的服務(wù)弛针,如文件系統(tǒng)相關(guān)系統(tǒng)調(diào)用提供的打開文件统抬、關(guān)閉文件或讀寫文件服務(wù)冀宴,時鐘相關(guān)的系統(tǒng)調(diào)用提供的獲取系統(tǒng)時間灭贷、設(shè)置系統(tǒng)時間服務(wù)等。
?從邏輯上來說略贮,系統(tǒng)調(diào)用可被看成是一個內(nèi)核與用戶空間程序交互的接口——好比一個中間人甚疟,把用戶進(jìn)程的請求傳達(dá)給內(nèi)核,待內(nèi)核把請求處理完畢后再將處理結(jié)果送回給用戶進(jìn)程逃延。
一個系統(tǒng)調(diào)用的典型調(diào)用過程如下圖所示.
系統(tǒng)調(diào)用的作用:
?系統(tǒng)服務(wù)之所以需要通過系統(tǒng)調(diào)用提供給用戶空間览妖,其根本原因是為了對系統(tǒng)進(jìn)行“保護(hù)”。我們知道操作系統(tǒng)的運行空間分為內(nèi)核空間與用戶空間揽祥,它們各自運行在不同的級別中讽膏,邏輯上相互隔離,故用戶進(jìn)程在通常情況下不允許訪問內(nèi)核數(shù)據(jù)拄丰、不允許使用內(nèi)核函數(shù)府树,它們只能在用戶空間操作用戶數(shù)據(jù),調(diào)用用戶空間的函數(shù)料按。但是很多情況下奄侠,用戶進(jìn)程需要獲得系統(tǒng)服務(wù)(調(diào)用系統(tǒng)程序),這時就必須利用系統(tǒng)提供給用戶的“特殊”接口——系統(tǒng)調(diào)用载矿,其特殊性在于規(guī)定了用戶進(jìn)程進(jìn)入內(nèi)核的具體位置垄潮,即用戶訪問內(nèi)核的路徑是事先規(guī)定好的,只能從規(guī)定位置進(jìn)入內(nèi)核闷盔,而不準(zhǔn)許肆意跳入內(nèi)核弯洗。有了上述陷入內(nèi)核的統(tǒng)一訪問路徑限制,才能有效保證系統(tǒng)內(nèi)核的安全逢勾。我們可以形象地描述上述機(jī)制:作為一個游客牡整,你可以買票要求進(jìn)入野生動物園,但你必須老老實實的坐在觀光車上敏沉,按照規(guī)定的路線觀光游覽果正。當(dāng)然炎码,不準(zhǔn)下車,因為那樣太危險秋泳,不是讓你丟掉小命潦闲,就是讓你嚇壞了野生動物。
?在前述文章“Linux-3.10.1內(nèi)核的編譯和安裝”(詳見http://www.lingyuecloud.com/Index/details/id/58.html)中迫皱,我們知道利用Linux內(nèi)核的開源特性歉闰,可以對Linux系統(tǒng)進(jìn)行定制化開發(fā)、編譯和安裝卓起。例如和敬,通過修改Linux內(nèi)核源碼,我們定制化開發(fā)了一個新功能戏阅,那么如何在應(yīng)用程序中使用這個新功能呢昼弟?為此,我們還需要為“應(yīng)用程序”與“內(nèi)核中新增的新功能”建立橋梁——即一個能夠連接兩者的系統(tǒng)調(diào)用奕筐。
?假設(shè)我們已經(jīng)獲得了Linux-3.10.1的源碼包linux-3.10.1.tar.bz2舱痘,解壓該源碼包后得到linux-3.10.1文件夾,并切換到該文件夾下(如何獲取包linux-3.10.1.tar.bz2离赫?如何解壓芭逝?請詳見http://www.lingyuecloud.com/Index/details/id/58.html——“Linux-3.10.1內(nèi)核的編譯和安裝”)。接下來,靈躍桌面云將以Linux-3.10.1內(nèi)核為例,詳細(xì)描述為內(nèi)核添加一個新的系統(tǒng)調(diào)用的過程经伙,下述所有操作都在linux-3.10.1目錄下進(jìn)行。
2. 環(huán)境說明
注:在下述描述中胖翰,涉及在服務(wù)器Ubuntu 12.04操作系統(tǒng)環(huán)境上的所有操作,均以root身份登錄并執(zhí)行切厘。
3. 為Linux-3.10.1內(nèi)核添加一個系統(tǒng)調(diào)用
3.1 系統(tǒng)調(diào)用號
?Linux系統(tǒng)調(diào)用號的作用是在系統(tǒng)調(diào)用過程中泡态,將其數(shù)值作為下標(biāo)的在系統(tǒng)調(diào)用表中進(jìn)行索引,從而得到處理該系統(tǒng)調(diào)用的函數(shù)的地址迂卢。
?每個系統(tǒng)調(diào)用都有一個唯一的系統(tǒng)調(diào)用號,應(yīng)用程序可以通過系統(tǒng)調(diào)用號調(diào)用指定的系統(tǒng)調(diào)用桐汤。
3.2 系統(tǒng)調(diào)用表
?與Windows系統(tǒng)中的SSDT(System Services Descriptor Table)的作用一樣而克,Linux系統(tǒng)調(diào)用表保留著處理各個系統(tǒng)調(diào)用的函數(shù)的入口地址;其實際上是一個二維的指針數(shù)組[X][Y]怔毛,X代表系統(tǒng)調(diào)用號员萍,Y代表系統(tǒng)調(diào)用函數(shù)的入口地址。
3.3 添加系統(tǒng)調(diào)用lingyuecloudsyscall
- 添加自定義的系統(tǒng)調(diào)用源代碼
在“l(fā)inux-3.10.1/kernel”目錄下的sys.c文件中添加自定義的系統(tǒng)調(diào)用lingyuecloudsyscall的實現(xiàn)函數(shù)拣度。
打開sys.c文件碎绎,添加以下示例代碼:
#vim kernel/sys.c
|
- 修改系統(tǒng)調(diào)用表
系統(tǒng)調(diào)用表文件在“l(fā)inux-3.10.1/arch/x86/syscalls”目錄下的syscall_64.tbl文件中螃壤。
打開syscall_64.tbl,添加新的系統(tǒng)調(diào)用指針筋帖,如下所示:
#vim arch/x86/syscalls/syscall_64.tbl
如下圖所示:
其中奸晴,314為lingyuecloudsyscall的系統(tǒng)調(diào)用號,應(yīng)用程序可通過此調(diào)用號調(diào)用lingyuecloudsyscall系統(tǒng)調(diào)用日麸,也可以使用其它的系統(tǒng)調(diào)用號寄啼,但注意不能與已有的系統(tǒng)調(diào)用號重復(fù)。64表示適配于64位系統(tǒng)內(nèi)核環(huán)境代箭,相關(guān)描述詳情可查閱https://en.wikipedia.org/wiki/X32_ABI墩划。
- 添加系統(tǒng)調(diào)用lingyuecloudsyscall的函數(shù)聲明
在“l(fā)inux-3.10.1/include/linux/”目錄下的syscalls.h文件中添加函數(shù)聲明。
打開syscalls.h嗡综,在倒數(shù)第二行添加下面內(nèi)容:
#vim include/linux/syscalls.h
asmlinkage long sys_lingyuecloudsyscall(int num);
如下圖所示:
- 重新編譯
- 內(nèi)核
編譯過程詳見http://www.lingyuecloud.com/Index/details/id/58.html——“Linux-3.10.1內(nèi)核的編譯和安裝”乙帮。 - 測試系統(tǒng)調(diào)用
編寫測試程序lingyuecloud_test.c:
編譯測試程序:
gcc -o lingyuecloud lingyuecloud_test.c
測試結(jié)果如下圖所示:
如果能夠看到上述結(jié)果,表示你的第一個自定義系統(tǒng)調(diào)用已經(jīng)添加成功极景。
本文轉(zhuǎn)載于 靈躍云 : 原文鏈接