亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 5.txt

?? Linux內核源代碼分析/電子書
?? TXT
?? 第 1 頁 / 共 2 頁
字號:
第5章   系 統 調 用大部分介紹Unix內核的書籍都沒有仔細說明系統調用,我認為這是一個失誤。實際上,我們實際需要的系統調用現在已經十分完美。因此,從某種意義上來說,研究系統調用的實現是無意義的—如果你想為Linux內核的改進貢獻自己的力量,還有其他許多方面更值得投入精力。然而,對于我們來說,仔細研究少量系統調用是十分值得的。這樣就有機會初步了解一些概念,這些概念將在本書中逐步詳細介紹,例如進程處理和內存。這使你可以詳細了解Linux內核編程的特點。這包括一些和你過去在學校里(或工作中)所學的內容不同的方法。和其他編程任務相比,Linux內核編程的一個顯著特點是它不斷同三個成見進行斗爭—這三個成見就是速度、正確和清晰,我們不可能同時獲取這三個方面,至少并不總是能夠。5.1   什么是系統調用系統調用發生在用戶進程(比如emacs)通過調用特殊函數(例如open)以請求內核提供服務的時候。在這里,用戶進程被暫時掛起。內核檢驗用戶請求,嘗試執行,并把結果反饋給用戶進程,接著用戶進程重新啟動,隨后我們將詳細討論這種機制。系統調用負責保護對內核所管理的資源的訪問,系統調用中的幾個大類主要有:處理I/O請求(open、close、read、write、poll等等)、進程(fork、execve、kill等等)、時間(time、settimeofday等等)以及內存(mmap、brk等等)的系統調用。幾乎所有的系統調用都可以歸入這幾類中。然而,從根本上來說,系統調用可能和它表面上有所不同。首先,在Linux中,C庫中對于一些系統調用的實現是建立在其他系統調用的基礎之上的。例如,waitpid是通過簡單調用wait4實現的,但是它們兩個都是作為獨立的系統調用說明的。其他的傳統系統調用,如sigmask和ftime是由C庫而不是由Linux內核本身實現的;即使不是全部,至少大部分是如此。當然,從技巧的一面來看這是無害的—從應用程序的觀點來看,系統調用就和其他的函數調用一樣。只要結果符合預計的情況,應用程序就不能確定是否真正使用到了內核(這種處理方式還有一個潛在的優點:用戶可以直接觸發的內核代碼越少,出現安全漏洞的機會也就越少)。但是,由于使用這種技巧所引起的困擾將會使我們的討論更為困難。實際上,系統調用這一術語通常被演講者用來說明在第一個Unix版本中的任何對系統的調用。但是在本章中我們只對“真正”的系統調用感興趣—真正的系統調用至少包括用戶進程對部分內核代碼的調用。系統調用必須返回int的值,并且也只能返回int的值。為了方便起見,返回值如果為零或者為正,就說明調用成功;為負則說明發生了錯誤。就像老練的C程序員所知道的一樣,當標準C庫中的函數發生錯誤時,會通過設置全局整型變量errno指明發生錯誤的屬性,系統調用的原理和它相同。然而,僅僅研究內核源程序代碼并不能夠獲得這種系統調用方式的全部意義。如果發生了錯誤,系統調用簡單返回自己所期望的負數錯誤號,其余部分則由標準C庫實現(正常情況下,用戶代碼并不直接調用內核系統函數,而是要通過標準C庫中專門負責翻譯的一個小層次(thin layer)實現)。我們隨便舉一個例子,27825行(sys_nanosleep的一部分)返回-EINVAL指明所提供的值越界了。標準C庫中實際處理sys_nanosleep的代碼會注意到返回的負值,從而設置errno和EINVAL,并且自己返回-1給原始的調用者。在最近的內核版本中,系統調用返回負值偶爾也不一定表示錯誤。在目前的幾個系統調用中(例如lseek),即使結果正確也會返回一個很大的負值。最近,錯誤返回值是在-1到-4095范圍之內。現在,標準C庫實現能夠以更加成熟和高級的方式解釋系統調用的返回值;當返回值為負時,內核本身就不用再做任何特殊的處理了。中斷、內核空間和用戶空間我們將在第6章中介紹中斷和在第8章中介紹內存時再次明確這些概念。但是在本章中,我們只需要粗略地了解一些術語。第一個術語是中斷(interrupt),它來源于兩個方面:硬件中斷,例如磁盤指明其中存放一些數據(這與本章無關);軟件中斷,一種等價的軟件機制。在x86系列CPU中,軟件中斷是用戶進程通知內核需要觸發系統調用的基本方法(出于這種目的使用的中斷號是0x80,對于Intel芯片的研究者來說更為熟悉的是INT 80h)。內核通過system_call(171行)函數響應中斷,這一點我們馬上就會介紹。另外兩個術語是內核空間(kernel space)和用戶空間(user space),它們分別對應內核保留的內存和用戶進程保留的內存。當然,多用戶進程也經常同時運行,而且各個進程之間通常不會共享它們的內存,但是,任何一個用戶進程使用的內存都稱為用戶空間。內核在某一個時刻通常只和一個用戶進程交互,因此實際上不會引起任何混亂。由于這些內存空間是相互獨立的,用戶進程根本不能直接訪問內核空間,內核也只能通過put_user(13278行)和get_user(13254行)宏和類似的宏才可以訪問用戶空間。因為系統調用是進程和進程所運行的操作系統之間的接口,所以系統調用需要頻繁地和用戶空間交互,因此這些宏也就會不時的在系統調用中出現。在通過數值傳遞參數的情況下并不需要它們,但是當用戶把指針(內核通過這個指針進行讀寫)傳遞給系統調用時,就需要這些宏了。5.2   如何激活系統調用系統調用的激活有兩種方法:system_call函數和lcall7調用門(call gate)(請參見135行)。(你可能還聽說過一種機制,syscall函數,是通過調用lcall7實現的—至少在x86平臺上是如此,因此,它并不是一個特有的方法)。本節將細致地討論一下這兩種機制。在閱讀的過程中請注意系統調用本身并不關心它們是由system_call還是由lcall7激活的。這種把系統調用和其實現方式區別開來的方法是十分精巧的。這樣,如果出于某種原因我們不得不增加一種激活系統調用的方法,我們也不必修改系統調用本身來支持這種方法。在你瀏覽這些匯編代碼之前要注意這些機器指令中操作數的順序和普通Intel的次序相反。雖然還有一些其他的語法區別,但是操作數反序是最令人迷惑的。如果你還記得Intel的語法:mov eax, 0(本句代碼的意思是把常數0傳送到寄存器EAX中)在這里應該寫作:mov1 $0, %eax這樣你就能夠正確通過(內核使用的語法是AT&T的匯編語法。在GNU匯編文檔中有更多資料)。5.2.1   system_callsystem_call(171行)是所有系統調用的入口點(這是對于內部代碼來說的,lcall7用來支持iBCS2,這一點我們很快就會討論)。正如前面標題注釋中說明的一樣,目的是為普通情況簡單地實現直接的流程,不采用跳轉,因此函數的各個部分都是離散的—整體的流量控制已經因為要避免普通情況下的多分支而變得非常復雜(分支的避免是十分值得的,因為它們引起的代價非常昂貴。它們可以清空CPU管道,使現存CPU的并行加速機制失效)。圖5-1顯示了作為system_call的一部分出現的分支目標標號以及它們之間的流程控制方向,該圖可以在你閱讀本部分討論內容時提供很大的幫助。圖中system_call和restore_all兩個標號比其他標號都要大,因為這兩處是該函數正常的出口點和入口點;然而,還有另外兩個入口點,這一點在本章的后續內容中很快就可以看到。圖5-1   system_call的流程控制system_call是由標準C庫激活的,該標準C庫會把自己希望傳遞的參數裝載到CPU寄存器中,并觸發0x80軟件中斷(system_call在這里是一個中斷處理程序)。內核記錄了軟件中斷和6828行的system_call函數的聯系(SYSCALL_VECTOR是在1713行宏定義為0x80的)。 system_call171:system_call的第一個參數是所希望激活的系統調用的數目;它存儲在EAX寄存器中。system_call還允許有多達四個的參數和系統調用一起傳送。在一些極其罕見的情況下使用四個參數的限制是負擔繁重的,通常可以建立一個指向結構的指針參數來巧妙地完成同樣功能,指針指向的結構中可以包含你所需要的一切信息。隨后可能需要EAX值的一個額外拷貝,因此通過將其壓棧而保存起來;這個值就是218行的ORIG_EAX(%esp)表達式的值。173:SAVE_ALL宏是在85行定義的,它把所有寄存器的值拷貝壓入CPU的堆棧。隨后,就在system_call返回之前,使用RESTORE_ALL(100行)把棧中的值彈出。在這中間,system_call可以根據需要自由使用寄存器的值。更重要的是,任何它所調用的C函數都可以從棧中查找到所希望的參數,因為SAVE_ALL已經把所有寄存器的值都壓入棧中了。結果棧的結構從26行開始描述。像0(%esp)和4(%esp)一樣的表達式指明了堆棧指針(ESP寄存器)的一種替換形式—分別表示ESP上的0字節,ESP上的4字節等等。特別要注意的是在前面一行中壓入堆棧的EAX的拷貝已經變成本標題注釋作為orig_eax所描述的內容,它們是由SAVE_ALL壓入寄存器之上的堆棧的(orig_eax之上的寄存器在這里早已就緒了)。還需注意:這可能有點令人迷惑—由于我們調用orig_eax時EAX的拷貝已經壓入了堆棧,它是否有可能在其他寄存器下面,而不是在其他寄存器上面呢?答案既是肯定的,也是否定的。x86的堆棧指針寄存器ESP在有數據壓入堆棧時會減少—堆棧會向內存低地址發展。因此,orig_eax邏輯上是在其他值的下面,但是物理上卻是在其他值的上面。從51行開始的一系列宏有助于使這些替換更容易理解。例如,EAX(%esp)就和18(%esp)相同—然而前一種方法通過表達式引用存儲在堆棧中的EAX寄存器拷貝的決定可以使整個過程更加簡單。174:從EBX寄存器中取得指向當前任務的指針。完成這個工作的宏GET_CURRENT(131行)對于在大部分代碼中使用的C函數get_current(10277行)來說是一個無限循環。此后,當看到類似于foo(%ebx)或者foo(%esp)的表達式時,這意味著這些代碼正在引用代表當前進程的結構的字段—16325行的struct task_struct—在第7章中將對它進行更詳細的介紹(更確切的描述是, %ebx的置換在struct task_struct中,%esp的置換在與struct task_struct相關聯的struct pt_regs結構中。但是這些細節在這里都并不重要)。175:檢查(EAX中的)系統調用的數目是否超過系統調用的最大數量(此處EAX為一個無符號數,因此不可能為負值)。如果的確超過了,就向前跳轉到badsys(223行)。177:檢測系統調用是否正被跟蹤。如strace之類的程序為有興趣的人提供了系統調用的跟蹤工具,或者額外的調試信息:如果能夠監測到正在執行的系統調用,那么你就可以了解到當前程序正在處理的內容。如果系統調用正被跟蹤,控制流程就向前跳轉到tracesys(215行)。179:調用系統函數。此處有很多工作需要處理。首先,SYMBOL_NAME宏不處理任何工作,只是簡單的為參數文本所替換,因此可以將其忽略。sys_call_table是在當前文件(arch/i386/kernel/entry.S)的末尾從373行開始定義的。這是一張由指向實現各種系統調用的內核函數的函數指針組成的表。本行中第二對圓括號中包含了三個使用逗號分隔開的參數(第一個參數為空);這里就是實現數組索引的地方。當然,這個數組是以sys_call_table作為索引的,這稱為偏移(displacement)。這三個參數是數組的基地址、索引(EAX,系統調用的數目)和大小,或者每個數組元素中的字節數—在這里就是4。由于數組基地址為空,就將其當作0—但是它要和偏移地址sys_call_table相加,簡單的說就是sys_call_table被當作數組的基地址。本行基本上等同于如下的C表達式:/* Call a function in an array of functions. */(sys_call_table[eax])();然而, C當然還要處理許多繁重的工作,例如為你記錄數組元素的大小。不要忘記,系統調用的參數早已經存儲在堆棧中了,這主要由調用者提供給system_call并使用SAVE_ALL把它們壓棧。180:系統調用已經返回。它在EAX寄存器中的返回值(這個值同時也是system_call的返回值)被存儲起來。返回值被存儲在堆棧中的EAX內,以使得RESTORE_ALL可以迅速地恢復實際的EAX寄存器及其他寄存器的值。

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲激情欧美激情| 尤物av一区二区| 91麻豆精品国产91久久久使用方法 | 亚洲欧美视频在线观看| 中文字幕精品一区二区精品绿巨人 | 国产欧美一区二区精品性色超碰| 日韩三级中文字幕| 日韩精品一区二区三区中文不卡| 欧美丰满美乳xxx高潮www| 欧美乱熟臀69xxxxxx| 欧美日韩国产经典色站一区二区三区| 在线精品视频一区二区三四| 欧美午夜电影一区| 欧美精品免费视频| 久久综合久久综合九色| 中文子幕无线码一区tr| 中文字幕中文字幕中文字幕亚洲无线| 国产精品另类一区| 亚洲女人小视频在线观看| 亚洲黄一区二区三区| 天天爽夜夜爽夜夜爽精品视频| 午夜电影网一区| 国产精选一区二区三区 | 亚洲欧美一区二区三区孕妇| 悠悠色在线精品| 亚洲午夜精品在线| 美脚の诱脚舐め脚责91| 成人综合日日夜夜| 欧美影片第一页| 久久久久久一级片| 亚洲美女视频在线观看| 麻豆91小视频| 91老师片黄在线观看| 日韩一级黄色片| 国产精品三级电影| 亚洲成a人在线观看| 国产一区二区三区视频在线播放| 波多野结衣亚洲| 91精品国产综合久久久久久久久久 | 日韩一二三四区| ...中文天堂在线一区| 琪琪久久久久日韩精品| 色综合一区二区三区| 91精品免费观看| 亚洲乱码国产乱码精品精小说| 久久99久久99| 欧美亚洲综合另类| 国产精品天美传媒| 蜜桃av一区二区三区| 91福利区一区二区三区| 久久精品人人做人人综合| 亚洲成年人网站在线观看| 成人中文字幕合集| 精品精品国产高清a毛片牛牛 | 国产精品久久久久久久久免费相片| 亚洲一区二区成人在线观看| 国产成人精品免费一区二区| 91精品国产91久久久久久一区二区 | 天天影视涩香欲综合网| 99re6这里只有精品视频在线观看 99re8在线精品视频免费播放 | 久久精品999| 欧美日韩高清一区| 一区二区三区中文字幕| 国产mv日韩mv欧美| 欧美另类videos死尸| 国产精品卡一卡二| 国产99精品在线观看| 久久久久久久av麻豆果冻| 久久狠狠亚洲综合| 欧美日韩大陆在线| 亚洲一区二区黄色| 色成年激情久久综合| 欧美一级在线观看| 蜜臀av性久久久久蜜臀aⅴ四虎| 成人性生交大片| 日韩黄色片在线观看| 久久久亚洲高清| 美女脱光内衣内裤视频久久影院| 国产超碰在线一区| 久久久不卡网国产精品二区| 亚洲精品中文在线观看| 成人一区在线观看| 亚洲三级电影网站| 91色综合久久久久婷婷| 国产精品盗摄一区二区三区| 麻豆国产91在线播放| 日韩一级精品视频在线观看| 亚洲一区在线视频观看| 在线精品视频一区二区| 亚洲高清三级视频| 91精品久久久久久久91蜜桃| 一区二区高清免费观看影视大全| av中文字幕不卡| 亚洲综合精品久久| 欧美一卡二卡三卡| 国产精品 日产精品 欧美精品| 26uuu色噜噜精品一区| 国产在线看一区| 亚洲青青青在线视频| 在线观看日韩毛片| 日韩二区三区四区| 久久亚洲一级片| 99久久99久久综合| 五月激情丁香一区二区三区| 日本道色综合久久| 激情久久久久久久久久久久久久久久| 久久综合九色综合久久久精品综合| 天天色综合成人网| 欧美国产国产综合| 欧美色偷偷大香| 国产精品一区二区视频| 国产精品电影一区二区| 91亚洲大成网污www| 一区二区三区在线视频免费观看| 精品视频在线免费看| 日韩不卡一二三区| 自拍视频在线观看一区二区| 国产91清纯白嫩初高中在线观看| 综合网在线视频| 日韩色视频在线观看| 99精品视频免费在线观看| 亚洲午夜电影在线观看| 久久综合成人精品亚洲另类欧美| 成人动漫一区二区三区| 午夜a成v人精品| 国产精品久久久久久久久免费桃花| 欧美日韩一区二区三区在线看| 精品一区二区三区视频在线观看| 国产精品二三区| 久久婷婷色综合| 91精品国产综合久久久久久漫画 | 日本高清不卡视频| 久久99蜜桃精品| 亚洲国产你懂的| 亚洲三级久久久| 国产视频一区不卡| 精品日产卡一卡二卡麻豆| 91色综合久久久久婷婷| 久久99国产精品久久| 一区二区三区蜜桃| 国产精品久久久久久久久快鸭 | 制服丝袜亚洲网站| 在线免费亚洲电影| 色综合色狠狠综合色| 国产精品99久久久久久久vr| 亚洲天堂中文字幕| 国产精品国产自产拍高清av | 日韩欧美在线影院| 欧美午夜精品久久久久久超碰| 国产精华液一区二区三区| 日韩高清在线不卡| 午夜精品福利视频网站| 亚洲日穴在线视频| 亚洲免费毛片网站| 玉米视频成人免费看| 国产精品久久久久一区二区三区 | 精品国产一区二区三区不卡| aaa欧美日韩| 99精品视频一区二区三区| 高清不卡一区二区在线| 国产一区二区91| 风间由美中文字幕在线看视频国产欧美| 久久99精品国产91久久来源| 亚洲精品国产精品乱码不99| 久久综合网色—综合色88| 欧美成人欧美edvon| 欧美日本一区二区三区四区| 不卡的av电影| 91成人国产精品| 欧美久久一二区| 精品99999| 中文字幕一区二区不卡| 亚洲品质自拍视频| 午夜电影一区二区三区| 日韩黄色一级片| 国产精品亚洲综合一区在线观看| 激情综合网天天干| 波多野结衣亚洲一区| 色先锋久久av资源部| 欧美熟乱第一页| 26uuu国产在线精品一区二区| 2021中文字幕一区亚洲| 亚洲国产精品ⅴa在线观看| 国产精品久久久久久久第一福利 | 亚洲成人一区二区在线观看| 亚洲精品水蜜桃| 久久机这里只有精品| 成人精品视频.| 色婷婷综合久久久久中文一区二区| 91首页免费视频| 日韩免费观看2025年上映的电影| 精品免费国产二区三区| 国产精品久久国产精麻豆99网站| 亚洲欧美日韩成人高清在线一区| 性感美女极品91精品| 蜜桃视频免费观看一区| 成人性生交大片免费| 欧美日韩一卡二卡三卡| 久久精子c满五个校花| 一区二区三区日韩精品视频|