




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、第5章Linux系統(tǒng)調(diào)用,系統(tǒng)調(diào)用功能概述系統(tǒng)調(diào)用處理進程系統(tǒng)調(diào)用的實例分析系統(tǒng)調(diào)用添加方法,系統(tǒng)調(diào)用概述,系統(tǒng)調(diào)用(SYSTEM CALL) OS內(nèi)核具有一組實現(xiàn)系統(tǒng)功能的進程。系統(tǒng)調(diào)用是對上述進程的調(diào)用。程序員使用系統(tǒng)調(diào)用向OS提交服務(wù)請求,由OS代替。通常,進程不能訪問系統(tǒng)內(nèi)核。無法訪問內(nèi)核使用的內(nèi)存段或調(diào)用內(nèi)核函數(shù)。CPU的硬件結(jié)構(gòu)可以確保這一點。只有系統(tǒng)調(diào)用例外。5.1 Linux系統(tǒng)調(diào)用-功能,系統(tǒng)調(diào)用是用戶狀態(tài)進入內(nèi)核狀態(tài)的唯一入口,控制一般系統(tǒng)調(diào)用:硬件:如write/read調(diào)用。設(shè)定系統(tǒng)狀態(tài)或讀取核心資料getpid()、getpriority()、setpriority(
2、)、sethostname()程序管理3360,例如fork()、clone首先,您可以確認請求的正確性。5.1 Linux系統(tǒng)調(diào)用-功能、5.2 Int 0 X80命令以及在Linux上實現(xiàn)系統(tǒng)調(diào)用利用i386體系結(jié)構(gòu)的軟件中斷。也就是說,調(diào)用int $0 X80組件命令。此程序集命令生成矢量為128的編程異常,CPU轉(zhuǎn)換為內(nèi)核狀態(tài),執(zhí)行內(nèi)核函數(shù)并轉(zhuǎn)到系統(tǒng)調(diào)用處理程序的入口system_call()。Int $0 X80命令將用戶狀態(tài)的執(zhí)行模式轉(zhuǎn)換為內(nèi)核狀態(tài),并將控制權(quán)傳遞給系統(tǒng)調(diào)用進程的起始點system_call()處理函數(shù)。system_call()函數(shù)system_call()檢查系
3、統(tǒng)調(diào)用號,該編號告訴內(nèi)核進程請求的服務(wù)。查看內(nèi)核進程系統(tǒng)調(diào)用表(sys_call_table),找到調(diào)用的內(nèi)核函數(shù)入口地址。然后調(diào)用相應(yīng)的函數(shù),返回后執(zhí)行系統(tǒng)檢查,然后返回到進程。系統(tǒng)調(diào)用和常規(guī)函數(shù)調(diào)用,API是用于調(diào)用應(yīng)用程序的特定目的的函數(shù),系統(tǒng)調(diào)用允許應(yīng)用程序直接進入系統(tǒng)內(nèi)核。Linux內(nèi)核提供包裝和擴展系統(tǒng)調(diào)用的C語言庫。這些庫函數(shù)也稱為系統(tǒng)調(diào)用,因為它們與系統(tǒng)調(diào)用有很密切的關(guān)系。某些API函數(shù)不需要使用系統(tǒng)調(diào)用,因為可以在用戶空間中完成工作,例如用于數(shù)學(xué)計算的某些函數(shù)。某些API函數(shù)可以執(zhí)行多個系統(tǒng)調(diào)用。根據(jù)API函數(shù)的不同,可能會有相同的系統(tǒng)調(diào)用。例如,malloc()、callo
4、c()、free()等函數(shù)都使用相同的方法分配和釋放內(nèi)存。系統(tǒng)命令、內(nèi)核函數(shù)和系統(tǒng)調(diào)用的API比系統(tǒng)命令系統(tǒng)命令的API高。每個系統(tǒng)命令都是可執(zhí)行程序,例如ls命令。這些命令的實現(xiàn)調(diào)用系統(tǒng)調(diào)用。系統(tǒng)調(diào)用和內(nèi)核函數(shù)系統(tǒng)調(diào)用是用戶進入內(nèi)核的接口層,本身不是內(nèi)核函數(shù),而是由內(nèi)核函數(shù)實現(xiàn)的。進入內(nèi)核后,徐璐在其他系統(tǒng)調(diào)用中查找相應(yīng)的內(nèi)核函數(shù),稱為系統(tǒng)調(diào)用的“服務(wù)例程”。系統(tǒng)調(diào)用getpid()實際調(diào)用的服務(wù)實例是sys_getpid(),或者系統(tǒng)調(diào)用getpid()是服務(wù)實例sys_getpid()中的程序包例程。封裝例程(wrapper routine)、切入命令是特殊命令,因此是依賴操作系統(tǒng)實現(xiàn)的
5、平臺(例如,在i386體系結(jié)構(gòu)中,int $0 X80(切入命令),而不是編程時必須使用的語句。這可能會使移植用戶程序變得困難。在標(biāo)準(zhǔn)C庫函數(shù)中,為每個系統(tǒng)調(diào)用設(shè)置了軟件包例程,當(dāng)用戶程序執(zhí)行系統(tǒng)調(diào)用時,將調(diào)用C庫中相應(yīng)的軟件包例程。,系統(tǒng)調(diào)用過程,系統(tǒng)調(diào)用過程,system_call()片段,pushl/*系統(tǒng)調(diào)用號堆棧*/save _ all.cmpl $ (NR _ syscalls) 24(%esp) /*堆棧中的eax返回值jmpret _ from _ sys _ call,system _ call段(請參閱nob adsys 3360 call * sys _ call _ t
6、able(4)/在調(diào)用系統(tǒng)調(diào)用表中,將返回值存儲在調(diào)用號為eax的系統(tǒng)調(diào)用例程movleax (%esp)/堆棧中的jmpret _ fret用戶根據(jù)Eax的系統(tǒng)調(diào)用號調(diào)用相應(yīng)的服務(wù)實例。服務(wù)例程結(jié)束后,eax寄存器獲取返回值,并將其存儲在堆棧中,將用戶狀態(tài)eax寄存器放在存儲位置。然后轉(zhuǎn)到ret_from_sys_call(),結(jié)束系統(tǒng)調(diào)用程序的執(zhí)行。定義SAVE_ALL宏,# define SAVE _ ALL CLDPushl % esPushl % dsPushl pushl pushl pushl % ESIpushl pushl pushl movl $(_ _ kernel _
7、ds),movl % dsmovl % es;將寄存器的參數(shù)推入核心堆棧(內(nèi)核可以使用用戶傳遞的參數(shù))。)INT指令與CALL指令不同,在徐璐控制不同權(quán)限級別之間的轉(zhuǎn)換時,不會自動將外部堆棧的參數(shù)復(fù)制到內(nèi)部堆棧,因此在調(diào)用系統(tǒng)調(diào)用時,必須為每個寄存器指定參數(shù),調(diào)用主程序(system_call)運行流程圖,調(diào)用系統(tǒng)調(diào)用表和調(diào)用編號來創(chuàng)建系統(tǒng),如果應(yīng)用程序調(diào)用fork()封裝例程,則必須在運行int $0 X80之前創(chuàng)建系統(tǒng)此寄存器的設(shè)置由libc庫中的封裝例程執(zhí)行,因此用戶通常對系統(tǒng)調(diào)用號、系統(tǒng)調(diào)用表和調(diào)用號不感興趣,并為內(nèi)核中的每個系統(tǒng)調(diào)用定義唯一的編號。此編號在linux/include/
8、asm/unistd.h(最大NR _ STD)中定義。第n個表條目包含系統(tǒng)調(diào)用號為n的服務(wù)實例的地址。在系統(tǒng)調(diào)用進入內(nèi)核之前,必須將系統(tǒng)調(diào)用號一起傳遞給內(nèi)核。此標(biāo)簽實際上位于系統(tǒng)調(diào)用表(sys_call_table)的下標(biāo)i386,通過在運行int $0 X80之前將調(diào)用號加載到eax寄存器中來實現(xiàn)此傳遞行為。這樣,運行系統(tǒng)調(diào)用處理程序后,可以從eax獲取系統(tǒng)調(diào)用號,然后轉(zhuǎn)到系統(tǒng)調(diào)用表查找其服務(wù)實例。系統(tǒng)調(diào)用號,# Define _ _ NR _ exit 1 # Define _ _ NR _ fork 2 # Define _ _ NR _ read 3 # Define _long s
9、ymbol _ name (sys _ ni _ syscall)。long symbol _ name(.long symbol _ name (sys _ write)。long symbol _ name (sys _ open)。long symbol _ name (sys)。long symbol _ name (sys _ link)。long symbol _ name (sys _ unlink)。偏移long symbol _ name (sys)系統(tǒng)調(diào)用號可以在表中查找相應(yīng)的處理程序地址。Linux/include/linux/sys.h中定義的NR_syscalls表示
10、表可以包含的最大系統(tǒng)調(diào)用數(shù)(常規(guī)NR_syscalls=256)。、系統(tǒng)調(diào)用表(sys_call_table)、系統(tǒng)調(diào)用的返回、服務(wù)例程結(jié)束時,system_call()從eax獲取系統(tǒng)調(diào)用的返回值,并將它們存儲在用戶狀態(tài)eax寄存器堆棧單元格的存儲位置。在進程還原用戶狀態(tài)的運行之前,RESTORE_ALL宏將還原在用戶進入內(nèi)核之前保留在堆棧中的寄存器值。其中,返回eax時系統(tǒng)調(diào)用的返回代碼(負數(shù)表示調(diào)用錯誤,0或正數(shù)表示正常完成),ret_from_sys_call,cli #關(guān)閉中斷cmpl $0,need_resched(負數(shù)表示錯誤條件。其中返回值不同于封裝例程返回值的規(guī)則。如果未設(shè)置
11、內(nèi)核,或使用errno變量封裝例程在系統(tǒng)調(diào)用獲得返回值后設(shè)置此變量。如果系統(tǒng)調(diào)用出錯,則返回的負值存儲在errno變量中。應(yīng)用程序,調(diào)用5.3系統(tǒng)-分析實例,源文件名為getpid.c,內(nèi)容為# include # include # include int main(void)long id。ID=getpid();Printf (getpid()=%ldn,ID);返回(0);系統(tǒng)調(diào)用-分析調(diào)用程序包例程getpid()的實例。軟件包例程將系統(tǒng)調(diào)用號_NR_getpid(第20個)推入EAX寄存器CPU,通過int $0 X80進入內(nèi)核,找到并調(diào)用system _ call()。3。在內(nèi)核
12、中首先運行4 sys_getpid()服務(wù)實例。5運行完成后,進入ret_from_sys_call()例程,系統(tǒng)調(diào)用返回到用戶狀態(tài)。5.4系統(tǒng)調(diào)用的參數(shù)傳遞,許多系統(tǒng)調(diào)用需要一個或多個參數(shù)。一般C函數(shù)的參數(shù)傳遞是通過將參數(shù)值寫入堆棧(用戶狀態(tài)堆?;騼?nèi)核狀態(tài)堆棧)來完成的。但是,系統(tǒng)調(diào)用是從用戶狀態(tài)進入內(nèi)核狀態(tài)的特殊函數(shù),因此,用戶狀態(tài)堆?;騼?nèi)核狀態(tài)堆棧,用戶狀態(tài)堆棧,用戶狀態(tài)C函數(shù),內(nèi)核狀態(tài)堆棧,內(nèi)核狀態(tài)C函數(shù)畢竟,服務(wù)例程是C函數(shù),所以仍然需要在堆棧中查找參數(shù)。、用戶狀態(tài)堆棧、用戶狀態(tài)C函數(shù)、內(nèi)核狀態(tài)堆棧、內(nèi)核狀態(tài)C函數(shù)、寄存器、系統(tǒng)調(diào)用的參數(shù)傳遞、系統(tǒng)調(diào)用號用于傳遞系統(tǒng)調(diào)用所需參數(shù)參數(shù)的
13、寄存器為:eax:存儲系統(tǒng)調(diào)用號和系統(tǒng)調(diào)用返回值存儲系統(tǒng)調(diào)用參數(shù):在ebx、ecx、edx、esi和EDI中進入內(nèi)核狀態(tài)后,system_call使用SAVE_ALL進行存儲,必須滿足兩個條件才能將參數(shù)傳遞到注冊表。每個參數(shù)的長度不能超過寄存器的長度參數(shù)數(shù)6(包括從eax傳遞的系統(tǒng)調(diào)用號)。否則,必須使用單獨的寄存器(ebx)從進程地址空間指向具有這些參數(shù)值的內(nèi)存區(qū)域。返回值必須寫入eax寄存器。如果系統(tǒng)調(diào)用所需的參數(shù)數(shù)大于5,則在發(fā)出int 0 X80命令時,必須將系統(tǒng)調(diào)用功能號存儲在寄存器eax中。不同之處在于,必須按順序放置所有參數(shù)。系統(tǒng)調(diào)用完成后,返回值仍存儲在寄存器eax中。因為只需要存儲系統(tǒng)調(diào)用參數(shù)的連續(xù)內(nèi)存區(qū)域,所以可以像常規(guī)函數(shù)調(diào)用一樣使用堆棧來傳遞系統(tǒng)調(diào)用所需的參數(shù)。但是請記住,Linux使用C語言的調(diào)用模式。也就是說,所有參數(shù)必須按相反的順序堆疊。也就是說,最后一個參數(shù)必須首先進入堆棧,第一個參數(shù)必須最后進入堆棧。如果使用堆棧傳遞系統(tǒng)調(diào)用所需的參數(shù),則在發(fā)出int 0 X80命令時
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 借款抵押財產(chǎn)合同范本
- 申請安裝充電樁的報告
- 國際化經(jīng)營合同范本
- 農(nóng)村建房的申請報告書
- 買活牛合同范本
- 催化新探模板
- 園林花園設(shè)計合同范例
- 交付合同范本
- 口腔護士聘用合同范本
- 創(chuàng)新引領(lǐng)共贏未來
- 中學(xué)家長學(xué)校工作方案(10篇)
- 高考地理二輪復(fù)習(xí)【知識精研】大氣運動規(guī)律-大氣受熱過程與氣溫
- 日內(nèi)交易策略(TBQ版)
- 2025年新執(zhí)業(yè)醫(yī)師定期考核真題庫附參考答案
- 部編版九年級道德與法治上冊《第二課創(chuàng)新驅(qū)動發(fā)展》同步測試題(附答案)
- 充電樁投放合同范本
- 2025-2030年地質(zhì)數(shù)據(jù)定制化服務(wù)行業(yè)深度調(diào)研及發(fā)展戰(zhàn)略咨詢報告
- 鐵路信號基礎(chǔ)(第四版) 課件 第一章 信號繼電器
- 氯化車間安全操作規(guī)程(2篇)
- 2024年電力交易員(高級工)職業(yè)鑒定理論考試題庫(單選題、多選題、判斷題)
- 江蘇省蘇州市(2024年-2025年小學(xué)六年級語文)部編版小升初真題(下學(xué)期)試卷及答案
評論
0/150
提交評論