xv6操作系統(tǒng)整體報告_第1頁
xv6操作系統(tǒng)整體報告_第2頁
xv6操作系統(tǒng)整體報告_第3頁
xv6操作系統(tǒng)整體報告_第4頁
xv6操作系統(tǒng)整體報告_第5頁
已閱讀5頁,還剩31頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、前言操作系統(tǒng)是一種復(fù)雜的系統(tǒng)軟件。本書通過介紹操作系統(tǒng)的基本概念和原理.并結(jié)合操作系統(tǒng)原理來分析一個小型但全面的操作系統(tǒng)xv6.并進一步進行各種基于xv6操作系統(tǒng)的實驗.來讓讀者了解和掌握操作系統(tǒng)的設(shè)計與實現(xiàn)。xv6是一個運行在基于x86架構(gòu)的計算機系統(tǒng)上的類似UNIX的教學用操作系統(tǒng)。xv6起源于MIT。在2002年秋季.FransKaashoek,JoshCates,andEmilSit在MIT開設(shè)了一門新的實驗型課程“操作系統(tǒng)工程”.英文名稱是“OperatingSystemsEngineering.課程代號是“6.097.后改為“6.828.在此課程上.一開始采用了“萊昂氏UNIX源代

2、碼分析”(英文書名是“LionCornmentaryonUNIX6thEditionWithSourceCode)作為參考資料。此參考資料描述的UNIXv6(簡稱V6)是運行在古老的PDP-11計算機系統(tǒng)上。為了讓學生更好地理解V6的實現(xiàn).FransKaashoek等從2006年夏季開始參考V6的架構(gòu)在x86計算機系統(tǒng)上重新實現(xiàn)了一個支持多處理器計算機系統(tǒng)的類似UNIX的教學用操作系統(tǒng).稱為為xv6。在目前的MIT本科生課程“6.828:OperatingSystemsEngineering中.xv6主要用于講課.而另一個基于exokernel架構(gòu)的JOS主要用于做試驗。目前xv6在MIT的網(wǎng)

3、址在 HYPERLINK /6.828/xv6/ /6.828/xv6/第零章安裝使用如果是Linux初學者.請看附錄F.了解如何安裝、使用UbuntuLinux.如何在UbuntuLinux下編程。編譯needupdate安裝UbuntuLinux8.10.具體安裝方法可以參考附錄C。并通過apt工具進一步安裝相關(guān)軟件包$sudoapt-getinstallgccbinutilslibc6-devgdb然后解壓xv6軟件包.到某一目錄.然后到此目錄下執(zhí)行$make就可以生成相關(guān)執(zhí)行文件和鏡像.包括xv6.img(包含bootloader和xv6kernel)和fs.img(包含應(yīng)用程序)運行

4、needupdate安裝UbuntuLinux8.10.并通過apt工具進一步安裝相關(guān)軟件包$sudoapt-getinstallqemubochsbiosvgabioslibsdl1.2debiankvm如果通過qemu執(zhí)行.可執(zhí)行如下命令qemu-smp4-parallelstdio-hdbfs.img-hdaxv6.img如果通過kvm執(zhí)行.可執(zhí)行如下命令kvm-smp4-parallelstdio-hdbfs.imgxv6.imgqemu和kvm的相關(guān)運行參數(shù)的含義可參考附錄B。調(diào)試needupdate對qemu而言.可以同時實現(xiàn)qemu內(nèi)嵌的debugger調(diào)試(需要打陳渝老師擴展的

5、patch并重新編譯生成新的qemu.特點是簡單.可控制硬件的手段多缺點是不是C源碼級調(diào)試)和通過gdb遠程調(diào)試(特點是是可進行C源碼級調(diào)試缺點是可能會有奇怪的問題對硬件控制不夠)。1用gdb遠程調(diào)試的方法如下:aqemu調(diào)試方式啟動qemu-S-s-smp2-monitorstdio-hdbfs.img-hdaxv6.imgbgdb啟動并調(diào)試gdbkernel(gdb)targetremote:1234(gdb)breakFUNCTION-NAME(gdb)continue(gdb)quit2用qemuinternaldebugger調(diào)試aqemu啟動命令qemu-smp2-monitors

6、tdio-hdbfs.img-hdaxv6.img然后在qemu的monitor中可執(zhí)行如下命令進行調(diào)試分析x/fmtaddr一virtualmemorydumpstartingataddrinfocpus一showinfosforeachCPUinforegisters一showthecpuregisterssinglestepsinglestap_enabledtogglesinglestepmodebreakpoint_insertaddr一insertbreakpointbreakpoint_removeaddr一removebreakpointbreakpoint_show一show

7、breakpointwatchpoint_insertaddrtype一insertwatchpointtype0=read1=writewatchpoint_removeaddr一removewatchpointwatchpoint_showshowwatchpointwhere一showcallsstack第一章總體結(jié)構(gòu)和系統(tǒng)組成本章將給出xv6啟動實現(xiàn)的概貌。讀者將學習以下一些內(nèi)容:操作系統(tǒng)是什么?xv6是如何產(chǎn)生的?xv6的總體結(jié)構(gòu)是什么?xv6包含哪些重要的組成部分?操作系統(tǒng)是一種軟件操作系統(tǒng)沒有一個精確和統(tǒng)一的定義。操作系統(tǒng)是一種比較復(fù)雜的軟件我們可以從多種角度來了解操作系統(tǒng)。從操

8、作系統(tǒng)的任務(wù)來看.操作系統(tǒng)的任務(wù)主要是控制和管理計算機系統(tǒng)中的硬件資源并對應(yīng)用軟件和用戶提供各種方便使用計算機的功能。通過操作系統(tǒng).能有效地組織和管理計算機系統(tǒng)中的硬件資源和其他軟件資源向用戶和應(yīng)用軟件提供各種服務(wù)功能使得用戶和應(yīng)用軟件能夠靈活、方便、有效地使用計算機并使整個計算機系統(tǒng)能高效地運行。從操作系統(tǒng)在計算機系統(tǒng)中的實現(xiàn)層次上看操作系統(tǒng)位于計算機硬件之上.應(yīng)用軟件之下。由于操作系統(tǒng)是一個復(fù)雜的軟件系統(tǒng).為了能夠更好地設(shè)計和實現(xiàn)操作系統(tǒng)我們可以從功能上對操作系統(tǒng)進行分解可把操作系統(tǒng)分解為系統(tǒng)調(diào)用、進程調(diào)度、內(nèi)存管理、中斷處理、文件系統(tǒng)和設(shè)備管理等功能模塊在具體實現(xiàn)上可采用模塊化、層次化和

