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

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? 5.txt

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

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
久久久久国产免费免费| 亚洲欧美中日韩| 粉嫩绯色av一区二区在线观看| 亚洲精品乱码久久久久| 国产亚洲精品中文字幕| 日韩欧美第一区| 欧美日韩成人在线一区| 在线视频一区二区三区| 不卡的av网站| www.日韩精品| 91丨porny丨首页| 91福利在线观看| 欧美日本韩国一区二区三区视频 | 青青草原综合久久大伊人精品 | 国产精品久久久久久久久图文区| 久久综合一区二区| 国产三级欧美三级| 欧美精品乱码久久久久久按摩| 欧美午夜影院一区| 精品国产免费久久| 一色桃子久久精品亚洲| 国产xxx精品视频大全| 91精品国产色综合久久久蜜香臀| 日韩欧美中文字幕公布| 国产午夜精品理论片a级大结局| 亚洲成人激情社区| 国产米奇在线777精品观看| 久久国产视频网| 国产不卡视频在线观看| 欧美mv日韩mv亚洲| 久久久一区二区三区捆绑**| 日韩—二三区免费观看av| 国产高清在线精品| 欧美影视一区二区三区| 亚洲激情第一区| 在线观看一区不卡| 一区二区三区波多野结衣在线观看 | 欧美影院一区二区| 亚洲一区成人在线| 国产69精品久久久久毛片| 国产午夜亚洲精品羞羞网站| 高清在线不卡av| 中文字幕av一区 二区| 亚洲444eee在线观看| 欧美午夜在线观看| 免费在线观看视频一区| 欧美一区二区三区人| 久久国产尿小便嘘嘘尿| 久久久久国产精品厨房| 91在线你懂得| 久久久夜色精品亚洲| 高清成人在线观看| 亚洲欧美二区三区| 国产成人综合视频| 国产精品美女一区二区三区 | 国产精一区二区三区| 欧美电影在哪看比较好| 日本免费在线视频不卡一不卡二| 欧美一区二区精品在线| 激情综合色播激情啊| 欧美日韩亚洲综合一区 | 欧美一级一区二区| 国产在线观看一区二区| 亚洲欧美怡红院| 91精品国产综合久久精品麻豆| 国产精品伦理一区二区| 91九色最新地址| 日本视频在线一区| 中文字幕第一区二区| 在线免费视频一区二区| 男女激情视频一区| 1区2区3区精品视频| 91麻豆精品国产91久久久 | 在线免费不卡视频| 久久er精品视频| 亚洲人成在线观看一区二区| 欧美麻豆精品久久久久久| 国产成人福利片| 婷婷开心激情综合| 欧美精品免费视频| 国产精品99久久久久久久vr| 亚洲一二三专区| 2014亚洲片线观看视频免费| 在线欧美小视频| 成人av在线资源| 理论片日本一区| 亚洲制服丝袜在线| 一色屋精品亚洲香蕉网站| 26uuu亚洲综合色| 91福利资源站| 99综合电影在线视频| 美女性感视频久久| 精品国产91亚洲一区二区三区婷婷| 99re视频精品| 国产精品 欧美精品| 日韩精彩视频在线观看| 日韩一区二区三| 欧美亚洲国产bt| 99国产精品久久久| 岛国精品在线播放| 一区二区三区中文字幕电影 | 国产精品一区二区视频| 日韩电影免费一区| 亚洲一级在线观看| 一区二区在线电影| 国产精品视频免费看| 久久久亚洲精品石原莉奈| 日韩欧美激情四射| 欧美一区二区在线免费播放| 欧美亚洲图片小说| 欧美在线观看一区二区| 色婷婷国产精品久久包臀 | 国内成人自拍视频| 久久国产尿小便嘘嘘| 美腿丝袜亚洲色图| 麻豆91精品视频| 蜜臀av亚洲一区中文字幕| 日韩精品一区第一页| 婷婷综合另类小说色区| 亚洲va国产va欧美va观看| 亚洲大片一区二区三区| 亚洲大片免费看| 日韩电影在线一区二区三区| 日韩中文字幕不卡| 青青草精品视频| 久久99精品国产.久久久久| 亚洲天天做日日做天天谢日日欢| 欧美日韩一区在线观看| 欧美日韩国产欧美日美国产精品| 91国模大尺度私拍在线视频| 欧美在线观看视频在线| 欧美日韩亚洲综合在线 | 精品一区二区三区在线视频| 加勒比av一区二区| 国产.欧美.日韩| 91在线播放网址| 欧美三区免费完整视频在线观看| 欧美网站大全在线观看| 91精品国产色综合久久不卡电影| 精品少妇一区二区三区视频免付费 | 欧美区视频在线观看| 欧美大片免费久久精品三p | 欧美成人三级电影在线| 久久久精品免费观看| 亚洲精品视频在线| 久久99久久久欧美国产| 成人自拍视频在线| 欧美高清性hdvideosex| 国产拍欧美日韩视频二区| 亚洲精选视频在线| 久久成人18免费观看| 99精品视频一区| 日韩欧美久久一区| 中文字幕不卡在线观看| 偷窥国产亚洲免费视频| 粉嫩欧美一区二区三区高清影视| 色综合久久中文字幕| 日韩精品中文字幕在线一区| 亚洲天堂精品在线观看| 免费美女久久99| 97se亚洲国产综合自在线观| 欧美xxxx老人做受| 亚洲国产成人va在线观看天堂| 一区二区三区在线影院| 久久狠狠亚洲综合| 欧美伊人久久大香线蕉综合69| 久久亚洲一级片| 五月婷婷另类国产| 99免费精品在线| 久久人人爽爽爽人久久久| 亚洲国产裸拍裸体视频在线观看乱了| 狠狠色丁香久久婷婷综合丁香| 色吧成人激情小说| 久久精品欧美一区二区三区不卡| 日韩不卡一区二区| 91国偷自产一区二区三区成为亚洲经典| 精品国产乱码久久久久久夜甘婷婷| 一区二区三区国产豹纹内裤在线| 国内一区二区视频| 91精品午夜视频| 亚洲自拍另类综合| 99国产精品久久久久| 国产欧美一区二区在线观看| 老司机精品视频一区二区三区| 欧美日韩一区二区三区免费看 | 国产视频一区不卡| 免费的成人av| 欧美高清精品3d| 五月天中文字幕一区二区| 色一情一伦一子一伦一区| 国产精品毛片大码女人| 国产成人自拍高清视频在线免费播放 | 国产欧美日韩另类一区| 黑人精品欧美一区二区蜜桃| 欧美日韩成人高清| 亚洲国产成人精品视频| 欧美剧在线免费观看网站 | 欧美一区二区在线免费观看| 午夜国产精品一区| 6080亚洲精品一区二区|