第一篇:linux0.11系統(tǒng)調(diào)用原理及實(shí)驗(yàn)總結(jié)
Linux0.11系統(tǒng)調(diào)用原理及實(shí)驗(yàn)總結(jié)
系統(tǒng)調(diào)用的原理
1.1 概述
系統(tǒng)調(diào)用是一個(gè)軟中斷,中斷號(hào)是0x80,它是上層應(yīng)用程序與Linux系統(tǒng)內(nèi)核進(jìn)行交互通信的唯一接口。通過int 0x80,就可使用內(nèi)核資源。不過,通常應(yīng)用程序都是使用具有標(biāo)準(zhǔn)接口定義的C函數(shù)庫間接的使用內(nèi)核的系統(tǒng)調(diào)用,即應(yīng)用程序調(diào)用C函數(shù)庫中的函數(shù),C函數(shù)庫中再通過int 0x80進(jìn)行系統(tǒng)調(diào)用。
所以,系統(tǒng)調(diào)用過程是這樣的:
應(yīng)用程序調(diào)用libc中的函數(shù)->libc中的函數(shù)引用系統(tǒng)調(diào)用宏->系統(tǒng)調(diào)用宏中使用int 0x80完成系統(tǒng)調(diào)用并返回。
另外一種訪問內(nèi)核的方式是直接添加一個(gè)系統(tǒng)調(diào)用,供自己的應(yīng)用程序使用,這樣就不再使用庫函數(shù)了,變得更為直接,效率也會(huì)更高。
1.2 相關(guān)的數(shù)據(jù)結(jié)構(gòu)
在說具體的調(diào)用過程之前,這里先要說幾個(gè)數(shù)據(jù)結(jié)構(gòu)。
1.2.1 系統(tǒng)調(diào)用函數(shù)表
系統(tǒng)調(diào)用函數(shù)表sys_call_table是在sys.h中定義的,它是一個(gè)函數(shù)指針數(shù)組,每個(gè)元素是一個(gè)函數(shù)指針,它的值是各個(gè)系統(tǒng)提供的供上層調(diào)用的系統(tǒng)函數(shù)的入口地址。也就是說通過查詢這個(gè)表就可以調(diào)用軟中斷0x80所有的系統(tǒng)函數(shù)處理函數(shù)。
1.2.2 函數(shù)指針偏移宏
這是一系列宏,它們的定義在unistd.h中,基本形式為#define _NR_name value,name為系統(tǒng)函數(shù)名字,value是一個(gè)整數(shù)值,是name所對(duì)應(yīng)的系統(tǒng)函數(shù)指針在sys_call_table中的偏移量。
1.2.3 系統(tǒng)調(diào)用宏
系統(tǒng)調(diào)用宏_syscalln(type,name)在內(nèi)核的unistd.h文件中定義的,對(duì)它展開就是: type name(參數(shù)列表){ 調(diào)用過程; }; 其中,n為參數(shù)個(gè)數(shù),type為函數(shù)返回值類型,name為所要調(diào)用的系統(tǒng)函數(shù)的名字。在unistd.h中共定義了4個(gè)這樣的宏(n從0到3),也就是說,0.11核中系統(tǒng)調(diào)用最多可帶3個(gè)參數(shù)。那么下面就說這個(gè)宏干了什么,也就是說上面的那個(gè)“調(diào)用過程”是怎么樣的呢?在這個(gè)宏中嵌入了匯編代碼,做的工作就是int 0x80,其中將字符串“_NR_”和name連接,組成一個(gè)宏并將這個(gè)宏的值,也就是被調(diào)用的系統(tǒng)函數(shù)在sys_call_table中偏移量送到eax寄存器中;同時(shí)指明系統(tǒng)函數(shù)將來的返回值放到eax中。
1.3 系統(tǒng)調(diào)用處理過程
下面我再說一下系統(tǒng)調(diào)用的核心軟中斷int 0x80具體干了什么。這條指令會(huì)引起CPU的軟件中斷,cpu會(huì)根據(jù)中斷號(hào)找到中斷處理程序。這個(gè)中斷處理程序是在System_call.s中。在中斷處理程序的工作過程大致是這樣的:
1.3.1 將寄存器ds,es,fs以及存有參數(shù)的edx,ecx,ebx入棧,再ds,es,指向內(nèi)核段,fs指向用戶段。
1.3.2 根據(jù)eax中的偏移值,在函數(shù)表sys_call_table中找到對(duì)應(yīng)的系統(tǒng)函數(shù)指針(函數(shù)的入口地址)。并利用call指令調(diào)用系統(tǒng)函數(shù),返回后,程序把返回值加入堆棧。
1.3.3 檢查執(zhí)行本次系統(tǒng)調(diào)用的進(jìn)程的狀態(tài),如果發(fā)現(xiàn)由于某種原因原進(jìn)程沒處在就緒狀態(tài)或者時(shí)間片到了,就會(huì)執(zhí)行進(jìn)程調(diào)度函數(shù)schedule()。1.3.4 通過執(zhí)行這次調(diào)用的程序的代碼選擇符判斷它是不是普通用戶程序,如果是就調(diào)用信號(hào)處理函數(shù)。若不是就直接彈出棧內(nèi)容,并返回 添加一個(gè)系統(tǒng)調(diào)用的實(shí)驗(yàn)
2.1 實(shí)驗(yàn)內(nèi)容
在linux0.11版本中添加兩個(gè)系統(tǒng)調(diào)用,并編寫一個(gè)簡(jiǎn)單的應(yīng)用程序測(cè)試它們。
第一個(gè)系統(tǒng)調(diào)用是iam(),其原型為:
intiam(const char * name);完成的功能是將字符串參數(shù)name的內(nèi)容拷貝到內(nèi)核中保存下來。要求name的長(zhǎng)度不能超過23個(gè)字符。返回值是拷貝的字符數(shù)。如果name的字符個(gè)數(shù)超過了23,則返回“-1”,并置errno為EINVAL。
第二個(gè)系統(tǒng)調(diào)用是whoami(),其原型為:
intwhoami(char* name, unsigned int size);它將內(nèi)核中由iam()保存的名字拷貝到name指向的用戶地址空間中,同時(shí)確保不會(huì)對(duì)name越界訪存(name的大小由size說明)。返回值是拷貝的字符數(shù)。如果size小于需要的空間,則返回“-1”,并置errno為EINVAL。
2.2 代碼添加修改步驟
2.2.1 在unistd.h中添加系統(tǒng)調(diào)用接口
#define __NR_whoami 72 #define __NR_iam 73 intwhoami(void);intaim(void);
2.2.2 在exit.c文件中添加系統(tǒng)調(diào)用處理函數(shù)的實(shí)現(xiàn)
系統(tǒng)調(diào)用的函數(shù)可以在其他.c文件中添加或在新建文件中添加,只要編輯進(jìn)image都是可以的,這里為了調(diào)試方便就在exit.c文件中添加了。
#define MAX 23 char N_MAX[26];
intsys_whoami(char* name, unsigned int size){ if(strlen(N_MAX)>size)return-EINVAL;
int i;
for(i=0;N_MAX[i]!=' 主站蜘蛛池模板: 亚洲色欲色欲高清无码| 欧美国产成人精品一区二区三区| 欧美私人情侣网站| 天天做天天爱夜夜爽女人爽| 亚洲人成网站18禁止人| 精品无码人妻夜人多侵犯18| 亚洲国产成人福利精品| 久久亚洲精精品中文字幕| 最近中文字幕在线mv视频在线| 中国凸偷窥xxxx自由视频妇科| 亚洲av无码不卡一区二区三区| 日韩av片无码一区二区不卡电影| 亚洲综合成人av一区在线观看| 老子影院午夜伦手机不四虎卡| 国产目拍亚洲精品二区| 狠狠躁夜夜躁人人爽天天天天97| 无码人妻丰满熟妇啪啪欧美| 老子影院午夜伦手机不四虎卡| 青草伊人久久综在合线亚洲| 亚洲色成人中文字幕网站| 伊人久久大香线蕉无码综合| 动漫成人无码精品一区二区三区| 免费看性视频xnxxcom| 国产色无码精品视频国产| 日本久久高清一区二区三区毛片| 人妻av无码一区二区三区| 国产成年女人特黄特色毛片免| 综合久久国产九一剧情麻豆| 欧美丰满熟妇bbb久久久| 免费无码一区无码东京热| 日射精情感性色视频| 天天狠天天透天干天天怕∴| 国产偷国产偷亚洲清高动态图| 老头把我添高潮了a片| 日本高清色倩视频在线观看| 色综合久久无码五十路人妻| 久久国产乱子伦精品免费女人| 国产99视频精品免视看9| 曰本极品少妇videossexhd| 狼友av永久网站免费观看| 伊伊综合在线视频无码|