9、面向?qū)ο蟮仍O(shè)計方法來設(shè)計實現(xiàn)操作系統(tǒng)。一個OS組成結(jié)構(gòu)圖needtoupdate。要了解xv6.首先我們需要了解操作系統(tǒng)的一些基本概念(請參考附錄A)。xv6(基于xv6-rev2版本)是一個支持對稱多處理器(SMP)的類Unix系統(tǒng)。它包含操作系統(tǒng)一些最基本的要素包括系統(tǒng)調(diào)用、進程調(diào)度、內(nèi)存管理、中斷處理和文件系統(tǒng)等。xv6總體設(shè)計思路xv6基于典型的UNIX操作系統(tǒng)設(shè)計思路。簡單地說.xv6是一種能區(qū)分內(nèi)核態(tài)和用戶態(tài)基于扁平內(nèi)存管理的層次型單體內(nèi)核應(yīng)用程序和操作系統(tǒng)是處于不同的特權(quán)狀態(tài)和地址空間。代表應(yīng)用程序的用戶態(tài)進程運行在CPU的用戶態(tài)(又稱非特權(quán)模式用戶模式)無法直接訪問系統(tǒng)硬件和操

10、作系統(tǒng)中的系統(tǒng)數(shù)據(jù).而操作系統(tǒng)運行在CPU的核心態(tài)(又稱特權(quán)模式.內(nèi)核模式)可以訪問系統(tǒng)硬件和核心數(shù)據(jù)。下面分別從系統(tǒng)調(diào)用接口、進程/線程管理、內(nèi)存管理、文件系統(tǒng)、I/O管理等幾個方面進行總體分析。系統(tǒng)調(diào)用是應(yīng)用程序訪問操作系統(tǒng)的接口。在系統(tǒng)調(diào)用接口上通用操作系統(tǒng)與基于此操作系統(tǒng)的應(yīng)用程序處于兩個不同的CPU特權(quán)態(tài)操作系統(tǒng)處于核心態(tài)而應(yīng)用程序處于用戶態(tài)。在核心態(tài)可以執(zhí)行CPU特權(quán)指令.而用戶態(tài)無法執(zhí)行特權(quán)指令且只能通過特定的指令或中斷來訪問操作系統(tǒng)提供的各種功能。這在一定程度上保證了系統(tǒng)整體的安全避免應(yīng)用程序?qū)Σ僮飨到y(tǒng)可能的破壞。在內(nèi)存管理方面通用操作系統(tǒng)采用了虛擬內(nèi)存管理方式這樣可以讓內(nèi)存需

11、求超過實際物理內(nèi)存的進程/線程能夠執(zhí)行其主要思想是把重要和常用的數(shù)據(jù)和執(zhí)行代碼放在物理內(nèi)存中.把不常用的數(shù)據(jù)和執(zhí)行代碼放到二級存儲(這里主要指的是硬盤等可在掉電后保存數(shù)據(jù)的存儲介質(zhì))隨時根據(jù)系統(tǒng)執(zhí)行情況替換放在內(nèi)存中的數(shù)據(jù)和代碼。而且通過虛存管理可以實現(xiàn)對不同內(nèi)存區(qū)域的保護不同進程之間.或者應(yīng)用程序和操作系統(tǒng)之間的地址空間相對隔離。這樣一般情況下不同進程的地址空間不能直接訪問且應(yīng)用程序不能直接訪問內(nèi)核地址空間。所以一個與錯誤的應(yīng)用程序不會導(dǎo)致系統(tǒng)的崩潰.從而增加了系統(tǒng)的可靠性。xv6操作系統(tǒng)沒有采用虛擬內(nèi)存管理.而是采用了簡單的基于X86段模式的單一地址空間管理方式。在內(nèi)存分配和釋放的管理上.

12、xv6相對實現(xiàn)得比較簡單.采用基于可變分區(qū)分配的首次適配算法.容易產(chǎn)生內(nèi)存碎片。在進程/線程管理方面.當前通用操作系統(tǒng)結(jié)合虛存管理采用進程和線程結(jié)合的管理方式。進程代表了一個程序執(zhí)行的過程以及其所占用的計算機資源(包括CPU、內(nèi)存、文件等)進程的執(zhí)行流可用線程來表示。操作系統(tǒng)的調(diào)度單位可以是進程或線程。一個進程可以包含多個線程.屬于同一進程的多個線程共享進程管理的資源.比如屬于同一進程的多個線程共享進程所管理的內(nèi)存這樣這些線程可以直接訪問屬于進程的全局地址空間。xv6操作系統(tǒng)實現(xiàn)了一個基于進程(沒有實現(xiàn)線程)的簡單進程管理機制。在文件系統(tǒng)管理方面.當前通用操作系統(tǒng)結(jié)合虛存管理實現(xiàn)了多種復(fù)雜、高

13、效且可靠的文件系統(tǒng)且建立了一個統(tǒng)一的虛擬文件系統(tǒng)層.屏蔽不同文件系統(tǒng)的差異對上層提供統(tǒng)一的接口。且與用戶管理和進程管理結(jié)合可實現(xiàn)安全管理保證對文件的安全訪問。xv6操作系統(tǒng)實現(xiàn)了一個相對簡單的基于inode索引方式的文件系統(tǒng)。在1/O管理方面.xv6操作系統(tǒng)與通用操作系統(tǒng)(特別是類UNIX操作系統(tǒng))差別不是特別大都把設(shè)備“看成”是一種特殊的設(shè)備文件有設(shè)備號.用文件的訪問接口來進行打開、關(guān)閉、讀、寫和控制等操作。在靈活性方面.xv6驅(qū)動程序不能象通用操作系統(tǒng)那樣根據(jù)硬件情況動態(tài)加載.而是在編譯時候就靜態(tài)確定的。xv6總體架構(gòu)從操作系統(tǒng)模型上來看.xv6是一個單地址空間的層次式單體內(nèi)核不是微內(nèi)核(

14、microkernel)模型的操作系統(tǒng)(如Mach.QNX).與通用操作系統(tǒng)(如Linux)的架構(gòu)在地址空間和特權(quán)模式上也有一定的差別。下面主要分進程調(diào)度、內(nèi)存管理、同步互斥、文件系統(tǒng)幾方面對xv6進行介紹。同步互斥由于在SMP架構(gòu)中.內(nèi)存磁盤等硬件資源在所有CPU中都是共享的所以在需要某種機制對資源進行互斥訪問控制。在xv6中通過實現(xiàn)了spinlock從而可以對共享資源加鎖來限制同時訪問此資源的CPU數(shù)量。內(nèi)存管理在內(nèi)存管理方面,xv6采用了段式虛擬內(nèi)存的管理方式。每個用戶進程所占用的內(nèi)存都是在一個連續(xù)的段中。用戶進程內(nèi)存的分布為:代碼段、靜態(tài)變量段、固定大小的棧和可變大小的堆空間。由于進程

