版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、Linux操作系統(tǒng)原理與應(yīng)用第一章 操作系統(tǒng)概述認(rèn)識操作系統(tǒng) 操作系統(tǒng)的發(fā)展開放源代碼的Unix/Linux操作系統(tǒng) Linux內(nèi)核 Linux內(nèi)核源代碼 不同角度看到的操作系統(tǒng)操作系統(tǒng)整體看操作系統(tǒng)設(shè)計(jì)者使用者普通開發(fā)者認(rèn)識操作系統(tǒng)打開計(jì)算機(jī),首先跳入眼簾的是什么?要拷貝一個(gè)文件,具體的拷貝操作是誰完成的?你需要知道文件存放在何處嗎?柱面、磁道、扇區(qū)描述什么?數(shù)據(jù)的搬動(dòng)過程怎樣進(jìn)行繁瑣留給自己,簡單留給用戶 操作系統(tǒng)穿上華麗的外衣圖形界面操作系統(tǒng)穿上樸素的外衣字符界面認(rèn)識操作系統(tǒng)從使用者的角度看拷貝命令的C語言實(shí)現(xiàn)片斷inf=open(“/floppy/TEST”,O_RDONLY,0);o
2、ut=open(“/mydir/test”,O_WRONLY,0600); dol=read(inf,buf,4096);write(outf,buf,l); while(l);close(outf);close(inf);認(rèn)識操作系統(tǒng)從程序開發(fā)者的角度看 瀏覽器 信息管理 文件管理系統(tǒng) 游戲 編譯程序 編輯程序 命令 解釋程序 操作系統(tǒng) CPU、內(nèi)存、I/O接口硬件內(nèi)核 認(rèn)識操作系統(tǒng)從所處位置看操作系統(tǒng)是其它所有用戶程序運(yùn)行的基礎(chǔ)。 #includemain()printf(“ Hello worldn”)用戶告訴操作系統(tǒng)執(zhí)行test程序 操作系統(tǒng)通過文件名找到該程序 檢查其類型,檢查程序首
3、部,找出代碼和數(shù)據(jù)存放的地址文件系統(tǒng)找到第一個(gè)磁盤塊 操作系統(tǒng)建立程序的執(zhí)行環(huán)境 操作系統(tǒng)把程序從磁盤裝入內(nèi)存,并跳到程序開始處執(zhí)行 該程序的執(zhí)行過程簡述如下:操作系統(tǒng)檢查字符串的位置是否正確 操作系統(tǒng)找到字符串被送往的設(shè)備 操作系統(tǒng)將字符串送往輸出設(shè)備窗口系統(tǒng)確定這是一個(gè)合法的操作,然后將字符串轉(zhuǎn)換成像素窗口系統(tǒng)將像素寫入存儲映像區(qū) 視頻硬件將像素表示轉(zhuǎn)換成一組模擬信號控制顯示器(重畫屏幕) 顯示器發(fā)射電子束。你在屏幕上看到Hello world。 從中看到什么認(rèn)識操作系統(tǒng)從程序執(zhí)行看從操作系統(tǒng)設(shè)計(jì)者的角度看操作系統(tǒng)的設(shè)計(jì)目標(biāo)是什么?盡可能地方便用戶使用計(jì)算機(jī) 讓各種軟件資源和硬件資源高效而
4、協(xié)調(diào)地運(yùn)轉(zhuǎn)起來。 計(jì)算機(jī)的硬件資源和軟件資源各指什么?假設(shè)在一臺計(jì)算機(jī)上有三道程序同時(shí)運(yùn)行,并試圖在一臺打印機(jī)上輸出運(yùn)算結(jié)果,必須考慮哪些問題 ?從操作系統(tǒng)設(shè)計(jì)者的角度考慮,一個(gè)操作系統(tǒng)必須包含以下幾部分 操作系統(tǒng)接口CPU管理內(nèi)存管理設(shè)備管理文件管理認(rèn)識操作系統(tǒng)從設(shè)計(jì)者角度看 操作系統(tǒng)是計(jì)算機(jī)系統(tǒng)中的一個(gè)系統(tǒng)軟件,是一些程序模塊的集合它們能以盡量有效、合理的方式組織和管理計(jì)算機(jī)的軟硬件資源,合理的組織計(jì)算機(jī)的工作流程,控制程序的執(zhí)行并向用戶提供各種服務(wù)功能,使得用戶能夠靈活、方便、有效的使用計(jì)算機(jī),使整個(gè)計(jì)算機(jī)系統(tǒng)能高效、順暢地運(yùn)行。認(rèn)識操作系統(tǒng)定義操作系統(tǒng)的演變單道批處理系統(tǒng) 串行執(zhí)行預(yù)先
5、組織好的一組任務(wù) 提高了系統(tǒng)效率 。 多道批處理系統(tǒng) 可以交錯(cuò)運(yùn)行多個(gè)程序 再次提高系統(tǒng)效率。分時(shí)系統(tǒng)將處理器的運(yùn)行時(shí)間分成數(shù)片,均分或依照一定權(quán)重派發(fā)給系統(tǒng)中的用戶使用 快速響應(yīng) 操作系統(tǒng)的發(fā)展硬件角度下的操作系發(fā)展軌跡 年 代 硬 件 特點(diǎn) 操作系統(tǒng)特點(diǎn) 背 景 機(jī)械計(jì)算機(jī)時(shí)代17世紀(jì)20世紀(jì)初 1)純機(jī)械結(jié)構(gòu),低速2)只能進(jìn)行簡單的數(shù)學(xué)運(yùn)算 純手工操作 從計(jì)算尺至差分機(jī)到分析機(jī)發(fā)展了數(shù)百年第一代計(jì)算機(jī)1946年50年代末電子管計(jì)算機(jī) 1)體積大、能耗高、故障多、價(jià)格貴2)難以普及應(yīng)用 無操作系統(tǒng)(程序按機(jī)器碼編寫,載體從插件板到卡片與紙帶) 1906年發(fā)明電子管1946 ENIAC研制成
6、功(第一臺電子管計(jì)算機(jī)) 年 代 硬 件 特點(diǎn) 操作系統(tǒng)特點(diǎn) 背 景 第二代計(jì)算機(jī)50年代末60年代中期晶體管計(jì)算機(jī) 1)采用印刷電路2)穩(wěn)定性與可靠性大大提高3)批量生產(chǎn)成為可能4)進(jìn)入實(shí)際應(yīng)用領(lǐng)域但數(shù)量有限1)單道批處理系統(tǒng)2)操作系統(tǒng)以監(jiān)督軟件形式出現(xiàn)3)任務(wù)按順序方式處理 1947年發(fā)明晶體管 第三代計(jì)算機(jī)60年代中期70年代初集成電路計(jì)算機(jī) 1)體積減小,性價(jià)比迅速提高2)小型計(jì)算機(jī)發(fā)展迅速3)進(jìn)入商業(yè)應(yīng)用4)尚不適合家庭應(yīng)用的需求1)涌現(xiàn)大批操作系統(tǒng)多道批處理系統(tǒng)、分時(shí)系統(tǒng)和實(shí)時(shí)系統(tǒng)2)奠定了現(xiàn)代操作系統(tǒng)的基本框架 1958年發(fā)明集成電路1971年INTEL發(fā)明微處理器 硬件角度下
7、的操作系統(tǒng)發(fā)展軌跡分析在硬件的性價(jià)比較低的時(shí)候,操作系統(tǒng)設(shè)計(jì)追求什么? 在硬件性價(jià)比越來越高后,操作系統(tǒng)的設(shè)計(jì)開始追求的目標(biāo)是什么?計(jì)算機(jī)開始普及后,操作系統(tǒng)的設(shè)計(jì)開始追求?從第三代到第四代計(jì)算機(jī),操作系統(tǒng)的發(fā)展逐漸擺脫追隨硬件發(fā)展的狀況 ,形成自己的理論體系進(jìn)入第四代系統(tǒng)后,分布式系統(tǒng)和多處理器系統(tǒng)雖然極大的擴(kuò)充了操作系統(tǒng)理論,但系統(tǒng)結(jié)構(gòu)并沒有變化,只是各功能模塊得以進(jìn)一步完善。 操作系統(tǒng)的發(fā)展硬件角度下操作系統(tǒng)發(fā)展的分析主流操作系統(tǒng) 系統(tǒng)特點(diǎn) 計(jì) 算 機(jī) 語 言 背 景 無 手工操作 無編程語言直接使用機(jī)器代碼 1936年圖靈提出圖靈機(jī) 單道批處理系統(tǒng) 作業(yè)運(yùn)行的監(jiān)督程序 編程語言雛形期
8、1957年 FORTRAN語言開發(fā)成功多道批處理分時(shí)系統(tǒng)實(shí)時(shí)系統(tǒng)多處理系統(tǒng) 操作系統(tǒng)結(jié)構(gòu)確立,分為處理機(jī)管理、內(nèi)存管理、設(shè)備管理、文件管理等模塊 1)編程語言大量涌現(xiàn)2)結(jié)構(gòu)化程序設(shè)計(jì)3)C語言逐漸 60年代的軟件危機(jī)導(dǎo)致軟件工程的發(fā)展1969年 Unix誕生1972年 C語言推出 主流操作系統(tǒng) 系統(tǒng)特點(diǎn) 計(jì) 算 機(jī) 語 言 背 景 類Unix系列WINDOWS系列 人機(jī)交互成為主題1)可視化界面2)多媒體技 面向?qū)ο笳Z言成為主流 80年代中期開始面向?qū)ο蠹夹g(shù)逐步發(fā)展網(wǎng)絡(luò)操作系統(tǒng)分布式操作系統(tǒng) 微內(nèi)核技術(shù)興起 1)JAVA語言2)腳本語言興起 1995年JAVA推出 嵌入式系統(tǒng) 單內(nèi)核與微內(nèi)核
9、競爭激烈 編程工具向跨平臺方向發(fā) 1991年免費(fèi)的操作系統(tǒng)Linux發(fā)布 軟件角度下的操作系統(tǒng)發(fā)展軌跡 分析程序設(shè)計(jì)理論約束著操作系統(tǒng)設(shè)計(jì)。操作系統(tǒng)的發(fā)展滯后于計(jì)算機(jī)語言的發(fā)展,從結(jié)構(gòu)化設(shè)計(jì)到對象化設(shè)計(jì),操作系統(tǒng)總是最后應(yīng)用新編程理論的軟件之一。 至今操作系統(tǒng)對于是否需要徹底對象化(即微內(nèi)核化),還處于徘徊時(shí)期,仍在探索單內(nèi)核與微內(nèi)核的最佳結(jié)合方式。人機(jī)交互技術(shù)主要是為用戶考慮,這是對操作系統(tǒng)設(shè)計(jì)進(jìn)行的變革。 以Linux為代表的開源軟件的出現(xiàn),打破了帶有神秘色彩的傳統(tǒng)的封閉式開發(fā)模式。 軟件角度下的操作系統(tǒng)發(fā)展軌跡分析 講究效率的單模塊操作系統(tǒng)進(jìn)程管理內(nèi)存管理設(shè)備管理文件管理模塊之間可以互相
10、調(diào)用的單模塊結(jié)構(gòu)講究效率的單模塊操作系統(tǒng)模塊之間直接調(diào)用函數(shù),除了函數(shù)調(diào)用的開銷外,沒有額外開銷。龐大的操作系統(tǒng)有數(shù)以千計(jì)的函數(shù)復(fù)雜的調(diào)用關(guān)系勢必導(dǎo)致操作系統(tǒng)維護(hù)的困難追求簡潔的微內(nèi)核操作系統(tǒng)客戶進(jìn)程進(jìn)程服務(wù)器內(nèi)存服務(wù)器文件服務(wù)器微內(nèi)核追求簡潔的微內(nèi)核操作系統(tǒng)內(nèi)核與各個(gè)服務(wù)器之間通過通信機(jī)制進(jìn)行交互,這使得微內(nèi)核結(jié)構(gòu)的效率大大折扣。內(nèi)核發(fā)出請求,服務(wù)器做出應(yīng)答為各個(gè)服務(wù)器模塊的相對獨(dú)立性,使得其維護(hù)相對容易歷史悠久的Unix在MULTICS(1969) 的肩上制研制者Ken Thompson和Dennis M. Ritchie 站Unix的誕生還伴有C語言呱呱落地Unix是現(xiàn)代操作系統(tǒng)的代表:
11、安全、可靠、強(qiáng)大的計(jì)算能力Unix的商業(yè)化是一把雙刃劍 自由而奔放的黑馬Linux誕生于學(xué)生之手成長于Internet 壯大于自由而開放的文化Linux之父-Linus Torvalds芬蘭、赫爾辛基大學(xué)、1990起始于寫兩個(gè)進(jìn)程 然后寫驅(qū)動(dòng)程序、文件系統(tǒng)、任務(wù)切換程序,從而形成一個(gè)操作系統(tǒng)鄒形Linux得以流行的原因之一 遵循POSIX標(biāo)準(zhǔn)POSIX 表示可移植操作系統(tǒng)接口(Portable Operating System Interface) POSIX是在Unix標(biāo)準(zhǔn)化過程中出現(xiàn)的產(chǎn)物。 POSIX 1003.1標(biāo)準(zhǔn)定義了一個(gè)最小的Unix操作系統(tǒng)接口 任何操作系統(tǒng)只有符合這一標(biāo)準(zhǔn),才
12、有可能運(yùn)行Unix程序 Linux的肥沃土壤GNUGNU 是 GNU Is Not Unix 的遞歸縮寫,是自由軟件基金會(huì)的一個(gè)項(xiàng)目 。 GNU 項(xiàng)目產(chǎn)品包括 emacs 編輯器、著名的 GNU C 和 Gcc編譯器等,這些軟件叫做GNU軟件。GNU 軟件和派生工作均適用 GNU 通用公共許可證,即 GPL(General Public License ) Linux的開發(fā)使用了眾多的GUN工具GPL開源軟件的法律GPL 允許軟件作者擁有軟件版權(quán) 但GPL規(guī)定授予其他任何人以合法復(fù)制、發(fā)行和修改軟件的權(quán)利。Linux系統(tǒng)或發(fā)布版 符合 POSIX 標(biāo)準(zhǔn)的操作系統(tǒng)內(nèi)核、 Shell 和外圍工具。
13、 C 語言編譯器和其他開發(fā)工具及函數(shù)庫 X Window 窗口系統(tǒng) 各種應(yīng)用軟件,包括字處理軟件、圖象處理軟件等。 開放與協(xié)作的開發(fā)模式 世界各地軟件愛好者集體智慧的結(jié)晶 提供源代碼,遵守GPL。 經(jīng)歷了各種各樣的測試與考驗(yàn),軟件的穩(wěn)定性好。 開發(fā)人員憑興趣去開發(fā),熱情高,具有創(chuàng)造性。 Linux內(nèi)核 Linus領(lǐng)導(dǎo)下的開發(fā)小組開發(fā)出的系統(tǒng)內(nèi)核 是所有Linux 發(fā)布版本的核心 內(nèi)核開發(fā)人員一般在百人以上,任何自由程序員都可以提交自己的修改工作。 采用郵件列表來進(jìn)行項(xiàng)目管理、交流、錯(cuò)誤報(bào)告有大量的用戶進(jìn)行測試,正式發(fā)布的代碼質(zhì)量高 整個(gè)系統(tǒng)的核心內(nèi)核 硬件系統(tǒng)調(diào)用接口應(yīng)用程序進(jìn)程1應(yīng)用程序進(jìn)程
14、2應(yīng)用程序進(jìn)程3Linux內(nèi)核用戶進(jìn)程 內(nèi)核子系統(tǒng)系統(tǒng)調(diào)用整個(gè)系統(tǒng)的核心內(nèi)核 用戶進(jìn)程運(yùn)行在Linux內(nèi)核之上的一個(gè)龐大軟件集合。系統(tǒng)調(diào)用內(nèi)核的出口,用戶程序通過它使用內(nèi)核提供的功能。 Linux內(nèi)核操作系統(tǒng)的靈魂,負(fù)責(zé)管理磁盤上的文件、內(nèi)存,負(fù)責(zé)啟動(dòng)并運(yùn)行程序,負(fù)責(zé)從網(wǎng)絡(luò)上接收和發(fā)送數(shù)據(jù)包等等。 硬件包括了Linux安裝時(shí)需要的所有可能的物理設(shè)備。例如,CPU、 內(nèi)存、硬盤、網(wǎng)絡(luò)硬件等等。 內(nèi)核子系統(tǒng) 內(nèi)核子系統(tǒng) 進(jìn)程調(diào)度控制著進(jìn)程對CPU的訪問。 內(nèi)存管理允許多個(gè)進(jìn)程安全地共享主內(nèi)存區(qū)域 虛擬文件系統(tǒng)隱藏各種不同硬件的具體細(xì)節(jié),為所有設(shè)備提供統(tǒng)一的接口。網(wǎng)絡(luò)提供了對各種網(wǎng)絡(luò)標(biāo)準(zhǔn)協(xié)議的存取和
15、各種網(wǎng)絡(luò)硬件的支持。 進(jìn)程間通信(IPC) 支持進(jìn)程間各種通信機(jī)制,包括共享內(nèi)存、消息隊(duì)列及管道等。 Linux內(nèi)核版本樹 0.01Linux(第一版)0.13版 | 產(chǎn)品化版本實(shí)驗(yàn)版本 1.0.0 1.1.0(1.0.0的拷貝) 1.0.X(修改)1.1.X(增加新功能,進(jìn)行測試) 1.1.95(成為1.2.0) 內(nèi)核源代碼結(jié)構(gòu)Linux內(nèi)核源代碼分析工具 Linux超文本交叉代碼檢索工具 http:/lxr.linux.no/ Windows平臺下的源代碼閱讀工具Source Insight“內(nèi)核之旅 ”網(wǎng)站 /電子雜志欄目是關(guān)于內(nèi)核研究和學(xué)習(xí)的資料 第一期“走入Linux世界”涉獵了操作
16、系統(tǒng)的來龍去脈后與大家攜手步入Linux世界。下載代碼,親手搭建實(shí)驗(yàn)系統(tǒng)。第二章 內(nèi)存尋址內(nèi)存尋址的演變 段機(jī)制分頁機(jī)制 Linux中的匯編語言 Linux系統(tǒng)地址映射示例 內(nèi)存尋址操作系統(tǒng)設(shè)計(jì)的硬件基礎(chǔ)之一操作系統(tǒng)橫跨軟件和硬件的橋梁內(nèi)存尋址操作系統(tǒng)設(shè)計(jì)的硬件基礎(chǔ)之一 操作系統(tǒng)的設(shè)計(jì)者必須在硬件相關(guān)的代碼與硬件無關(guān)的代碼之間劃出清楚的界限,以便于一個(gè)操作系統(tǒng)很容易地移植到不同的平臺。 在這眾多的平臺中,大家最熟悉的就是i386,即Intel80386體系結(jié)構(gòu)。因此,我們所介紹的內(nèi)存尋址也是以此為背景。 內(nèi)存尋址的不同時(shí)期石器時(shí)期8位 青銅時(shí)期16位白銀時(shí)期24位 黃金時(shí)期32位 石器時(shí)期8位
17、尋址在微處理器的歷史上,第一款微處理器芯片4004是由Intel推出的,4位。在4004之后,intel推出了一款8位處理器叫8080,它有1個(gè)主累加器(寄存器A)和6個(gè)次累加器(寄存器B,C,D,E,H和L)那時(shí)沒有段的概念,訪問內(nèi)存都要通過絕對地址,因此程序中的地址必須進(jìn)行硬編碼(給出具體地址),而且也難以重定位青銅時(shí)期“段”的引入intel開發(fā)出的16位的處理器叫8086,標(biāo)志著Intel X86王朝的開始,同時(shí)引入了“段 ”概念。段描述了一塊有限的內(nèi)存區(qū)域,區(qū)域的起始位置存在專門的寄存器(段寄存器)中。8086處理器地址線擴(kuò)展到了20位,尋址空間到了1M也就是把1M大的空間分成數(shù)個(gè)64
18、k的段來管理(化整為零了)。把16位的段地址左移動(dòng)4位后,再與16位的偏移量相加便可獲得一個(gè)20位的內(nèi)存地址,白銀時(shí)期“保護(hù)模式”的引入intel的80286處理器于1982年問世 。地址總線位數(shù)增加到了24位 。從此開始引進(jìn)了一個(gè)全新理念保護(hù)模式 訪問內(nèi)存時(shí)不能直接從段寄存器中獲得段的起始地址了,而需要經(jīng)過額外轉(zhuǎn)換和檢查 。80286處理器一些致命的缺陷注定不能長久,它很快被天資卓越的兄弟80386代替了 黃金時(shí)期內(nèi)存尋址的飛躍80386是一個(gè)32位的CPU,其尋址能力達(dá)到4GB Intel選擇了在段寄存器的基礎(chǔ)上構(gòu)筑保護(hù)模式,并且保留段寄存器16位 在保護(hù)模式下,它的段范圍不再受限于64K
19、,可以達(dá)到4G這真正解放了軟件工程師,他們不必再費(fèi)盡心思去壓縮程序規(guī)模,軟件功能也因此迅速提升 從80386以后,Intel的CPU經(jīng)歷了80486、Pentium、PentiumII、PentiumIII等型號,但基本上屬于同一種系統(tǒng)結(jié)構(gòu)的改進(jìn)與加強(qiáng),而無本質(zhì)的變化,所以我們把80386以后的處理器統(tǒng)稱為IA32(32 Bit Intel Architecture)。IA32寄存器簡介 把16位的通用寄存器、標(biāo)志寄存器以及指令指針寄存器擴(kuò)充為32位的寄存器 段寄存器仍然為16位。 增加4個(gè)32位的控制寄存器 增加4個(gè)系統(tǒng)地址寄存器 增加8個(gè)調(diào)式寄存器 增加2個(gè)測試寄存器常用寄存器簡介 通用寄
20、存器8個(gè)通用寄存器是8086寄存器的超集,它們分別為:EAX ,EBX ,ECX ,EDX ,EBP ,EBP, ESI及 EDI 段寄存器8086中有4個(gè)16位的段寄存器:CS、DS、SS、ES,分別用于存放可執(zhí)行代碼的代碼段、數(shù)據(jù)段、堆棧段和其他段的基地址。這些段寄存器中存放的不再是某個(gè)段的基地址,而是某個(gè)段的選擇符(Selector) 段基地址存放在段描述符表(Descriptor )中,表的索引就是選擇符 常用寄存器簡介 指令指針寄存器 指令指針寄存器EIP中存放下一條將要執(zhí)行指令的偏移量(offset ),這個(gè)偏移量是相對于目前正在運(yùn)行的代碼段寄存器CS而言的。偏移量加上當(dāng)前代碼段的
21、基地址,就形成了下一條指令的地址。 EIP中的低16位可以被單獨(dú)訪問,給它起名叫指令指針I(yè)P寄存器,用于16位尋址。 標(biāo)志寄存器 標(biāo)志寄存器EFLAGS存放有關(guān)處理器的控制標(biāo)志,很多標(biāo)志與16位FLAGS中的標(biāo)志含義一樣。 用于分頁機(jī)制的控制寄存器 物理地址、虛擬地址及線性地址 將主板上的物理內(nèi)存條所提供的內(nèi)存空間定義為物理內(nèi)存空間,其中每個(gè)內(nèi)存單元的實(shí)際地址就是物理地址將應(yīng)用程序員看到的內(nèi)存空間定義為虛擬地址空間(或地址空間),其中的地址就叫虛擬地址(或虛地址), 一般用“段:偏移量”的形式來描述 線性地址空間是指一段連續(xù)的,不分段的,范圍為0到4GB的地址空間,一個(gè)線性地址就是線性地址空間
22、的一個(gè)絕對地址。 地址之間的轉(zhuǎn)換保護(hù)模式下的尋址 CPUMMU內(nèi)存磁盤控制器總線CPU把虛地址送給MMU MMU把物理地址送給存儲器地址之間的轉(zhuǎn)換MMU機(jī)制虛擬地址段機(jī)制 段是虛擬地址空間的基本單位,段機(jī)制必須把虛擬地址空間的一個(gè)地址轉(zhuǎn)換為線性地址空間的一個(gè)線性地址。用三個(gè)方面來描述段 段的基地址(Base Address):在線性地址空間中段的起始地址。 段的界限(Limit):在虛擬地址空間中,段內(nèi)可以使用的最大偏移量。 段的保護(hù)屬性(Attribute): 表示段的特性。例如,該段是否可被讀出或?qū)懭耄蛘咴摱问欠褡鳛橐粋€(gè)程序來執(zhí)行,以及段的特權(quán)級等等。 虛擬線性地址的轉(zhuǎn)換 虛擬地址空間段
23、描述符表段表 如圖所示的段描述符表(或叫段表)來描述轉(zhuǎn)換關(guān)系。段號描述的是虛擬地址空間段的編號,基地址是線性地址空間段的起始地址。段描述符表中的每一個(gè)表項(xiàng)叫做段描述符012 索引(段號) 基地址 界限 屬性 Baseb Limitb Attributeb Basea Limita Attributea Basec LimitcAttributec保護(hù)模式下的其他描述符表簡介 全局描述符表GDT(Gloabal Descriptor Table)中斷描述符表IDT(Interrupt Descriptor Table) 局部描述符表LDT(Local Descriptor Table)為了加快對
24、這些表的訪問,Intel設(shè)計(jì)了專門的寄存器,以存放這些表的基地址及表的長度界限 。這些寄存器只供操作系統(tǒng)使用。有關(guān)這些表的詳細(xì)內(nèi)容請參看有關(guān)保護(hù)模式的參考書。 保護(hù)模式下段寄存器中存放什么 存放索引或叫段號,因此,這里的段寄存器也叫選擇符,即從描述符表中選擇某個(gè)段。選擇符(段寄存器)的結(jié)構(gòu): RPL表示請求者的特權(quán)級(Requestor Privilege Level) 保護(hù)模式下的特權(quán)級 保護(hù)模式提供了四個(gè)特權(quán)級,用03四個(gè)數(shù)字表示 很多操作系統(tǒng)(包括Linux,Windwos)只使用了其中的最低和最高兩個(gè),即0表示最高特權(quán)級,對應(yīng)內(nèi)核態(tài);3表示最低特權(quán)級,對應(yīng)用戶態(tài)。保護(hù)模式規(guī)定,高特權(quán)級
25、可以訪問低特權(quán)級,而低特權(quán)級不能隨便訪問高特權(quán)級。地址轉(zhuǎn)換及保護(hù) Linux中的段Linux是怎樣處理段機(jī)制?分頁機(jī)制頁將線性地址空間劃分成若干大小相等的片,稱為頁(Page) 物理地址空間分成與頁大小相等的若干存儲塊,稱為(物理)塊或頁面(Page Frame)頁的大小應(yīng)該為多少?由誰確定? 分頁機(jī)制頁表頁表是把線性地址映射到物理地址的一種數(shù)據(jù)結(jié)構(gòu)。 頁表中應(yīng)當(dāng)包含如下內(nèi)容:物理頁面基地址:線性地址空間中的一個(gè)頁裝入內(nèi)存后所對應(yīng)的物理頁面的起始地址。 頁的屬性:表示頁的特性。例如該頁是否在內(nèi)存,是否可被讀出或?qū)懭氲?。頁面的大小?KB ,物理頁面基地址需要多少位就可以? 分頁機(jī)制頁表項(xiàng)結(jié)構(gòu)物
26、理頁面基地址: 指的是頁所對應(yīng)的物理頁面在內(nèi)存的起始物理地址。相當(dāng)于物理塊號(為什么?)其最低12位全部為0,因此用高20位來描述32位的地址。 屬性見書 物理頁面基地址 屬性31 11 0 分頁機(jī)制兩級頁表為什么要采用兩級頁表? 頁目錄頁表物理頁面分頁機(jī)制線性地址結(jié)構(gòu)這個(gè)結(jié)構(gòu)的偽代碼描述如下 typedef struct unsigned int dir:10; /*用作頁目錄中的下標(biāo),對應(yīng)的 目錄項(xiàng)指向一個(gè)頁表*/ unsigned int page:10 /*用作頁表的下標(biāo),對應(yīng)的頁表 項(xiàng)指向一個(gè)物理頁面*/ unsigned int offset:12 /*在4K字物理頁面內(nèi)的偏移量*
27、/ LinearAddr 頁目錄 頁 頁內(nèi)偏移量31 22 12 0 分頁機(jī)制硬件保護(hù)機(jī)制對于頁表,頁的保護(hù)是由屬性部分的U/S標(biāo)志和R/W標(biāo)志來控制的。當(dāng)U/S標(biāo)志為0時(shí),只有處于內(nèi)核態(tài)的操作系統(tǒng)才能對此頁或頁表進(jìn)行尋址。當(dāng)這個(gè)標(biāo)志為1時(shí),則不管在內(nèi)核態(tài)還是用戶態(tài),總能對此頁進(jìn)行尋址。 此外,與段的三種存取權(quán)限(讀、寫、執(zhí)行)不同,頁的存取權(quán)限只有兩種(讀、寫)。如果頁目錄項(xiàng)或頁表項(xiàng)的讀寫標(biāo)志為0,說明相應(yīng)的頁表或頁是只讀的,否則是可讀寫的。 分頁機(jī)制線性地址到物理地址的轉(zhuǎn)換 分頁機(jī)制分頁示例假如操作系統(tǒng)給一個(gè)正在運(yùn)行的進(jìn)程分配的線性地址空間范圍是0 x20000000 到 0 x2003f
28、fff。這個(gè)空間由64頁組成。 我們從分配給進(jìn)程的線性地址的最高10位(分頁硬件機(jī)制把它自動(dòng)解釋成頁目錄域)開始。這兩個(gè)地址都以2開頭,后面跟著0,因此高10位有相同的值,即十六進(jìn)制的0 x080或十進(jìn)制的128。因此,這兩個(gè)地址的頁目錄域都指向進(jìn)程頁目錄的第129項(xiàng)。相應(yīng)的目錄項(xiàng)中必須包含分配給進(jìn)程的頁表的物理地址,如圖2.13。如果給這個(gè)進(jìn)程沒有分配其它的線性地址,則頁目錄的其余1023項(xiàng)都為0,也就是這個(gè)進(jìn)程在頁目錄中只占一項(xiàng)。 分頁機(jī)制分頁示例1023(0 x3ff) 128(0 x80) 1023(0 x3ff)64(0 x040) 63(0 x03f) 頁目錄頁表假設(shè)進(jìn)程需要讀線性
29、地址0 x20021406中的內(nèi)容。這個(gè)地址由分頁機(jī)制如何進(jìn)行處理?分頁機(jī)制頁面高速緩存 分頁機(jī)制Linux中的分頁 Linux主要采用分頁機(jī)制來實(shí)現(xiàn)虛擬存儲器管理,因?yàn)? Linux的分段機(jī)制使得所有的進(jìn)程都使用相同的段寄存器值,這就使得內(nèi)存管理變得簡單,也就是說,所有的進(jìn)程都使用同樣的線性地址空間(04G)。 Linux設(shè)計(jì)目標(biāo)之一就是能夠把自己移植到絕大多數(shù)流行的處理器平臺。但是,許多RISC處理器支持的段功能非常有限。 為了保持可移植性,Linux采用三級分頁模式而不是兩級 分頁機(jī)制Linux中的分頁 Linux中的C語言和匯編語言 GNU 的C語言 /docs/learnc/AT&T
30、的匯編:參見書 Linux系統(tǒng)地址映射示例Linux采用分頁存儲管理。虛擬地址空間劃分成固定大小的“頁”,由MMU在運(yùn)行時(shí)將虛擬地址映射(變換)成某個(gè)物理頁面中的地址 IA32的MMU對程序中的虛擬地址先進(jìn)行段式映射(虛擬地址轉(zhuǎn)換為線性地址),然后才能進(jìn)行頁式映射(線性地址轉(zhuǎn)換為物理地址)Linux巧妙地使段式映射實(shí)際上不起什么作用 Linux系統(tǒng)地址映射示例 假定我們有一個(gè)簡單的C程序Hello.c # include greeting ( ) printf(“Hello,world!n”); main() greeting(); Linux系統(tǒng)地址映射示例用Linux的實(shí)用程序objdum
31、p對其可執(zhí)行代碼進(jìn)行反匯編:% objdump d hello08048568 : 8048568: pushl %ebp 8048569: movl %esp, %ebp 804856b: pushl $0 x809404 8048570: call 8048474 8048575: addl $0 x4, %esp 8048578: leave 8048579: ret 804857a: movl %esi, %esi 0804857c : 804857c: pushl %ebp 804857d: movl %esp, %ebp 804857f: call 8048568 8048584:
32、 leave 8048585: ret 8048586: nop 8048587: nopLinux系統(tǒng)地址映射示例Linux最常見的可執(zhí)行文件格式為elf(Executable and Linkable Format)。 在elf格式的可執(zhí)行代碼中,ld總是從0 x8000000開始安排程序的“代碼段” ,這個(gè)地址就是虛地址程序執(zhí)行時(shí)在物理內(nèi)存中的實(shí)際地址,則由內(nèi)核為其建立內(nèi)存映射時(shí)臨時(shí)分配,具體地址取決于當(dāng)時(shí)所分配的物理內(nèi)存頁面。 0 x08048568 如何轉(zhuǎn)化為物理地址?本章小節(jié)內(nèi)存尋址的演變 段機(jī)制分頁機(jī)制 Linux中的匯編語言 Linux系統(tǒng)地址映射示例 “內(nèi)核之旅 ”網(wǎng)站/電子
33、雜志欄目是關(guān)于內(nèi)核研究和學(xué)習(xí)的資料 第二期“i386體系結(jié)構(gòu)分兩部分,上半部分讓大家認(rèn)識一下Intel系統(tǒng)中的內(nèi)存尋址和虛擬內(nèi)存的來龍去脈。下半部分將實(shí)現(xiàn)一個(gè)最短小的可啟動(dòng)內(nèi)核,一是加深對i386體系的了解,再就是演示系統(tǒng)開發(fā)的原始過程。下載代碼進(jìn)行調(diào)試第三章 進(jìn)程進(jìn)程介紹 進(jìn)程控制塊 進(jìn)程的組織方式 進(jìn)程調(diào)度 進(jìn)程的創(chuàng)建 與進(jìn)程相關(guān)的系統(tǒng)調(diào)用及其應(yīng)用 與調(diào)度相關(guān)的系統(tǒng)調(diào)用及應(yīng)用 進(jìn)程介紹程序和進(jìn)程 進(jìn)程介紹進(jìn)程層次結(jié)構(gòu) initABCDE進(jìn)程介紹進(jìn)程狀態(tài) 運(yùn)行態(tài)阻塞態(tài)就緒態(tài)進(jìn)程介紹進(jìn)程示例include /* 提供類型pid_t的定義,在PC機(jī)上與int型 相同 */#include /*
34、提供系統(tǒng)調(diào)用的定義 */ main() pid_t pid;/*此時(shí)僅有一個(gè)進(jìn)程*/ printf(“PID before fork():%dn”,(int)getpid(); pid=fork(); /*此時(shí)已經(jīng)有兩個(gè)進(jìn)程在同時(shí)運(yùn)行*/ if(pidpid返回正在執(zhí)行的進(jìn)程的標(biāo)識符 進(jìn)程的組織方式-進(jìn)程鏈表 在task_struct中定義如下: task_struct *prev_task, *next_task宏for_each_task()遍歷整個(gè)進(jìn)程鏈表 #define for_each_task(p) for (p = &init_task ; (p = p-next_task) !
35、= &init_task ; ) 進(jìn)程的組織方式-哈希表 哈希函數(shù) #define pid_hashfn(x) (x) 8) (x) & (PIDHASH_SZ - 1) 圖為地址法處理沖突時(shí)的哈希表假定哈希表義為: struct task_struct *pidhashPIDHASH_SZ 對給定的PID,如何快速找到對應(yīng)進(jìn)程? 進(jìn)程的組織方式-可運(yùn)行隊(duì)列 把可運(yùn)行狀態(tài)的進(jìn)程組成一個(gè)雙向循環(huán)鏈表,也叫可運(yùn)行隊(duì)列(runqueue) 在task_struct結(jié)構(gòu)中定義了兩個(gè)指針。 struct task_struct *next_run, *prev_run;init_task起鏈表頭的作用在
36、調(diào)度程序運(yùn)行過程中,允許隊(duì)列中加入新出現(xiàn)的可運(yùn)行態(tài)進(jìn)程,新出現(xiàn)的可運(yùn)行態(tài)進(jìn)程插入到隊(duì)尾 進(jìn)程的組織方式-等待隊(duì)列等待隊(duì)列表示一組睡眠的進(jìn)程 可以把等待隊(duì)列定義為如下結(jié)構(gòu): struct wait_queue struct task_struct * task; struct wait_queue * next; ; 如何讓正在運(yùn)行的進(jìn)程等待某一特定事件? Linux內(nèi)核中實(shí)現(xiàn)了sleep_on()函數(shù),請給出該函數(shù)的實(shí)現(xiàn)。如果要讓等待的進(jìn)程喚醒,就調(diào)用喚醒函數(shù)wake_up(),它讓待喚醒的進(jìn)程進(jìn)入TASK_RUNNING狀態(tài)。 進(jìn)程調(diào)度-調(diào)度算法考慮的因素公平:保證每個(gè)進(jìn)程得到合理的CPU時(shí)
37、間。 高效:使CPU保持忙碌狀態(tài),即總是有進(jìn)程在CPU上運(yùn)行。 響應(yīng)時(shí)間:使交互用戶的響應(yīng)時(shí)間盡可能短。 周轉(zhuǎn)時(shí)間:使批處理用戶等待輸出的時(shí)間盡可能短。吞吐量:使單位時(shí)間內(nèi)處理的進(jìn)程數(shù)量盡可能多。進(jìn)程調(diào)度-調(diào)度算法時(shí)間片輪轉(zhuǎn)調(diào)度算法 系統(tǒng)使每個(gè)進(jìn)程依次地按時(shí)間片輪流地執(zhí)行 優(yōu)先權(quán)調(diào)度算法 非搶占式優(yōu)先權(quán)算法 搶占式優(yōu)先權(quán)調(diào)度算法 多級反饋隊(duì)列調(diào)度 優(yōu)先權(quán)高的進(jìn)程先運(yùn)行給定的時(shí)間片,相同優(yōu)先權(quán)的進(jìn)程輪流運(yùn)行給定的時(shí)間片 實(shí)時(shí)調(diào)度 一般采用搶占式調(diào)度方式 進(jìn)程調(diào)度-時(shí)間片 時(shí)間片表明進(jìn)程在被搶占前所能持續(xù)運(yùn)行的時(shí)間。 時(shí)間片過長會(huì)導(dǎo)致系統(tǒng)對交互的響應(yīng)表現(xiàn)欠佳 時(shí)間片太短會(huì)明顯增大進(jìn)程切換帶來的處理
38、器時(shí)間。Linux調(diào)度程序提高交互式程序的優(yōu)先級,讓它們運(yùn)行得更頻繁,于是,調(diào)度程序提供較長的默認(rèn)時(shí)間片給交互式程序 Linux調(diào)度程序還根據(jù)進(jìn)程的優(yōu)先級動(dòng)態(tài)調(diào)整分配給它的時(shí)間片 進(jìn)程調(diào)度-調(diào)度時(shí)機(jī) 進(jìn)程狀態(tài)轉(zhuǎn)換的時(shí)刻:進(jìn)程終止、進(jìn)程睡眠 當(dāng)前進(jìn)程的時(shí)間片用完時(shí);設(shè)備驅(qū)動(dòng)程序運(yùn)行時(shí); 從內(nèi)核態(tài)返回到用戶態(tài)時(shí); 為什么在這些時(shí)機(jī)返回?進(jìn)程調(diào)度-與調(diào)度相關(guān)的域need_resched:調(diào)度標(biāo)志,以決定是否調(diào)用schedule( )函數(shù)。 counter: 進(jìn)程處于可運(yùn)行狀態(tài)時(shí)所剩余的時(shí)鐘節(jié)拍(即時(shí)鐘中斷的間隔時(shí)間,為10ms或1ms)數(shù)。這個(gè)域也叫動(dòng)態(tài)優(yōu)先級。priority: 進(jìn)程的基本優(yōu)先級或
39、叫“靜態(tài)優(yōu)先級”rt_priority: 實(shí)時(shí)進(jìn)程的優(yōu)先級 policy: 調(diào)度的類型,允許的取值是: SCHED_FIFO:先入先出的實(shí)時(shí)進(jìn)程 SCHED_RR:時(shí)間片輪轉(zhuǎn)的實(shí)時(shí)進(jìn)程 SCHED_OTHER:普通的分時(shí)進(jìn)程。 進(jìn)程調(diào)度-衡量值得運(yùn)行的程度static inline int goodness(struct task_struct * p, struct task_struct *prev) int weight; * 權(quán)值,作為衡量進(jìn)程是否運(yùn)行的唯一依據(jù) */if (p-police!=SCHED_OTHER) /*實(shí)時(shí)進(jìn)程*/ weight = 1000 + p-rt_pri
40、ority; goto out weight = p-counter; /*普通進(jìn)程*/if(!weight) / *p用完了時(shí)間片*/ goto out; if(p =prev) * 細(xì)微調(diào)整 */weight+= 1; weight+=p-priorityout: return weight 調(diào)度函數(shù)schedule( )-變量說明 struct task_truct current, *prev, *next;current:全局變量,表示當(dāng)前正在運(yùn)行的進(jìn)程。 prev:局部變量,表示調(diào)度發(fā)生之前運(yùn)行的進(jìn)程,用它保存current的值。 next: 局部變量,表示調(diào)度發(fā)生之后要運(yùn)行的進(jìn)程
41、。c:局部變量,進(jìn)程值得運(yùn)行的程度schedule( )函數(shù)的關(guān)鍵操作是設(shè)置局部變量next,以使next代替prev而指向被選中進(jìn)程的PCB。調(diào)度函數(shù)schedule( ) 片段如果prev進(jìn)程時(shí)間片用完,而且還是實(shí)時(shí)進(jìn)程,就給它分配新的時(shí)間片,并讓它到可運(yùn)行隊(duì)列末尾: if (prev-policy = SCHED_RR&!prev-counter) prev-counter = prev-priority; move_last_runqueue(prev); 調(diào)度函數(shù)schedule( ) 片段如果prev進(jìn)程處于淺度睡眠狀態(tài),而且它有未處理的信號,就應(yīng)當(dāng)喚醒它,給它一個(gè)被選擇執(zhí)行的機(jī)會(huì)
42、。 if (prev-state = TASK_INTERRUPTIBLE & signal_pending(prev) prev-state = TASK_RUNNING; 如果prev進(jìn)程不是可運(yùn)行狀態(tài),說明它必須等待某一外部資源,那就讓它去睡覺,因此,必須從運(yùn)行隊(duì)列鏈表中刪除prev: if (prev-state != TASK_RUNNING) del_from_runqueue(prev); 調(diào)度函數(shù)schedule( ) 片段把next初始化為要檢查的第一個(gè)可運(yùn)行進(jìn)程。 if (prev-state = TASK_RUNNING) next = prev; if (prev-po
43、licy & SCHED_YIELD) *自愿放棄CPU */ prev-policy &= SCHED_YIELD; c = 0; else c = goodness(prev, prev); else c = -1000; *永不選中,運(yùn)行隊(duì)列鏈表只包含 init_task */ next = &init_task; 調(diào)度函數(shù)schedule( ) 片段schedule( ) 在可運(yùn)行進(jìn)程隊(duì)列上重復(fù)調(diào)用goodness( )函數(shù)以確定最佳后選者:p = init_task.next_run; while (p != &init_task) weight = goodness(prev, p
44、); if (weight c) c = weight; next = p; p = p-next_run; 調(diào)度函數(shù)schedule( ) 片段現(xiàn)在到了schedule( )的結(jié)束部分:如果已選擇了一個(gè)進(jìn)程,進(jìn)程切換必定發(fā)生:if (prev != next) kstat.context_swtch+; * 統(tǒng)計(jì)進(jìn)程切換的次數(shù)*/ switch_to(prev,next); /* 從prev切換到next*/ return; 進(jìn)程的創(chuàng)建進(jìn)程的創(chuàng)建fork()借用現(xiàn)實(shí)世界的“克隆”技術(shù) 子進(jìn)程克隆父進(jìn)程,但不僅如此。而是采用了“寫時(shí)復(fù)制 ”技術(shù)父進(jìn)程并不是把自己的所有東西馬上都給兒子,而是直到
45、兒子真正需要時(shí)才給它。也就是當(dāng)父進(jìn)程或子進(jìn)程試圖修改某些內(nèi)容時(shí),內(nèi)核才在修改之前將被修改的部分進(jìn)行拷貝這叫做寫時(shí)復(fù)制。fork()的實(shí)際開銷就是復(fù)制父進(jìn)程的頁表以及給子進(jìn)程創(chuàng)建唯一的PCB 進(jìn)程的創(chuàng)建fork()進(jìn)程創(chuàng)建函數(shù)fork()和線程創(chuàng)建函數(shù)clone()都調(diào)用內(nèi)核函數(shù)do_fork(),其主要操作:調(diào)用alloc_task_struct( )函數(shù)以獲得8KB的union task_union內(nèi)存區(qū),用來存放新進(jìn)程的PCB和內(nèi)核棧。 讓當(dāng)前指針指向父進(jìn)程的PCB,并把父進(jìn)程PCB的內(nèi)容拷貝到剛剛分配的新進(jìn)程的PCB中。檢查新創(chuàng)建這個(gè)子進(jìn)程后,當(dāng)前用戶所擁有的進(jìn)程數(shù)目沒有超出給他分配的資
46、源的限制?,F(xiàn)在, do_fork( )已經(jīng)獲得它從父進(jìn)程能利用的幾乎所有的東西;剩下的事情就是集中建立子進(jìn)程的新資源,并讓內(nèi)核知道這個(gè)新進(jìn)程已經(jīng)呱呱落地。進(jìn)程的創(chuàng)建fork()接下來,子進(jìn)程的狀態(tài)被設(shè)置為TASK_UNINTERRUPTIBLE以保證它不會(huì)馬上投入運(yùn)行。 調(diào)用get_pid()為新進(jìn)程獲取一個(gè)有效的PID。 然后,更新不能從父進(jìn)程繼承的PCB的其他所有域,例如,進(jìn)程間親屬關(guān)系的域。 把新的PCB插入進(jìn)程鏈表,以確保進(jìn)程之間的親屬關(guān)系。把新的PCB插入pidhash哈希表。 把子進(jìn)程PCB的狀態(tài)域設(shè)置成TASK_RUNNING,并調(diào)用wake_up_process( )把子進(jìn)程插
47、入到運(yùn)行隊(duì)列鏈表。 讓父進(jìn)程和子進(jìn)程平分剩余的時(shí)間片。 返回子進(jìn)程的PID,這個(gè)PID最終由用戶態(tài)下的父進(jìn)程讀取 線程獨(dú)立執(zhí)行的一個(gè)函數(shù) Linux把線程和進(jìn)程一視同仁,不過線程本身擁有的資源少,共享進(jìn)程的資源,如地址空間。Linux內(nèi)核線程 在內(nèi)核態(tài)下創(chuàng)建、獨(dú)立執(zhí)行的一個(gè)內(nèi)核函數(shù):int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) pid_t p; p = clone( 0, flags | CLONE_VM ); if ( p ) /* 父*/ return p; else /* 子*/ fn(arg)
48、; exit( ); 內(nèi)核線程周期執(zhí)行的任務(wù)內(nèi)核線程是通過系統(tǒng)調(diào)用clone()來實(shí)現(xiàn)的,使用CLONE_VM標(biāo)志說明內(nèi)核線程與調(diào)用它的進(jìn)程(current)具有相同的進(jìn)程地址空間. 由于調(diào)用進(jìn)程是在內(nèi)核中調(diào)用kernel_thread(),因此當(dāng)系統(tǒng)調(diào)用返回時(shí),子進(jìn)程也處于內(nèi)核態(tài)中,而子進(jìn)程隨后調(diào)用fn,當(dāng)fn退出時(shí),子進(jìn)程調(diào)用exit()退出,所以子進(jìn)程是在內(nèi)核態(tài)運(yùn)行的. 由于內(nèi)核線程是在內(nèi)核態(tài)運(yùn)行的,因此內(nèi)核線程可以訪問內(nèi)核中數(shù)據(jù),調(diào)用內(nèi)核函數(shù). 運(yùn)行過程中不能被搶占等等. 內(nèi)核線程也可以叫內(nèi)核任務(wù),它們周期性地執(zhí)行,例如,磁盤高速緩存的刷新,網(wǎng)絡(luò)連接的維護(hù),頁面的換入換出等等。 幾個(gè)特
49、殊身份的內(nèi)核線程沒事閑逛的0號進(jìn)程從無到有誕生的第一個(gè)線程,執(zhí)行cpu_idle()函數(shù)(省電又少熱)。 既是內(nèi)核線程也是1號用戶進(jìn)程的init。Init進(jìn)程誕生后就不愿意死亡了,它創(chuàng)建和監(jiān)控操作系統(tǒng)外層所有進(jìn)程的活動(dòng)。 還有另外四個(gè)線程:kflushd (即bdflush)線程:刷新“臟”緩沖區(qū)中的內(nèi)容到磁盤以歸還內(nèi)存。Kupdate線程:刷新舊的“臟”緩沖區(qū)中的內(nèi)容到磁盤以減少文件系統(tǒng)不一致的風(fēng)險(xiǎn)。 Kpiod線程:把屬于共享內(nèi)存映射的頁面交換出去。 Kswapd線程:執(zhí)行內(nèi)存回收功能。 進(jìn)程的系統(tǒng)調(diào)用Fork()父親克隆一個(gè)兒子。執(zhí)行fork()之后,兵分兩路,兩個(gè)進(jìn)程并發(fā)執(zhí)行。Exec
50、()新進(jìn)程脫胎換骨,離家獨(dú)立,開始了獨(dú)立工作的職業(yè)生涯。Wait()等待不僅僅是阻塞自己,還準(zhǔn)備對僵死的子進(jìn)程進(jìn)行善后處理。Exit()終止進(jìn)程,把進(jìn)程的狀態(tài)置為“僵死”,并把其所有的子進(jìn)程都托付給init進(jìn)程,最后調(diào)用schedule()函數(shù),選擇一個(gè)新的進(jìn)程運(yùn)行。 進(jìn)程的一生隨著一句fork,一個(gè)新進(jìn)程呱呱落地,但這時(shí)它只是老進(jìn)程的一個(gè)克隆。然后,隨著exec,新進(jìn)程脫胎換骨,離家獨(dú)立,開始了獨(dú)立工作的職業(yè)生涯。人有生老病死,進(jìn)程也一樣,它可以是自然死亡,即運(yùn)行到main函數(shù)的最后一個(gè),從容地離我們而去;也可以是中途退場,退場有2種方式,一種是調(diào)用exit函數(shù),一種是在main函數(shù)內(nèi)使用r
51、eturn,無論哪一種方式,它都可以留下留言,放在返回值里保留下來;甚至它還可能被謀殺,被其它進(jìn)程通過另外一些方式結(jié)束它的生命。進(jìn)程死掉以后,會(huì)留下一個(gè)空殼,wait站好最后一班崗,打掃戰(zhàn)場,使其最終歸于無形。這就是進(jìn)程完整的一生。與調(diào)度相關(guān)的系統(tǒng)調(diào)用系統(tǒng)調(diào)用描述 nice( ) 改變一個(gè)普通進(jìn)程的優(yōu)先級getpriority( ) 取得一組普通進(jìn)程的最大優(yōu)先級setpriority( ) 設(shè)置一組普通進(jìn)程的優(yōu)先級 sched_getscheduler( )取得一個(gè)進(jìn)程的調(diào)度策略sched_setscheduler( ) 設(shè)置一個(gè)進(jìn)程的調(diào)度策略和優(yōu)先級 sched_getparam( ) 取得
52、一個(gè)進(jìn)程的調(diào)度優(yōu)先級 sched_setparam( ) 設(shè)置一個(gè)進(jìn)程的優(yōu)先級 sched_yield( )不阻塞的情況下自愿放棄處理機(jī) sched_get_ priority_min( )取得某種策略的最小優(yōu)先級sched_get_ priority_max( )取得某種策略的最大優(yōu)先級 小節(jié)進(jìn)程是一個(gè)抽象概念,是對程序執(zhí)行過程的抽象 進(jìn)程控制塊是進(jìn)程這一抽象概念在計(jì)算機(jī)中的描述 進(jìn)程的組織采用了樹、鏈表,哈希表,隊(duì)列等。 Linux采用了時(shí)間片輪轉(zhuǎn)的優(yōu)先級調(diào)度方式 進(jìn)程采用“寫時(shí)復(fù)制”技術(shù)創(chuàng)建一個(gè)新進(jìn)程 程序開發(fā)人員可以改變進(jìn)程的優(yōu)先級,甚至調(diào)度策略 進(jìn)程從誕生到死亡涉及四種系統(tǒng)調(diào)用第四章
53、 內(nèi)存管理Linux的內(nèi)存管理 進(jìn)程的用戶空間管理請頁機(jī)制物理內(nèi)存的分配與回收交換機(jī)制內(nèi)存管理示例內(nèi)存的層次結(jié)構(gòu)虛擬內(nèi)存的基本思想:在計(jì)算機(jī)中運(yùn)行的程序,其代碼、數(shù)據(jù)和堆棧的總量可以超過實(shí)際內(nèi)存的大小,操作系統(tǒng)只將當(dāng)前使用的程序塊保留在內(nèi)存中,其余的程序塊則保留在磁盤上。必要時(shí),操作系統(tǒng)負(fù)責(zé)在磁盤和內(nèi)存之間交換程序塊。擴(kuò)大了的記憶虛擬內(nèi)存虛地址到實(shí)地址轉(zhuǎn)換虛擬地址虛擬內(nèi)存、內(nèi)核空間和用戶空間內(nèi)核空間(1GB)進(jìn)程1的用戶空間(3GB)進(jìn)程2的用戶空間(3GB)進(jìn)程n的用戶空間(3GB)虛擬地址空間虛擬內(nèi)存共4G字節(jié),分為內(nèi)核空間(最高的1G字節(jié))和用戶空間(較低的3G字節(jié))兩部分,每個(gè)進(jìn)程最大
54、擁有3G字節(jié)私有虛存空間地址轉(zhuǎn)換通過頁表把虛存空間的一個(gè)地址轉(zhuǎn)換為物理空間中的實(shí)際地址。虛擬內(nèi)存、內(nèi)核空間和用戶空間內(nèi)核空間由所有進(jìn)程共享,其中存放的是內(nèi)核代碼和數(shù)據(jù),即“內(nèi)核映象”進(jìn)程的用戶空間中存放的是用戶程序的代碼和數(shù)據(jù)內(nèi)核空間映射到物理內(nèi)存總是從最低地址(0 x00000000)開始,使之在內(nèi)核空間與物理內(nèi)存之間建立簡單的線性映射關(guān)系。內(nèi)核空間到物理內(nèi)存的映射03G4G0X虛擬地址空間 物理內(nèi)存圖4.1 內(nèi)核的虛擬地址空間到物理地址空間的映射 內(nèi)核空間到物理內(nèi)存的映射Linux虛擬內(nèi)存的實(shí)現(xiàn)需要多種機(jī)制的支持地址映射機(jī)制請頁機(jī)制內(nèi)存分配和回收機(jī)制交換機(jī)制緩存和刷新機(jī)制虛擬內(nèi)存實(shí)現(xiàn)機(jī)制地
55、址映射圖4.2 虛擬內(nèi)存實(shí)現(xiàn)機(jī)制及之間的關(guān)系虛擬內(nèi)存實(shí)現(xiàn)機(jī)制及之間的關(guān)系每個(gè)進(jìn)程經(jīng)編譯、鏈接后形成的二進(jìn)制映像文件有一個(gè)代碼段和數(shù)據(jù)段 進(jìn)程運(yùn)行時(shí)須有獨(dú)占的堆棧空間進(jìn)程的用戶空間管理堆棧段空洞數(shù)據(jù)段代碼段進(jìn)程的用戶空間(3G) Linux把進(jìn)程的用戶空間劃分為一個(gè)個(gè)區(qū)間,便于管理一個(gè)進(jìn)程的用戶地址空間主要由mm_struct結(jié)構(gòu)和vm_area_structs結(jié)構(gòu)來描述。mm_struct結(jié)構(gòu)它對進(jìn)程整個(gè)用戶空間進(jìn)行描述vm_area_structs結(jié)構(gòu)對用戶空間中各個(gè)區(qū)間(簡稱虛存區(qū))進(jìn)行描述 進(jìn)程用戶空間 struct mm_struct atomic_t count; pgd_t * p
56、gd; int map_count; struct semaphore mmap_sem; unsigned long start_code,end_code,start_data,end_data; unsigned long start_brk, brk, start_stack; unsigned long arg_start, arg_end, env_start, env_end; unsigned long rss, total_vm, locked_vm; unsigned long def_flags; struct vm_area_struct *mmap, *mmap_av
57、l, *mmap_cache; unsigned long swap_cnt; unsigned long swap_address; ; mm_struct 結(jié)構(gòu) 域名說 明count對mm_struct結(jié)構(gòu)的引用進(jìn)行計(jì)數(shù)。為了在Linux中實(shí)現(xiàn)線程,內(nèi)核調(diào)用clone派生一個(gè)線程,線程和調(diào)用進(jìn)程共享用戶空間,即mm_struct結(jié)構(gòu),派生后系統(tǒng)會(huì)累加mm_struct中的引用計(jì)數(shù)。pgd進(jìn)程的頁目錄基地址,當(dāng)調(diào)度程序調(diào)度一個(gè)進(jìn)程運(yùn)行時(shí),就將這個(gè)地址轉(zhuǎn)成物理地址,并寫入控制寄存器(CR3)map_count在進(jìn)程的整個(gè)用戶空間中虛存區(qū)的個(gè)數(shù)semaphore對mm_struct結(jié)構(gòu)進(jìn)行串行訪
58、問所使用的信號量Start_code,end_code, start_data, end_data進(jìn)程的代碼段和數(shù)據(jù)段的起始地址和終止地址start_brk, brk, start_stack;每個(gè)進(jìn)程都有一個(gè)特殊的地址區(qū)間,這個(gè)區(qū)間就是所謂的堆,也就是圖4.4中的空洞。前兩個(gè)域分別描述堆的起始地址和終止的地址,最后一個(gè)域描述堆棧段的起始地址。arg_start, arg_end, env_start, env_end命令行參數(shù)所在的堆棧部分的起始地址和終止地址;環(huán)境串所在的堆棧部分的起始地址和終止地址rss, total_vm, locked_vm進(jìn)程貯留在物理內(nèi)存中的頁面數(shù),進(jìn)程所需的總頁
59、數(shù),被鎖定在物理內(nèi)存中的頁數(shù)。mmapvm_area_struct虛存區(qū)結(jié)構(gòu)形成一個(gè)單鏈表,其基址由小到大排列mmap_avlvm_area_struct虛存區(qū)結(jié)構(gòu)形成一個(gè)顆AVL平衡樹mmap_cache最近一次用到的虛存區(qū)很可能下一次還要用到,因此,把最近用到的虛存區(qū)結(jié)構(gòu)放入高速緩存,這個(gè)虛存區(qū)就由mmap_cache指向。struct vm_area_struct struct mm_struct * vm_mm; unsigned long vm_start; unsigned long vm_end; pgprot_t vm_page_prot; unsigned short vm_
60、flags; struct vm_area_struct *vm_next; short vm_avl_height; struct vm_area_struct *vm_avl_left, *vm_avl_right; struct vm_operations_struct * vm_ops;struct vm_area_struct *vm_next_share, *vm_pprev_share; unsigned long vm_offset; struct file * vm_file; unsigned long vm_pte; ; VM_AREA_STRUCT 結(jié)構(gòu) 域名說 明Vm
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年電商平臺運(yùn)營管理服務(wù)協(xié)議版B版
- 個(gè)人門窗安裝合同范本(2024版)
- 二手房中介勞動(dòng)合同模板(2024版)
- 二零二五版綠色建材認(rèn)證及采購合同3篇
- 二零二五年度蔬菜產(chǎn)業(yè)數(shù)據(jù)共享協(xié)議2篇
- 2025年度航空客運(yùn)服務(wù)采購與質(zhì)量管理體系合同3篇
- 二零二五版LNG現(xiàn)貨交易與風(fēng)險(xiǎn)管理合同2篇
- 2025年度鋅錠生產(chǎn)技術(shù)改造升級合作協(xié)議3篇
- 2024版居間銷售合同
- 二零二五年度住宅小區(qū)公共收益管理服務(wù)協(xié)議
- TSGD7002-2023-壓力管道元件型式試驗(yàn)規(guī)則
- 2024年度家庭醫(yī)生簽約服務(wù)培訓(xùn)課件
- 建筑工地節(jié)前停工安全檢查表
- 了不起的狐貍爸爸-全文打印
- 糖尿病酮癥酸中毒病例討論-文檔資料
- 液相色譜質(zhì)譜質(zhì)譜儀LCMSMSSYSTEM
- 民辦非企業(yè)單位章程核準(zhǔn)表-空白表格
- 派克與永華互換表
- 第二章流體靜力學(xué)基礎(chǔ)
- 小學(xué)高年級語文作文情景互動(dòng)教學(xué)策略探究教研課題論文開題中期結(jié)題報(bào)告教學(xué)反思經(jīng)驗(yàn)交流
- 春節(jié)新年紅燈籠中國風(fēng)信紙
評論
0/150
提交評論