15、內(nèi)存是按照段管理的.因此在每次分配進程內(nèi)存時.xv6將找一片正好能放下整段的連續(xù)內(nèi)存塊進行放置。進程管理因為是基于SMP架構(gòu)操作系統(tǒng)中的多個進程會占用計算機系統(tǒng)中的多個CPU執(zhí)行其具體功能.由于進程數(shù)量大于CPU數(shù)量.這就涉及到進程如何分時共享CPU的操作系統(tǒng)管理問題.具體包括如果創(chuàng)建進程、如何刪除進程、選擇哪個進程占用哪個CPU.何時進行進程切換進程能夠持續(xù)占用CPU的時間片段的大小設(shè)定等。在xv6中首先其進程是基于時間片來調(diào)度的。每次進程的調(diào)度是由時鐘中斷產(chǎn)生的或者是因當前進程主動放棄。其次每個CPU之間都共享一個進程池(具體實現(xiàn)為一個全局數(shù)組)其中有所有待運行的進程。在每個時間片中.CP

16、U將當前運行的進程放回進程池然后從進程池中選取另一個待運行的進程進行執(zhí)行。文件系統(tǒng)xv6中提供了一個簡單的文件系統(tǒng)這個文件系統(tǒng)提供了大多數(shù)POSIX標準的接口。由于這個文件系統(tǒng)比較簡單.其中一個文件最多由(12+128)個組成.所以文件的大小也被限制在(12+128)*512Bytes。在這個文件系統(tǒng)中提供了一個Buf層.用來緩存磁盤上的數(shù)據(jù)。但是此文件系統(tǒng)是寫直達的.因此每次更新都會直接寫到磁盤上。中斷管理和系統(tǒng)調(diào)用管理NTU外設(shè)管理NTU第二章啟動流程(boot)仁概述本章將給出xv6啟動實現(xiàn)的概貌。讀者將學習以下一些內(nèi)容:bootloader是什么?bootloader做了哪些事情?xv

17、6是如何被加載并啟動的?xv6的初始內(nèi)存管理是如何實現(xiàn)的?xv6的初始中斷管理是如何實現(xiàn)的?xv6如何實現(xiàn)內(nèi)核態(tài)到用戶態(tài)的轉(zhuǎn)變的?xv6啟動用戶態(tài)進程前需要完成哪些事情?xv6如何創(chuàng)建并啟動第一個用戶態(tài)進程?當計算機加電后.一般不直接執(zhí)行操作系統(tǒng).而是執(zhí)行引導(dǎo)加載程序。簡單地說.引導(dǎo)加載程序就是在操作系統(tǒng)內(nèi)核運行之前運行的一段小程序。通過這段小程序.我們可以初始化硬件設(shè)備、建立系統(tǒng)的內(nèi)存空間映射圖從而將系統(tǒng)的軟硬件環(huán)境帶到一個合適的狀態(tài).以便為最終調(diào)用操作系統(tǒng)內(nèi)核準備好正確的環(huán)境。最終引導(dǎo)加載程序把操作系統(tǒng)內(nèi)核映像加載到RAM中.并將系統(tǒng)控制權(quán)傳遞給它。對于絕大多數(shù)計算機系統(tǒng)而言操作系統(tǒng)和應(yīng)用

18、軟件是存放在磁盤(硬盤/軟盤)、光盤、EPROM、ROM、Flash等可在掉電后繼續(xù)保存數(shù)據(jù)的存儲介質(zhì)上。計算機啟動后.CPU開始會到一個特定的地址開始執(zhí)行指令這個特定的地址存放了系統(tǒng)軟件(不僅是操作系統(tǒng)還可能是引導(dǎo)加載程序等)。引導(dǎo)加載程序(bootloader)是系統(tǒng)加電后運行的第一段軟件代碼。對于PC386的體系結(jié)構(gòu)而言.PC機中的引導(dǎo)加載程序由BIOS(BasicInputOutputSystem.即基本輸入/輸出系統(tǒng).其本質(zhì)是一個固化在主板Flash/CMOS上的軟件)和位于軟盤/硬盤引導(dǎo)扇區(qū)中的OSBootLoader一起組成。BIOS實際上是被固化在計算機ROM(只讀存儲器)芯片

19、上的一個特殊的軟件為上層軟件提供最底層的、最直接的硬件控制與支持。更形象地說.BIOS就是PC計算機硬件與上層軟件程序之間的一個橋梁負責訪問和控制硬件。以PC386為例.計算機加電后.CPU從物理地址OxFFFFFFFO(由初始化的CS:EIP確定.此時CS和IP的值分別是OxFOOO和OxFFFO)開始執(zhí)行。在OxFFFFFFFO這里只是存放了一條跳轉(zhuǎn)指令.通過跳轉(zhuǎn)指令跳到BIOS例行程序起始點。BIOS做完計算機硬件自檢和初始化后.會選擇一個啟動設(shè)備(例如軟盤、硬盤、光盤等)并且讀取該設(shè)備的第一扇區(qū)(即啟動扇區(qū))到內(nèi)存一個特定的地址Ox7cOO處.然后CPU控制權(quán)會轉(zhuǎn)移到那個地址繼續(xù)執(zhí)行。

20、至此BIOS的初始化工作做完了.進一步的工作交給了xv6。整個xv6系統(tǒng)的啟動流程大致是這樣的:做為多處理系統(tǒng)啟動是首先從一個CPU的啟動進行的。第一個CPU的啟動過程與其他在單核上啟動操作系統(tǒng)的過程是十分類似的。首先BIOS將把OS的BootLoader從磁盤上(一般是位于第一個扇區(qū))拷貝到內(nèi)存當中。當BIOS將基本的初始化程序完成后.將跳轉(zhuǎn)到BootLoader所在內(nèi)存的位置繼續(xù)執(zhí)行。BootLoader將把OS的內(nèi)核從磁盤上拷貝到然后運行。這樣第一個CPU就完成了啟動。那么第一個CPU將把啟動代碼拷貝到內(nèi)存中.然后喚起其他CPU執(zhí)行這一段代碼.完成它們的初始化過程。在xv6的源碼中整個啟

21、動過程主要牽涉到如下幾個文件:bootloaderobootasm.Sobootmain.cxv6初始化模塊omain.cobootother.S下面將針對這些文件進行分析.對啟動過程分成兩部分進行介紹。2代碼分析bootloader代碼分析bootloader的組成在makefile中50行56行有如下語句50:bootblock:bootasm.Sbootmain.c51:$(CC)$(CFLAGS)-0-nostdincT.-cbootmain.c52:$(CC)$(CFLAGS)-nostdincT.-cbootasm.S53:$(LD)$(LDFLAGS)-N-estart-Ttex

22、t0 x7C00-obootblock.obootasm.obootmain.o54:$(0BJDUMP)-Sbootblock.obootblock.asm55:$(0BJC0PY)-S-Obinarybootblock.obootblock56:. HYPERLINK /sign.plbootblock從中可以看出bootloader包含兩個文件.bootasm.S和bootmain.c。生成的bootloader會寫到一個主引導(dǎo)扇區(qū)上面。作為主引導(dǎo)扇區(qū)其位置在軟盤或硬盤的第一個扇區(qū)其大小為512個字節(jié).在此扇區(qū)的最后兩個字節(jié)是一個主引導(dǎo)扇區(qū)特征碼為”55AA”。Makefile的51行和

23、52行是通過gcc把bootmain.c和bootasm.S編譯成目標文件bootmain.o和bootasm.o。Makefile的53行是通過ld程序把目標文件bootmain.o和bootasm.o鏈接成目標文件bootblock.o.且定義了起始執(zhí)行的點(也稱入口點)為start函數(shù).具體的代碼段起始地址為0 x7C00。Q大家還記得0 x7C00這個特殊的地址的含義嗎?Makefile的54行是通過objdump程序把bootblock.o反匯編成bootlock.asm。Makefile的55行是通過objcopy程序把bootblock.o變成二進制碼bootlock。Qboot

24、lock的大小可以大于512字節(jié)嗎?Makefile的56行是通過sign.pl程序把bootlock擴展到512個字節(jié).并把最后兩個字節(jié)寫成”55AA”。小實驗把最后的xv6.img的前512個字節(jié)取出來.反匯編它的內(nèi)容.并與bootasm.S和bootmain.c的內(nèi)容(可以用bootblock.asm)進行比較,觀察前512個字節(jié)的最后兩個字節(jié)的內(nèi)容是否是“55AA”代碼分析bootloader的啟動主要涉及到bootasm.S、bootmain.c。其中bootasm.S的主要作用是從實模式轉(zhuǎn)化到保護模式。bootmain的作用是把內(nèi)核從磁盤拷貝到內(nèi)存中。bootasm.S在進入實模式

25、向保護模式切換之前首先需要把中斷關(guān)閉(cliatline15).保證轉(zhuǎn)換過程不被硬件中斷打斷。在1922行中將DS,ES,SS進行清零。在2042行(打開A20地址線)歷史在8086年代.8086提供了20跟地址線,那么提供的可尋址空間范圍即02八20(00000HFFFFFH)的1M空間.而由于8086的數(shù)據(jù)處理位寬位16位,所以8086提供了段地址加偏移地址的地址轉(zhuǎn)換機制.就是我們常見的”段地址:偏移地址(或有效地址)”,實際的計算方法為:”段地址*10H+偏移地址”作為段地址的數(shù)據(jù)是放在段寄存器中的(16位).而座位偏移地址的數(shù)據(jù)則是通過8086提供的尋址方式來計算而來的(16位)。而“

26、段值:偏移”這種表示法能夠表示的最大內(nèi)存為10FFEEh(FFFF0+FFFF).所以當尋址到超過1MB的內(nèi)存時.會發(fā)生“回卷”(不會發(fā)生異常)。但是到了80286提供了24根地址線,cpu的尋址范圍變?yōu)?八24=16M,同時也提供了保護模式.真的可以訪問到1MB以上的內(nèi)存了.此時如果遇到“尋址超過1MB”的情況.系統(tǒng)不會再回卷”了這就造成了向上不兼容。為了保持完全的兼容性.IBM決定在PCAT系統(tǒng)上加個邏輯.來模仿以上的回繞特征。他們的方法就是把A20和鍵盤控制器的一個輸出進行AND.這樣來控制A20的打開和關(guān)閉。一開始時A20是被屏蔽的(總為0).直到系統(tǒng)軟件去打開它。注意A20而非A20

27、A31被控制所以在A20關(guān)閉時會發(fā)生一些有趣的副作用。就是在訪問奇數(shù)M地址空間的時候.實際的地址會減少1M。例如訪問1M2M-d1時實際訪問的是01M-1;訪問3M4M-1時為2M3M-1.等等。當A20Gate禁止時.則程序就像在8086中運行.100000h100FFEFh的地是不可訪問的。在保護模式下A20Gate是要打開的。為了使能所有地址位的尋址能力,必須向鍵盤控制器8042發(fā)送一個命令。鍵盤控制器8042將會將它的的某個輸出引腳的輸出置高電平,作為A20門的輸入。一旦設(shè)置成功之后,內(nèi)存將不會再被繞回(memorywrapping),這樣我們就可以尋址整個286的16M內(nèi)存,或者是尋

28、址80386級別機器的所有4G內(nèi)存了。8042鍵盤控制器的10端口是0 x600 x6f.實際上IBMPC/AT使用的只有0 x60和0 x64兩個端口(0 x61、0 x62和0 x63用于與XT兼容目的)。8042通過這些端口給鍵盤控制器或鍵盤發(fā)送命令或讀取狀態(tài)。輸出端口P2用于特定目的。位0(P20引腳)用于實現(xiàn)CPU復(fù)位操作位1(P21引腳)用戶控制A20信號線的開啟與否。系統(tǒng)向輸入緩沖(端口0 x64)寫入一個字節(jié)即發(fā)送一個鍵盤控制器命令??梢詭б粋€參數(shù)。參數(shù)是通過0 x60端口發(fā)送的。命令的返回值也從端、-r匸r皓九逹沖給空未用:4荒誥敦劃甑向)薑堆旦低AJO丄吿,詢地址.琢寫控剖

29、j也14P:Ph52P2C-11】曲叫2KC4垂攢訊F盤二恵示褂黑邂J謹盤佟宦輸岀歸口理ftAM口應(yīng)盤t卍衛(wèi):加陰潮1:履沖圖Intel8042芯片或其兼容芯片的邏輯示意圖口0 x60去讀。2831行.等待I/O端口0 x64空閑.讀1/0端口0 x64.如果返回值的第1位(最低位為第0位)的值不為0.表示端口0 x64為busy.需要再次重復(fù)測試直到第1位為0為止。3334行.把0 xd1寫入I/0端口0 x64;0 xd1命令是寫輸出端口.bit0是復(fù)位,bit1是GateA20.3639行.等待I/0端口0 x64空閑.即讀I/O端口0 x64.如果返回值的第1位(最低位為第0位)的值不

30、為0.表示端口0 x64為busy.需要再次重復(fù)測試直到第1位為0為止。4142行.把0 xdf寫入I/0端口0 x60;0 xdf命令是使能A20至此.A20地址線已經(jīng)使能。在第48行.lgdtgdtdesc將新的全局段描述符表進行加載。注意到gdtdesc中給出了新段表有效大小和所在地址(gdt)。在gdt中給出了三個段的描述.第0段默認是空段.第1段是代碼段第2段是數(shù)據(jù)段。由于現(xiàn)在只是做模式切換之用因此第1、2段的范圍都是0 x00 xffffffff。在第4951行中通過將CR0的第0位置1.把保護模式設(shè)置為打開。但此時段模式并沒有真正運行。只有當執(zhí)行完55行的Ijmp后段模式才真正的

31、啟動。此時cs變成$PROT_MODE_CSEG所指向的段(即83=1,為gdt的第1段即代碼段)。在完成Ijmp后機器進入32位模式。在5965行在將其他段寄存器置成數(shù)據(jù)段即gdt中的第2段.即數(shù)據(jù)段。在第68行.將棧頂指針指向$start坐在位置即(0 x7c00)。然后在第69調(diào)用bootmain過程.進行內(nèi)核的加載。bootmain.c在這個文件中主要有四個函數(shù):bootmain、waitdisk、readsect和readseg。其中bootmain是加載內(nèi)核.其余三個都是對磁盤進行訪問的程序。首先來看一下waitdisk、readsect和readseg。readseg函數(shù)的作用是

32、從磁盤的offset處開始讀取count個字符到va處。在讀取數(shù)據(jù)時是通過調(diào)用readsect以扇區(qū)為單位進行的。因此在88行保證va是從一個扇區(qū)起始位置開始.因此要對va進行對齊。readsect是對磁盤進行讀取在讀取之前每次調(diào)用waitdisk等待磁盤的準備過程一旦磁盤準備好后就可以進行讀取了。然后看一下bootmain過程。bootmain的目的是從磁盤中加載內(nèi)核到內(nèi)存中.其中內(nèi)核是以ELF執(zhí)行文件格式存在磁盤上的。首先將從磁盤讀取一頁大?。?*512B=4KB)的信息其中包含了ELF執(zhí)行文件格式的頭。從中可以知道讀取鏡像的大小以及存放的位置(見3437行)。當完成拷貝后.bootmai

33、n獲取內(nèi)核入口程序的地址(見4041行).然后進入該入口(即main.c中的main函數(shù))。操作系統(tǒng)初始化模塊代碼分析操作系統(tǒng)的啟動部分包含如下文件main.cbootother.Smain.cmain.c的作用是進行對系統(tǒng)各方面的初始化工作.然后喚起其他CPU的初始化。首先我們看一下main過程。在這個過程將進行一系列的初始化過程。第一步是對BSS段進行初始化(18行)。在20行將調(diào)用函數(shù)mp_init將獲取所有cpu的信息.其中bcpu將指定BOOTSTRAPCPU的編號(即第一個啟動的CPU的編號)。接下2436行是一系列的初始化過程涉及processtablebuffercachePI

34、CinterruptcontrollerIOAPICinterruptcontrollerphysicalmemoryallocatortrapvectorsfiletableinodecacheconsoledevice&interruptIDEdevice&interrupttimer(onlyforuniprocessor)firstuserprocess這些將在后面的文章具體介紹。在初始話內(nèi)存、中斷表、文件系統(tǒng)、I/O設(shè)備等之后第一個CPU將啟動調(diào)用bootothers()去啟動其他的CPU。在調(diào)用函數(shù)bootothers()之前.第一個用戶進程將通過userint()進行初始化。在初

35、始化其他AP后.將進入scheduler。過程。scheduler過程是對單個CPU的進行進程調(diào)度的.這將在以后進行討論。然后.我們看一下bootothers()過程。在這個過程中將對除bootstrapCPU之外每個CPU進行啟動。啟動時這樣進行的.首先把bootother.S的代碼拷貝到0 x7000起始的這塊內(nèi)存里。然后在0 x7000-4、0 x7000-8兩個內(nèi)存單元記錄下bootother.S中將要進行跳轉(zhuǎn)的內(nèi)核棧位置以及mpmain的入口地址。這樣當CPU運行完bootother.S中的代碼之后將進入mpmain過程。在mpmain中.每個CPU將進行中斷表和段表的初始化.然后打

36、開中斷進入scheduler。過程。bootother.Sbootother.S完成啟動其他CPU的啟動工作.根據(jù)Makefile的5862行:58:bootother:bootother.S59:$(CC)$(CFLAGS)-nostdinc-I.-cbootother.S60:$(LD)$(LDFLAGS)-N-estart-Ttext0 x7000-obootother.outbootother.o61:$(OBJCOPY)-S-Obinarybootother.outbootother62:$(OBJDUMP)-Sbootother.obootother.asm可以了解到:Makefi

37、le的59行是通過gcc把bootother.S編譯成目標文件bootother.o。Makefile的60行是通過ld把bootother.o進行地址重定位,設(shè)定其起始入口點為start.起始地址位0 x7000.并生成執(zhí)行文件bootother.out。Makefile的61行是通過objcopy把bootother.out轉(zhuǎn)變成二進制代碼boototheroMakefile的62行是通過objdump把bootother.o反匯編成bootother.asm。bootother.S的執(zhí)行內(nèi)容十分類似之前的bootasm.S。在這個文件中晚啟動的CPU將會進行從實模式到保護模式的轉(zhuǎn)化(42

38、49行)。然后重設(shè)段寄存器(5459行)。完成后.便設(shè)置kernel棧.跳轉(zhuǎn)進入mpmain過程(61-63行)。Q這個棧的內(nèi)容是什么?第三章同步互斥與鎖機制(spinlock)概述本章將給出xv6同步互斥實現(xiàn)的概貌。讀者將學習以下一些內(nèi)容:什么是競爭狀態(tài)?什么是互斥?什么是同步?NUDxv6中的臨界區(qū)代碼是什么?xv6是怎樣處理臨界區(qū)代碼的?當兩個或多個線程在執(zhí)行一些關(guān)鍵性的臨界區(qū)代碼時(如對共享資源的訪問)如何確保它們不會相互妨礙?當線程之間存在著某種依存關(guān)系時如何來調(diào)整它們的運行次序?當線程經(jīng)常需要與其它線程進行通信那么如何根據(jù)需要提供有效的通信手段?這實際上需要操作系統(tǒng)提供同步互斥與通

39、信的手段才能解決上述問題。任何為進程所占用的實體都可稱為資源。資源可以是CPU、內(nèi)存也可以是I/O設(shè)備還可以是一個變量一個結(jié)構(gòu)或一個數(shù)組等。可以被一個以上進程使用的資源叫做共享資源。為了防止數(shù)據(jù)被隨意訪問(特別是執(zhí)行寫操作)每個進程在與共享資源打交道時必須獨占該資源。這叫做互斥(mutualexclusion)o需要互斥訪問的共享資源稱為臨界資源。如果兩個或多個進程對同一共享資源同時進行讀寫操作.而最后的結(jié)果是不可預(yù)測的.該結(jié)果取決于各個進程具體運行情況。則稱此狀態(tài)為競爭狀態(tài)(racecondition)。對共享資源的訪問可能導(dǎo)致競爭狀態(tài)的出現(xiàn)。我們把可能出現(xiàn)競爭態(tài)的程序片斷稱為程序臨界區(qū)。程

40、序臨界區(qū)在處理時不可以被中斷要保證其操作的原子性。為確保臨界區(qū)程序執(zhí)行過程中不被中斷.在進入臨界區(qū)之前要屏蔽中斷.而臨界區(qū)代碼執(zhí)行完以后要立即使能中斷.以減少對中斷處理延遲的影響。Spinlock的引入是為了進行資源的互斥訪問。在SMP架構(gòu)下.每個CPU的權(quán)限都是相同的.但是某些情況下.一個CPU需要對資源進行獨占.此時就可以通過spinlock來進行。spinlock是通過一條CPU原子指令xchg完成的。具體的實現(xiàn)方法如下。代碼分析spinlock.h文件中給出了spinlock結(jié)構(gòu)的定義如下:structspinlockuintlocked;/Isthelockheld?/Fordebu

41、gging:char*name;/Ncpu;/Thenumberofthecpuholdingthelock.uintpcs10;/Thecallstack(anarrayofprogramcounters)/thatlockedthelock.;可以看到.起作用的主要是locked變量.這個用來表示當前鎖是否被鎖上。其他的變量name,cpu和pcs都是其調(diào)試作用的。其中name記錄鎖的用途.cpu記錄了那個cpu取得了這把鎖.pcs記錄了獲得這把鎖時的棧的內(nèi)容。spinlock.cspinlock.c文件中包含了對spinlock的各種操作:初始化、獲取鎖.釋放鎖

42、等。我們依次閱讀文件中的每個過程。初始化鎖initlock過程是對所進行初始化.即初始化name、locked和cpu三個域。cpu被置成Oxffffffff.表示不被任何cpu所有。獲取鎖acquire過程是獲取鎖(變量lock)的過程。在2829行.通過pushcli屏蔽中斷.檢查當前鎖是否已經(jīng)被當前CPU所占有。此時.用cli指令把當前CPU的中斷關(guān)閉(注意其他CPU的中斷并不受到影響而且其他軟中斷也并沒有被關(guān)閉)。在程序35行的while將直到成功獲取鎖為止。在35行通過cmpxchg去獲取鎖。其指令格式為:xchg(va,newvalue)。作用是交換內(nèi)存地址va中的值和newval

43、ue.返回值為內(nèi)存地址va中運行xchg之前的值。因為locked=0表示這把鎖沒有人獲取.此時xchg(va,1)便能返回0.跳出while循環(huán).否則在while循環(huán)中打轉(zhuǎn)。跳出while表示獲得了鎖.42行是記錄獲得鎖的CPUID。43行是調(diào)用函數(shù)getcallerpcs記錄獲得鎖時的函數(shù)調(diào)用棧。釋放鎖release過程十分簡單.首先判斷是否當前CPU拿到這把鎖.如果不是.則報錯;如果是.那么就把鎖進行釋放并清除獲得鎖的CPU記錄和函數(shù)調(diào)用棧。同時如果當前CPU已經(jīng)沒有拿任何鎖.那么通過popcli將中斷打開。第四章內(nèi)存管理1概述本章將給出xv6內(nèi)存管理實現(xiàn)的概貌。讀者將學習以下一些內(nèi)容:

44、xv6如何進行內(nèi)存管理初始化的?xv6的靜態(tài)內(nèi)存分配的空間包括什么?xv6的動態(tài)內(nèi)存分配的空間包括什么?xv6的動態(tài)內(nèi)存分配是如何實現(xiàn)的?如何使用xv6的動態(tài)內(nèi)存分配的空間?內(nèi)存管理機制是實時操作系統(tǒng)的重要組成部分。xv6不支持虛擬存儲管理.不支持復(fù)雜的段頁式的保護機制而采用線性編址方式.即邏輯地址和物理地址對應(yīng)的平面模式。這樣沒有虛擬存儲管理提供的不受限于物理內(nèi)存大小的大地址空間、地址保護等功能。xv6同時支持靜態(tài)內(nèi)存分配和動態(tài)內(nèi)存分配兩種管理方式。靜態(tài)內(nèi)存分配是指在編譯或鏈接時將應(yīng)用所需的內(nèi)存空間分配好。采用這種分配方案的xv6內(nèi)核映像所占內(nèi)存空間(代碼段和數(shù)據(jù)段等)的大小一般在編譯時就能

45、夠確定.中斷向量表等其它區(qū)域所占用的內(nèi)存空間大小是個定值。這樣采用靜態(tài)的內(nèi)存分配機制.在編譯時就可以確定xv6所需內(nèi)存的大小。而動態(tài)內(nèi)存分配是指系統(tǒng)運行時根據(jù)應(yīng)用需要動態(tài)地分配內(nèi)存。動態(tài)內(nèi)存分配的實現(xiàn)機制靈活.給程序?qū)崿F(xiàn)帶來極大的方便有的應(yīng)用環(huán)境中動態(tài)內(nèi)存分配甚至是必不可少的。xv6目前采用的是基于段模式的尋址方式。首先在xv6.img所在內(nèi)存的末尾開始增加一塊1MB的空閑動態(tài)內(nèi)存空間。然后通過一種鏈表的方式來管理這1MB內(nèi)存空間的在xv6中動態(tài)分配和釋放。在初始化完動態(tài)內(nèi)存空間后的內(nèi)存布局如下:2代碼分析kalloc.c動態(tài)內(nèi)存管理初始化內(nèi)存空間初始化工作由函數(shù)kinit完成.執(zhí)行完kini

46、t后.內(nèi)存布局如下所示:內(nèi)核首先會被bootloader加載到xOxIOOOO.然后main初始化總控函數(shù)通過kalloc.c文件中的kinit函數(shù)對內(nèi)存進行初始化。其執(zhí)行流程如下:調(diào)用initlock函數(shù)初始化用于內(nèi)存管理互斥的kalloc_lock(32行)得到代碼段數(shù)據(jù)段之后的最后地址指針end.并把它賦值給start指針變量.并把start指針頁對齊.把start指針指向的地址作為xv6所管理的空閑區(qū)域的起始地址(3334行)3設(shè)置可使用的內(nèi)存空間為256個4K大小的頁并調(diào)用kfree函數(shù)對start指針指向的地址為首地址.大小為256*4大1O24個字節(jié)的空間進行空閑設(shè)置處理。(35

47、37行)動態(tài)內(nèi)存分配與釋放kalloc.c中是對內(nèi)存空間進行管理.kfree是回收一段內(nèi)存.而kalloc是分配一段內(nèi)存。xv6的內(nèi)存管理是十分簡單的。由于內(nèi)存分配是以連續(xù)的段的方式進行的通過單鏈表方式鏈接空閑的段。因此經(jīng)過一定時間的分配空閑空間將由一個個地址不連續(xù)的段組成。xv6用freelist將其按起始地址從左至右排列串起來。每次回收時.將回收的段加入段序列中。如果發(fā)現(xiàn)新加入段之后能夠合并則將其合并成一個段。當進行分配時.則遍歷整個鏈表直到找到一個比需求大的段.則將相應(yīng)的段分配出去。初始化后第一次分配第五章進程管理與調(diào)度概述本章將給出xv6進程管理實現(xiàn)的概貌。讀者將學習以下一些內(nèi)容:什么

48、是進程?xv6的進程管理數(shù)據(jù)結(jié)構(gòu)(進程控制塊.PCB)包含哪些內(nèi)容?xv6是如何組織進程管理數(shù)據(jù)結(jié)構(gòu)?xv6如何進行進程管理初始化的?xv6怎樣啟動多進程的(即需要做哪些初始化工作)?xv6何時進行進程調(diào)度?xv6是如何調(diào)度進程的(如何選擇進程占用CPU運行)?xv6是如何完成進程切換的?xv6如何啟動并執(zhí)行用戶態(tài)的進程的?進程的概念程序與進程的概念是不可分的。當用戶在計算機上運行一個程序時此程序?qū)?yīng)的進程就誕生了并實際完成各種程序提供的功能.而用戶關(guān)閉一個程序時進程也隨之終止。程序是為了完成某項任務(wù)編排的語句序列.它要告訴計算機如何執(zhí)行.因此程序是需要通過CPU來運行的.且在程序的運行過程中

49、需要占有計算機的各種資源(比如內(nèi)存等)才能運行下去。如果計算機系統(tǒng)在任一時刻限制只有一個程序在運行則程序在整個運行過程中獨占計算機中的全部資源.這樣整個程序運行和管理就簡單了。就象在一個家中只住了一個人A.他想看書就到書房去看書.想睡覺就到睡房的床上去睡覺.想看電視就到電視廳看電視.想吃飯就去餐廳吃飯.沒人和他搶占資源。但為了提高計算機系統(tǒng)的資源利用率需要支持多個程序并發(fā)執(zhí)行。這就會帶來許多新的問題如資源的共享與競爭.同步與互斥等。比如此人與B成家并有了小孩C.那就是三口之家同時住一套房.當A想去看足球比賽直播電視節(jié)目的時候如果發(fā)現(xiàn)電視廳已經(jīng)有B在坐著看連續(xù)劇電視節(jié)目了.A就得等待或干別的事情

50、。除非A在買一個電視并在另外一個房間看他的球比賽直播。由于程序是靜態(tài)的我們看到的程序是存儲在存儲介質(zhì)(如硬盤、光盤等)上的它無法反映出程序執(zhí)行過程中的動態(tài)特性.而且程序在執(zhí)行過程中會不斷申請資源或釋放資源這樣讓程序作為共享資源的基本單位是不合適的.所以需要引入一個概念.它能描述程序的執(zhí)行過程而且可以作為共享資源的基本單位.這個概念就是進程。簡單地說.一個進程是一個具有一定獨立功能的程序在一個數(shù)據(jù)集合上的一次動態(tài)執(zhí)行過程。每個進程都是整個應(yīng)用的某一部分。操作系統(tǒng)在邏輯上維護了進程的運行狀態(tài)信息.即與進程運行直接相關(guān)的CPU寄存器和??臻g(只有這樣才能實現(xiàn)進程切換)。操作系統(tǒng)根據(jù)當前進程的情況設(shè)置

51、進程的狀態(tài)并根據(jù)進程的狀態(tài)(比如優(yōu)先級)進行選擇一個進程占用CPU并運行這個過程成為調(diào)度。進程的狀態(tài)進程從誕生到死亡要經(jīng)歷若干個階段也會有生老病死。簡單地說進程有三種狀態(tài):就緒、執(zhí)行、等待。多種原因可以導(dǎo)致創(chuàng)建一個進程比如當操作系統(tǒng)把一個程序從硬盤調(diào)入內(nèi)存后在開始執(zhí)行前.操作系統(tǒng)就要為此程序創(chuàng)建一個對應(yīng)的進程。又比如.一個進程可以自己創(chuàng)建一個子進程子進程被創(chuàng)建后就是在內(nèi)存中.處于就緒態(tài)所謂就緒態(tài)就是萬事具備只欠CPU這個東風了;一旦進程占有了CPU.就可以執(zhí)行實際的工作了.其狀態(tài)就變成了執(zhí)行態(tài);進程在執(zhí)行中如果需要等待某個資源(如等硬盤輸入數(shù)據(jù))則進程會放棄CPU.且其狀態(tài)就變?yōu)榈却龖B(tài)這時操作

52、系統(tǒng)又會從處于就緒態(tài)的另一個進程中挑選一個進程占有CPU.則這另一個進程的狀態(tài)就變成了執(zhí)行態(tài)。當前一個進程所等到數(shù)據(jù)到來后處于等待態(tài)的前一個進程又被喚醒并把狀態(tài)變成為就緒態(tài)。在實際的操作系統(tǒng)中進程的狀態(tài)往往多于三種.比如找xv6中.進程具有多種狀態(tài).包括:EMBRO,SLEEPING,RUNNABLE,RUNNING和ZOMBIE。定義在proc.h文件中:enumproc_stateUNUSED,EMBRYO,SLEEPING,RUNNABLE,RUNNING,ZOMBIE;狀態(tài)的含義如下:UNUSED:進程未被創(chuàng)建(即進程控制塊空閑)時的狀態(tài);EMBRYO:需要分配一個進程控制塊且找到一個

53、處于UNUSED狀態(tài)的進程控制塊時.把此進程控制塊狀態(tài)設(shè)置為要使用的狀態(tài);SLEEPING:進程由于等待某資源等原因無法執(zhí)行進入睡眠狀態(tài)即等待態(tài);RUNNABLE:進程獲得了除CPU之外的所有資源處于可運行狀態(tài)即就緒態(tài);RUNNING:進程獲得CPU.正在運行的狀態(tài).即執(zhí)行態(tài);ZOMBIE:進程結(jié)束的狀態(tài)這幾個狀態(tài)之間的轉(zhuǎn)化如圖5.1(左)所示。由于是SMP架構(gòu)因此每個CPU獲取進程調(diào)度的權(quán)利是相同的。CPU在scheduler里面進行輪詢操作.每次從線程池中選擇一個RUNNABLE的進程進行運行。直到運行完畢或一單位時間片結(jié)束或者進程主動yield或sleep。CPU與進程池的關(guān)系如圖5.1

54、(右)所示。圖5.1狀態(tài)轉(zhuǎn)換的過程即哪些事件促使了狀態(tài)的轉(zhuǎn)換TODO進程控制塊程序的運行是通過進程體現(xiàn)的.操作系統(tǒng)對進程進行管理和控制.那么操作系統(tǒng)怎么了解到進程的狀態(tài)并掌握進程占有的資源分配呢.而且進程做狀態(tài)轉(zhuǎn)換時CPU的現(xiàn)場保存在那呢?這實際是通過進程控制快(ProcessControlBlock,簡稱PCB)。PCB是進程的唯一標志在其中記錄了進程的全部信息.相當于進程的檔案。操作系統(tǒng)通過PCB感知進程的存在.通過PCB了解進程和控制進程的運行。在xv6中所有的CPU共享一個進程控制塊池即源代碼中為proc.c中的proc(即進程控制塊)數(shù)組。在這個進程數(shù)組保存的進程控制塊結(jié)構(gòu)分成兩類:

55、一類是未使用的進程控制塊結(jié)構(gòu)另一類是正在使用的進程控制塊結(jié)構(gòu)。每次要創(chuàng)建一個進程時.只需要從進程控制塊數(shù)組中取得一個未使用進程控制塊結(jié)構(gòu)進行相應(yīng)的處理即可。代碼分析結(jié)構(gòu)與變量proc.h文件中定義了幾個關(guān)鍵的數(shù)據(jù)結(jié)構(gòu)。其中context是在內(nèi)核進行上下文切換需要保存的寄存器(定義在proc.h中):structcontextinteip;intesp;intebx;intecx;intedx;intesi;intedi;intebp;Q:為何不保存eax?proc結(jié)構(gòu)描述了進程運行需要的數(shù)據(jù):structprocchar*mem;processmemory(kerneladdress)uint

56、sz;ofprocessmemory(bytes)char*kstack;kernelstackforthisprocessenumproc_statestate;intpid;ProcessIDstructproc*parent;void*chan;zero,sleepingonchanintkilled;Ifnon-zero,havebeenkilledstructfile*ofileNOFILE;structinode*cwd;structcontextcontext;structtrapframe*tf;interruptcharname16;(debugging);其中:mem記錄了

57、進程在內(nèi)核的起始地址;/Startof/Size/Bottomof/Processstate/Parentprocess/Ifnon/Openfiles/Currentdirectory/Switchheretorunprocess/Trapframeforcurrent/ProcessnameSZ是記錄進程所占有的內(nèi)存空間大??;kstack是進程在內(nèi)核態(tài)的棧;state是進程的狀態(tài);pid是進程的ID;chan不為NULL時.是進程睡眠時所掛的睡眠隊列;killed不為0時.表示進程被殺死了;ofile數(shù)組是進程打開的文件數(shù)組;cwd是進程運行時所處的當前目錄;context是切換進程需要維

58、護的硬件寄存器內(nèi)容;tf是中斷進程后.需要恢復(fù)進程繼續(xù)執(zhí)行所保存的寄存器內(nèi)容;name保存了進程的名字(用于調(diào)試)。進程在內(nèi)存中的布局如下:expandableheap(堆)fixed-sizestack(棧)originaldataandbss(數(shù)據(jù))Text(代碼)procNPR0C數(shù)組(在proc.c文件的11行)定義了xv6所能夠支持的進程所需的相關(guān)數(shù)據(jù).NPR0C表示了xv6可支持進程個數(shù)。cpu結(jié)構(gòu)是記錄計算機中所有CPU的相關(guān)信息:structcpuucharapicid;LocalAPICIDstructproc*curproc;running.structcontextcon

59、text;schedulerstructtaskstatets;tofindstackforinterruptstructsegdescgdtNSEGS;/volatileuintbooted;started?intncli;/Dintena;interruptsenabledbeforepushcli?;/Processcurrently/Switchheretoenter/Usedbyx86x86globaldescriptortable/HastheCPU/Were其中:apicid代表此CPU的id編號;curproc是當前正在此CPU上運行的進程控制塊;TOC o 1-5 h zco

60、ntext;ts是Taskstatesegment.用于在中斷時找到棧;gdt是此CPU的全局描述符表(GDT);booted表示是否此CPU已經(jīng)啟動了;ncli表示執(zhí)行pushcli函數(shù)的次數(shù);intena表示;全局變量進程數(shù)組procNPR0C數(shù)組就是進程池。進程池訪問鎖proc_table_lock是一個spinlock是用來保護對進程池的臨界區(qū)訪問。當前運行進程curproc則是記錄每個cpu當前運行的進程。第一個進程initproc是記錄第一個創(chuàng)立的進程。這個進程十分特殊.它將托管所有沒有父進程的進程(也就是父進程先于子進程結(jié)束)。下一進程號nextid是用來產(chǎn)生進程號的.在系統(tǒng)啟動

溫馨提示

  • 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)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論