

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、<p><b> 《操作系統(tǒng)》</b></p><p><b> 課程設(shè)計(jì)說明書</b></p><p> 題 目: Geekos操作系統(tǒng)的研究與實(shí)現(xiàn) </p><p> 學(xué) 院: 計(jì)算機(jī)科學(xué)與工程學(xué)院 </p><p
2、> 專 業(yè): 信息安全 </p><p> 姓 名: </p><p> 學(xué) 號(hào): </p><p> 指導(dǎo)教師: </p&g
3、t;<p> 2013年 03 月 20日</p><p><b> 目 錄</b></p><p> 1 實(shí)驗(yàn)?zāi)康?..................................................................3</p><p> 2 項(xiàng)目設(shè)計(jì)要求...............
4、.............................................3</p><p> 3 如何建立開發(fā)環(huán)境.....................................................4</p><p> 4 項(xiàng)目設(shè)計(jì)原理........................................................
5、.....5</p><p> 5 項(xiàng)目設(shè)計(jì)的具體實(shí)現(xiàn)..................................................9</p><p> 6 系統(tǒng)編譯運(yùn)行的原理及結(jié)果.......................................19</p><p> 7 遇到問題及解決方法.................
6、.................................21</p><p> 8 課程設(shè)計(jì)總結(jié).............................................................22</p><p><b> 1 實(shí)驗(yàn)?zāi)康?</b></p><p> 操作系統(tǒng)的課程設(shè)計(jì)非常又必要,可以使我
7、們通過實(shí)驗(yàn),更加深入得理解和掌握操作系統(tǒng)的基本理論和功能技術(shù),將相對(duì)抽象的理論應(yīng)用于實(shí)踐,提高分析問題和解決問題的能力,提高編寫和開發(fā)系統(tǒng)程序的能力。 此次課程設(shè)計(jì),通過搭建Linux實(shí)驗(yàn)平臺(tái),對(duì)專門為操作系統(tǒng)課程教學(xué)而設(shè)計(jì)的操作系統(tǒng)——GeekOS的項(xiàng)目代碼的補(bǔ)充和完善,從淺到深,由表面到內(nèi)涵地去理解操作系統(tǒng)的設(shè)計(jì)思想,理解操作系統(tǒng)內(nèi)核工作的基本原理。在完成項(xiàng)目的過程中,通過動(dòng)手操作,使得我們能夠在動(dòng)手查閱資料、思考排難等探索性活動(dòng)中
8、進(jìn)一步理解操作系統(tǒng)的抽象概念,并進(jìn)一步理解操作系統(tǒng)復(fù)雜的結(jié)構(gòu)和工作原理。以下是各個(gè)項(xiàng)目的主要目的:</p><p> 項(xiàng)目0:熟悉GeekOS的項(xiàng)目編譯、調(diào)試和運(yùn)行環(huán)境,掌握GeekOS運(yùn)行工作過程。</p><p> 項(xiàng)目1:熟悉ELF文件格式,了解GeekOS系統(tǒng)如何將ELF格式的用戶可執(zhí)行程序裝入到內(nèi)存,建立內(nèi)核進(jìn)程并運(yùn)行的實(shí)現(xiàn)技術(shù)。</p><p>
9、項(xiàng)目2: 擴(kuò)充GeekOS操作系統(tǒng)內(nèi)核, 使得系統(tǒng)能夠支持用戶級(jí)進(jìn)程的動(dòng)態(tài)創(chuàng)建和執(zhí)行。</p><p><b> 2 項(xiàng)目設(shè)計(jì)要求</b></p><p> 2.1 Project0</p><p> 搭建GeekOS的編譯和調(diào)試平臺(tái),掌握GeekOS的內(nèi)核進(jìn)程工作原理。</p><p> 熟悉鍵盤操作函數(shù),編程
10、實(shí)現(xiàn)一個(gè)內(nèi)核進(jìn)程。該進(jìn)程的功能是:接收鍵盤輸入的字符并顯示到屏幕上,當(dāng)輸入ctrl+d時(shí),結(jié)束進(jìn)程的運(yùn)行。</p><p> 2.2 Project1</p><p> 修改/geekos/elf.c文件:在函數(shù)Parse_ELF_Executable( )中添加代碼,分析ELF格式的可執(zhí)行文件(包括分析得出ELF文件頭、程序頭,獲取可執(zhí)行文件長(zhǎng)度,代碼段、數(shù)據(jù)段等信息),并填充Exe
11、_Format數(shù)據(jù)結(jié)構(gòu)中的域值。</p><p> 在Linux環(huán)境下編譯系統(tǒng)得到GeekOS鏡像文件。</p><p> 編寫一個(gè)相應(yīng)的bochs配置文件。</p><p> 在bochs中運(yùn)行GeekOS系統(tǒng)顯示結(jié)果。</p><p> 2.3 Project2:要求用戶對(duì)以下幾個(gè)文件進(jìn)行修改:</p><p&
12、gt; “src/GeekOS/user.c”文件中的函數(shù)Spawn(),其功能是生成一個(gè)新的用戶級(jí)進(jìn)程;</p><p> “src/GeekOS/user.c”文件中的函數(shù)Switch_To_User_Context(),調(diào)度程序在執(zhí)行一個(gè)新的進(jìn)程前調(diào)用該函數(shù)以切換用戶地址空間;</p><p> “src/GeekOS/elf.c”文件中的函數(shù)Parse_ELF_Executa
13、ble()。該函數(shù)的實(shí)現(xiàn)要求和項(xiàng)目1相同。</p><p> “src/GeekOS/userseg.c”文件中主要是實(shí)現(xiàn)一些為實(shí)現(xiàn)對(duì)“src/GeekOS/user.c”中高層操作支持的函數(shù)。</p><p> “src/GeekOS/kthread.c”文件中的Start_User_Thread函數(shù)和Setup_User_Thread函數(shù)。Setup_User_Thread()函數(shù)
14、的功能是為進(jìn)程初始化內(nèi)核堆棧,堆棧中是為進(jìn)程首次進(jìn)入用戶態(tài)運(yùn)行時(shí)設(shè)置處理器狀態(tài)要使用的數(shù)據(jù)。Start_User_Thread()是一個(gè)高層操作,該函數(shù)使用User_Context對(duì)象開始一個(gè)新進(jìn)程。</p><p> “src/GeekOS/kthread.c”文件中主要是實(shí)現(xiàn)用戶程序要求內(nèi)核進(jìn)行服務(wù)的一些系統(tǒng)調(diào)用函數(shù)定義。要求用戶實(shí)現(xiàn)的有Sys_Exit()函數(shù)、Sys_PrintString()函數(shù)、Sy
15、s_GetKey()、Sys_SetAttr()、Sys_GetCursor()、Sys_PutCursor()、Sys_Spawn()函數(shù)、Sys_Wait()函數(shù)和Sys_GetPID( )函數(shù)。</p><p> 在main.c文件中改寫生成第一個(gè)用戶態(tài)進(jìn)程的函數(shù)調(diào)用:Spawn_Init_Process(void) 。</p><p><b> 3 開發(fā)環(huán)境的建立&l
16、t;/b></p><p> 3.1 開發(fā)環(huán)境的介紹</p><p> ?。?) Geekos是一個(gè)基于X86架構(gòu)的PC機(jī)上運(yùn)行的微操作系統(tǒng)內(nèi)核,由美國(guó)馬理蘭大學(xué)的教師開發(fā),是一個(gè)用C語言開發(fā)的操作系統(tǒng),GeekOS主要用于操作系統(tǒng)課程設(shè)計(jì),目的是使學(xué)生能夠?qū)嶋H動(dòng)手參與到一個(gè)操作系統(tǒng)的開發(fā)工作中。學(xué)生可以在Linux或Unix環(huán)境下對(duì)其進(jìn)行功能擴(kuò)充,也可以在windows下使用Cy
17、gwin工具進(jìn)行開發(fā),其主要特點(diǎn)是:簡(jiǎn)單、實(shí)用、易懂,便于學(xué)生們理解操作系統(tǒng)的設(shè)計(jì)思想和實(shí)現(xiàn)過程。出于教學(xué)目的,這個(gè)系統(tǒng)內(nèi)核設(shè)計(jì)簡(jiǎn)單,卻又兼?zhèn)鋵?shí)用性,它可以運(yùn)行在真正的X86 PC硬件平臺(tái)。</p><p> (2)VMware Workstation</p><p> VMware Workstation 是一款功能強(qiáng)大的桌面虛擬計(jì)算機(jī)軟件,提供用戶可在單一的桌面上同時(shí)運(yùn)行不同的操作
18、系統(tǒng),和進(jìn)行開發(fā)、測(cè)試 、部署新的應(yīng)用程序的最佳解決方案。它可以使你在一臺(tái)機(jī)器上同時(shí)運(yùn)行二個(gè)或更多Windows、DOS、LINUX系統(tǒng)。與“多啟動(dòng)”系統(tǒng)相比,VMWare采用了完全不同的概念。多啟動(dòng)系統(tǒng)在一個(gè)時(shí)刻只能運(yùn)行一個(gè)系統(tǒng),在系統(tǒng)切換時(shí)需要重新啟動(dòng)機(jī)器。VMWare是真正“同時(shí)”運(yùn)行,多個(gè)操作系統(tǒng)在主系統(tǒng)的平臺(tái)上,就象標(biāo)準(zhǔn)Windows應(yīng)用程序那樣切換。而且每個(gè)操作系統(tǒng)你都可以進(jìn)行虛擬的分區(qū)、配置而不影響真實(shí)硬盤的數(shù)據(jù),你甚至可
19、以通過網(wǎng)卡將幾臺(tái)虛擬機(jī)用網(wǎng)卡連接為一個(gè)局域網(wǎng),極其方便。安裝在VMware操作系統(tǒng)性能上比直接安裝在硬盤上的系統(tǒng)低不少,因此,比較適合學(xué)習(xí)和測(cè)試。</p><p> ?。?)Bochs PC 模擬器 </p><p> GeekOS運(yùn)行于Windows(或Linux)下的Bochs PC模擬器,Bochs 是用 C++ 開發(fā)的可移植的 IA-32 (x86) PC 模擬器,Bochs仿真
20、器其實(shí)質(zhì)就是一臺(tái)虛擬PC機(jī),它包括對(duì) Intel x86 CPU 、通用 I/O 設(shè)備和可定制的 BIOS 的模擬,幾乎可以運(yùn)行在所有流行的平臺(tái)上。目前, Bochs 可以模擬 386, 486, Pentium Pro 或者 AMD64 CPU 。Bochs 的模擬環(huán)境中也可以運(yùn)行大部分的操作系統(tǒng),包括 Linux, Windows 95, DOS, Windows NT 4, FreeBSD, MINIX 等。</p>
21、<p> 3.2開發(fā)環(huán)境的構(gòu)建</p><p> (1)下載并安裝VMware虛擬機(jī);</p><p> ?。?)在VMware虛擬機(jī)上安裝CentOS版本的linux操作系統(tǒng)。</p><p> ?。?)在VMware虛擬機(jī)上的linux環(huán)境下對(duì)GeekOS源文件進(jìn)行編譯和鏈接,編譯成功后生成fd.img軟盤映射文件和hd.img硬盤映射文件;&l
22、t;/p><p> ?。?)下載并安裝系統(tǒng)仿真工具Bochs;</p><p> ?。?)在終端打開bochs-2.3-pre3$ ./configure 配置bochs的文件</p><p> ?。?)make 工具</p><p> 無論是在Linux還是在UNIX環(huán)境中,make都是一個(gè)非常重要的系統(tǒng)開發(fā)工具。利用make工具,可以將大型
23、的開發(fā)項(xiàng)目分解成為多個(gè)更易于管理的模塊,對(duì)于一個(gè)包括幾百個(gè)源文件的應(yīng)用程序,使用make和makefile工具就可以簡(jiǎn)潔明快地理順各個(gè)源文件之間紛繁復(fù)雜的相互關(guān)系。 make能夠按照規(guī)則自動(dòng)完成編譯工作,并且可以只對(duì)程序員在上次編譯后修改過的文件進(jìn)行編譯,減少重復(fù)編譯的工作量。 它就是字符操作方式下的項(xiàng)目管理工具。</p><p> bochs-2.3-pre3$ make</p><p&g
24、t; bochs-2.3-pre3$ make install</p><p> ?。?)配置Bochs環(huán)境配置文件Bochsrc.txt:</p><p> vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest</p><p> romimage: file=$BXSHARE/BIOS-bochs-latest, ad
25、dress=0xf0000</p><p><b> megs: a</b></p><p><b> boot: c</b></p><p> floppya: 1_44=fd.img, status=inserted</p><p> #floppya: 1_44=fd_aug.img,
26、 status=inserted</p><p> log: ./bochs.out</p><p> keyboard_serial_delay: 200</p><p> floppy_command_delay: 500</p><p> vga_update_interval: 300000</p><p&
27、gt; ips: 1000000</p><p> mouse: enabled=0</p><p> private_colormap: enabled=0</p><p> i440fxsupport: enabled=0</p><p> ?。?)啟動(dòng)Boch環(huán)境,在提示的出現(xiàn)GeekOS的歡迎界面。</p>&
28、lt;p> ?。?)GeekOS系統(tǒng)編譯和仿真成功。</p><p><b> 4項(xiàng)目設(shè)計(jì)原理</b></p><p> 4.1 Project0</p><p> 利用bochs模擬計(jì)算機(jī)執(zhí)行一個(gè)操作系統(tǒng)軟件。其中BIOS-bochs-lastest文件模擬bochs硬件的BIOS。VGABIOS-lgpl-lastest文件模擬
29、bochs顯示系統(tǒng)的BIOS。bochsrc.txt描述模擬器硬件配置的配置。利用GeekOS提供的鍵盤處理函數(shù)keyboard.h與keyboard.c等進(jìn)行鍵盤常用功能的模擬。</p><p> 其中,在keyboard.c里面提供了一個(gè)功用函數(shù)Keycode Wait_For_Key(void),循環(huán)等待一個(gè)鍵盤事件,然后返回一個(gè)16位的數(shù)據(jù) Keycode型的, 在keyboard.h里定義了所有的鍵盤
30、代碼。Read_Key(Keycode* keycode)函數(shù)可以處理隊(duì)列鍵盤按鍵,可以保存到隊(duì)列中并輸出。</p><p> 4.2 Project1</p><p> ELF(Executable and linking format)文件是UNIX系統(tǒng)實(shí)驗(yàn)室作為應(yīng)用程序二進(jìn)制接口而開發(fā)的可執(zhí)行文件,是x86 Linux系統(tǒng)下的一種常用目標(biāo)文件(object file)格式。ELF
31、文件格式如下表1。</p><p> 表1 ELF目標(biāo)文件格式</p><p> ELF文件在磁盤中的映象和在內(nèi)存中的執(zhí)行程序鏡像的對(duì)應(yīng)關(guān)系如下圖:</p><p> 圖1 ELF文件和內(nèi)存中的可執(zhí)行文件鏡像</p><p> 內(nèi)核進(jìn)程的創(chuàng)建流程如下圖:</p><p> 圖2 內(nèi)核進(jìn)程流程圖</
32、p><p> Parse_ELF_Excutable函數(shù)的定義為:</p><p> int Parse_ELF_Executable(char *exeFileData,ulong_t exeFileLength,truct Exe_Format *exeFormat)</p><p> 參數(shù):exeFileData——已裝入內(nèi)存的可執(zhí)行文件所占用空間的起始地址
33、</p><p> exeFileLength——可執(zhí)行文件長(zhǎng)度</p><p> exeFormat——保存分析得到的elf文件信息的結(jié)構(gòu)體指針根據(jù)ELF文件格式,用戶可以從exeFileData指向的內(nèi)容中得到ELF文件頭,繼續(xù)分析可以得到程序頭,程序代碼段等信息。</p><p> 4.3 Project2</p><p> G
34、eekos進(jìn)程狀態(tài)及轉(zhuǎn)化:</p><p> 圖3 GeekOS進(jìn)程狀態(tài)轉(zhuǎn)換</p><p> GeekOS系統(tǒng)最早創(chuàng)建的內(nèi)核進(jìn)程有Idle、Reaper和Main三個(gè)進(jìn)程,它們由Init_Scheduler函數(shù)創(chuàng)建:最先初始化一個(gè)核態(tài)進(jìn)程mainThread,并將該進(jìn)程作為當(dāng)前運(yùn)行進(jìn)程,函數(shù)最后還調(diào)用Start_Kernel_Thread 函數(shù)創(chuàng)建了兩個(gè)系統(tǒng)進(jìn)程Idle和Reape
35、r。 所以,Idle、Reaper和Main三個(gè)進(jìn)程是系統(tǒng)中最早存在的進(jìn)程。</p><p> 在GeekOS中為了區(qū)分用戶態(tài)進(jìn)程和內(nèi)核進(jìn)程,在Kernel_Thread結(jié)構(gòu)體中設(shè)置了一個(gè)字段 userContext,指向用戶態(tài)進(jìn)程上下文。對(duì)于內(nèi)核進(jìn)程來說,這個(gè)指針為空,而用戶態(tài)進(jìn)程都擁有自己的用戶上下文(User_Context)。因此,在GeekOS中要判斷一個(gè)進(jìn)程是內(nèi)核進(jìn)程還是用戶態(tài)進(jìn)程,只要通過user
36、Context字段是否為空來判斷就可以了。 </p><p> 每個(gè)用戶態(tài)進(jìn)程都擁有屬于自己的內(nèi)存段空間,如:代碼段、數(shù)據(jù)段、堆棧段等,每個(gè)段有一個(gè)段描述符(segment descriptor),并且每個(gè)進(jìn)程有一個(gè)段描述符表(Local Descriptor Table),用于保存該進(jìn)程的所有段描述符。操作系統(tǒng)中還設(shè)置一個(gè)全局描述符表(GDT,Global Descriptor Table),用于記錄了系統(tǒng)中
37、所有進(jìn)程的ldt描述符。</p><p> 圖5 GDT、LDT和User_Context的關(guān)系</p><p> 用戶態(tài)進(jìn)程創(chuàng)建LDT的步驟:</p><p> (1)調(diào)用函數(shù)Allocate_Segment_Descriptor()新建一個(gè)LDT描述符;</p><p> (2)調(diào)用函數(shù)Selector()新建一個(gè)LDT選擇子;
38、</p><p> (3)調(diào)用函數(shù)Init_Code_Segment_Descriptor()新建一個(gè)文本段描述符;</p><p> (4)調(diào)用函數(shù)Init_Data_Segment_Descriptor()新建一個(gè)數(shù)據(jù)段;</p><p> (5)調(diào)用函數(shù)Selector()新建一個(gè)數(shù)據(jù)段選擇子;</p><p> (6)調(diào)用函數(shù)
39、Selector()新建一個(gè)文本(可執(zhí)行代碼)段選擇子。</p><p> 用戶態(tài)進(jìn)程創(chuàng)建流程:</p><p> 5 項(xiàng)目設(shè)計(jì)的具體實(shí)現(xiàn)</p><p> 5.1 Project0項(xiàng)目的具體實(shí)現(xiàn)</p><p> 一、 添加代碼1. 在Main函數(shù)中編寫一個(gè)函數(shù),函數(shù)功能是:接收鍵盤輸入的按鍵,并將鍵值顯示到顯示器的函數(shù),當(dāng)輸入C
40、trl+D就退出。</p><p> void project0(){ Print("To Exit hit Ctrl + d.\n"); Keycode keycode; while(1) { if( Read_Key(&keycode) ) {//讀取鍵盤按鍵狀態(tài) if(!( (keycode &a
41、mp; KEY_SPECIAL_FLAG) || (keycode & KEY_RELEASE_FLAG)) ) { //只處理非特殊按鍵的按下事件 int asciiCode = keycode & 0xff; //低8位為Ascii碼 if( (keycode & KEY_CTRL_FLAG)=
42、=KEY_CTRL_FLAG && asciiCode=='d') {//按下Ctrl鍵 Print("\n---------BYE!--------\n"); </p><p> void Main(struct Boot_Info* bootInfo){ .........
43、..</p><p> //TODO("Start a kernel thread to echo pressed keys and print counts"); struct Kernel_Thread *thread; thread = Start_Kernel_Thread(&project0,0,PRIORITY_NORMAL,false);</p&g
44、t;<p> ............</p><p> }二、 編譯GeekOS項(xiàng)目project01. 進(jìn)入geekos-0.3.0/src/project0/build目錄</p><p> # cd /.../geekos-0.3.0/src/project0/build2. 執(zhí)行 make depend </p><p> b
45、uild]# make depend</p><p> 生成depend.mak文件3. 執(zhí)行 make build]# make成功之后在build 目錄下生成fd.img文件。三、 配置啟動(dòng)Bochs1. 創(chuàng)建bochs配置文件:輸入 gedit bochsrc</p><p> build]# gedit bochsrc</p><p> 注意
46、:這是在geekos-0.3.0/src/project0/build目錄下創(chuàng)建bochs的配置文件 bochsrc。2. 在編輯器中輸入以下配置內(nèi)容</p><p> config_interface: textconfigvgaromimage: file=$BXSHARE/VGABIOS-lgpl-latestromimage: file=$BXSHARE/BIOS-bochs-latest, ad
47、dress=0xf0000megs: 8boot: afloppya: 1_44=fd.img, status=insertedlog: ./bochs.outkeyboard_serial_delay: 250keyboard_paste_delay: 100000floppy_command_delay: 500vga_update_interval: 300000ips: 1000000mouse: enab
48、led=0private_colormap: enabled=05.2 Project1項(xiàng)目的具體實(shí)現(xiàn)</p><p><b> 一、 添加代碼</b></p><p> 修改project/project1/src/geekos/elf.c文件:在函數(shù)Parse_ELF_Executable( )中添加代碼,分析 ELF格式的可執(zhí)行文件(包括分析得出ELF文
49、件頭、程序頭,獲取可執(zhí)行文件長(zhǎng)度,代碼段、數(shù)據(jù)段等信息),并填充Exe_Format數(shù)據(jù)結(jié)構(gòu)中的域值。</p><p> int Parse_ELF_Executable(char *exeFileData, ulong_t exeFileLength, struct Exe_Format *exeFormat){ int i; elfHeader *head=(elfHeader*)ex
50、eFileData; programHeader *proHeader=(programHeader *)(exeFileData+head->phoff); KASSERT(exeFileData!=NULL); KASSERT(exeFileLength>head->ehsize+head->phentsize*head->phnum); KASSERT(head->ent
51、ry%4==0); exeFormat->numSegments=head->phnum; exeFormat->entryAddr=head->entry; for(i=0;i<head->phnum;i++){ exeFormat->segmentList[i].offse</p><p> 二、 編譯GeekOS項(xiàng)目project1<
52、;/p><p> 1. 進(jìn)入geekos-0.3.0/src/project1/build目錄</p><p> # cd /.../geekos-0.3.0/src/project1/build2. 執(zhí)行 make depend </p><p> build]# make depend</p><p> 生成depend.mak文
53、件3. 執(zhí)行 make build]# make成功之后在build 目錄下生成fd.img和disk.img文件。</p><p> 三、 配置啟動(dòng)Bochs1. 創(chuàng)建bochs配置文件:輸入 gedit bochsrc</p><p> build]# gedit bochsrc</p><p> 注意:這是在geekos-0.3.0/src/pr
54、oject1/build目錄下創(chuàng)建bochs的配置文件 bochsrc。2. 在編輯器中輸入以下配置內(nèi)容</p><p> config_interface: textconfigvgaromimage: file=$BXSHARE/VGABIOS-lgpl-latestromimage: file=$BXSHARE/BIOS-bochs-latest, address=0xf0000megs: 8b
55、oot: afloppya: 1_44=fd.img, status=insertedlog: ./bochs.outkeyboard_serial_delay: 250keyboard_paste_delay: 100000floppy_command_delay: 500vga_update_interval: 300000ips: 1000000mouse: enabled=0private_colormap:
56、 enabled=0i440fxsupport: enabled=0ata0:enabled=1, ioaddr1=0x1f0,ioaddr2=0x3f0,irq=14ata0-master:type=disk,mode=flat,path=./diskc.img,</p><p> 5.3 Project2項(xiàng)目的具體實(shí)現(xiàn)</p><p><b> 1、添加代碼<
57、/b></p><p> ================== user.c ===============</p><p> //產(chǎn)生一個(gè)進(jìn)程(用戶態(tài))</p><p> int Spawn(const char *program, const char *command, struct Kernel_Thread **pThread)</p&g
58、t;<p> { int rc; char *exeFileData = 0; ulong_t exeFileLength; struct User_Context *userContext = 0; struct Kernel_Thread *process = 0;</p><p> struct Exe_Format exeFormat; if ((rc = Read_Fu
59、lly(program, (void**) &exeFileData, &exeFileLength)) != 0 ) { Print("Failed to Read File %s!\n", program); goto fail; } if((rc = Parse_ELF_Executable(exeFileData, exeFileLength, &exeFormat))
60、!= 0 ) { Print("Failed to Parse ELF File!\n"); goto fail; } if((rc = Load_User_Program(exeFileData, exeFileLength, &exeFormat, command, &userContext)) != 0) { Print("Failed to Load Us
61、er Program!\n"); goto fail; } Free(exeFileData); exeFi</p><p> rc = ENOMEM; return rc;fail: if (exeFileData != 0) Free(exeFileData); if (userContext != 0) Destroy_User_Context(userCon
62、text); return rc;</p><p><b> }</b></p><p> -------------------------------------</p><p> //切換至用戶上下文</p><p> void Switch_To_User_Context(struct Kernel_
63、Thread* kthread, struct Interrupt_State* state)</p><p> { static struct User_Context* s_currentUserContext; /* last user context used */ struct User_Context* userContext = kthread->userContext;//指向Use
64、r_Conetxt的指針,并初始化為準(zhǔn)備切換的進(jìn)程 KASSERT(!Interrupts_Enabled()); if (userContext == 0) { //userContext為0表示此進(jìn)程為核心態(tài)進(jìn)程就不用切換地址空間 return; } if (userContext != s_currentUserContext) { ulong_t esp0; //if (userDebug) Print(&
65、quot;A[%p]\n", kthread); Switch_To_Address_Space(userContext);//為用戶態(tài)進(jìn)程時(shí)則切換地址空間 esp0 = ((ulong_t) kthread->stackPage) + PAGE_SIZE; //</p><p><b> } </b></p><p> =======
66、=========== elf.c ====================同 project1</p><p> =================== userseg.c ===================</p><p> //需在此文件各函數(shù)前增加一個(gè)函數(shù),此函數(shù)的功能是按給定的大小創(chuàng)建一個(gè)用戶級(jí)進(jìn)程上下文,具體實(shí)現(xiàn)如下://函數(shù)功能:按給定的大小創(chuàng)建一個(gè)用戶級(jí)進(jìn)程上下
67、文static struct User_Context* Create_User_Context(ulong_t size){ struct User_Context * UserContext; size = Round_Up_To_Page(size); UserContext = (struct User_Context *)Malloc(sizeof(struct User_Context));
68、//為用戶態(tài)進(jìn)程 if (UserContext != 0) UserContext->memory = Malloc(size); //為核心態(tài)進(jìn)程 else goto fail; //內(nèi)存為空 if (0 == UserContext->memory) goto fail; memset(UserContex</p>
69、<p> --------------------------------------------</p><p><b> //摧毀用戶上下文</b></p><p> void Destroy_User_Context(struct User_Context* userContext)</p><p> { /
70、/TODO("Destroy a User_Context");</p><p> //釋放占用的LDT Free_Segment_Descriptor(userContext->ldtDescriptor); userContext->ldtDescriptor=0; //釋放內(nèi)存空間 Free(userContext->memory)
71、; userContext->memory=0; //釋放userContext本身占用的內(nèi)存 Free(userContext); userContext=0;}</p><p> ----------------------------------------------int Load_User_Program(char *exeFileData, ulong
72、_t exeFileLength,struct Exe_Format *exeFormat, const char *command, struct User_Context **pUserContext){ //TODO("Load a user executable into a user memory space using segmentation"); int i; ulong_t ma
73、xva = 0;//要分配的最大內(nèi)存空間 unsigned numArgs;//進(jìn)程數(shù)目 ulong_t argBlockSize;//參數(shù)塊的大小 ulong_t size, argBlockAddr;//參數(shù)塊地址 struct User_Context *userContext = 0;</p><p> //計(jì)算用戶態(tài)進(jìn)程所需的最大內(nèi)存空間 for (i = 0; i < exeForm
74、at->numSegments; ++i) { //elf.h struct Exe_Segment *segment = &exeFormat->segmentList[i]; ulong_t topva = segment->startAddress + segment->sizeInMemory; /* FIXME: range check */ if (topva > max
75、va) maxva = topva; } Get_Argument_Block_Size(command, &numArgs, &argBlockSize);//獲取參數(shù)塊信息 size = Round_Up_To_Page(maxva) + DEFAULT_USER_STACK_SIZE;//用戶進(jìn)程大小=參數(shù)塊總大小 + 進(jìn)程堆棧大小(8192) argBlockAddr = size; size
76、+= argBlockSize; userContext = Create_User_</p><p> ----------------------------------------------</p><p> //將用戶態(tài)的進(jìn)程復(fù)制到內(nèi)核緩沖區(qū)</p><p> bool Copy_From_User(void* destInKernel, ulon
77、g_t srcInUser, ulong_t bufSize)</p><p> { //TODO("Copy memory from user buffer to kernel buffer"); struct User_Context * UserContext = g_currentThread->userContext;</p><p>
78、//--: check if memory if validated if (!Validate_User_Memory(UserContext,srcInUser, bufSize)) return false;</p><p> //--:user->kernel memcpy(destInKernel, UserContext->memory + srcInUser, bufSize)
79、; return true;}</p><p> -----------------------------------------</p><p> //將內(nèi)核態(tài)的進(jìn)程復(fù)制到用戶態(tài)</p><p> bool Copy_To_User(ulong_t destInUser, void* srcInKernel, ulong_t bufSize)&
80、lt;/p><p> { //TODO("Copy memory from kernel buffer to user buffer") struct User_Context * UserContext = g_currentThread->userContext;</p><p> //--: check if memory if validate
81、d if (!Validate_User_Memory(UserContext, destInUser, bufSize)) return false; //--:kernel->user memcpy(UserContext->memory + destInUser, srcInKernel, bufSize);</p><p> return true;}</p>
82、<p> ----------------------------------------</p><p> //切換到用戶地址空間</p><p> void Switch_To_Address_Space(struct User_Context *userContext){ //TODO("Switch to user address space u
83、sing segmentation/LDT"); ushort_t ldtSelector= userContext->ldtSelector;/* Switch to the LDT of the new user context */ __asm__ __volatile__ ("lldt %0"::"a"(ldtSelector));</p><p&g
84、t;<b> }</b></p><p> ================= kthread.c ===============</p><p> 添加頭文件 #include <geekos/user.h></p><p> ----------------------------------</p>&l
85、t;p> //創(chuàng)建一個(gè)用戶進(jìn)程</p><p> /*static*/ void Setup_User_Thread(struct Kernel_Thread* kthread, struct User_Context* userContext){ //TODO("Create a new thread to execute in user mode"); ulong
86、_t eflags = EFLAGS_IF; unsigned csSelector=userContext->csSelector;//CS選擇子 unsigned dsSelector=userContext->dsSelector;//DS選擇子 Attach_User_Context(kthread, userContext); //初始化用戶態(tài)進(jìn)程堆棧,使之看上去像剛被中斷運(yùn)行一樣 //
87、分別調(diào)用Push函數(shù)將以下數(shù)據(jù)壓入堆棧 Push(kthread, dsSelector); //數(shù)據(jù)選擇子 Push(kthread, userContext->stackP</p><p> //開始用戶進(jìn)程struct Kernel_Thread* Start_User_Thread(struct User_Context* userCo
88、ntext, bool detached){ //TODO("Start user thread"); struct Kernel_Thread* kthread = Create_Thread(PRIORITY_USER, detached); //為用戶態(tài)進(jìn)程 if (kthread != 0){ Setup_User_Thread(kthread, userContext); Make_Ru
89、nnable_Atomic(kthread); } return kthread;</p><p><b> }</b></p><p> ================ syscall.c =================</p><p> //需在此文件別的函數(shù)前增加一個(gè)函數(shù),函數(shù)名為Copy_User_String,它被函數(shù)
90、Sys_PrintString調(diào)用,具體實(shí)現(xiàn)如下:static int Copy_User_String(ulong_t uaddr, ulong_t len, ulong_t maxLen, char **pStr){ int rc = 0; char *str; if (len > maxLen){ //超過最大長(zhǎng)度 return EINVALID; } str =
91、(char*) Malloc(len+1); //為字符串分配空間 if (0 == str){ rc = ENOMEM; goto fail; } if (!Copy_From_User(str, uaddr, len)){ //從用戶空間中復(fù)制數(shù)據(jù) rc = EINVALID; Free(str); goto fail;
92、 } str[len] = '</p><p> -----------------------------------------</p><p> static int Sys_Exit(struct Interrupt_State* state){ //TODO("Exit system call"); Exit(state->
93、ebx);</p><p><b> }</b></p><p> -----------------------------------------</p><p> static int Sys_PrintString(struct Interrupt_State* state){ //TODO("PrintStri
94、ng system call"); int rc = 0;//返回值 uint_t length = state->ecx;//字符串長(zhǎng)度 uchar_t* buf = 0; if (length > 0) {/* Copy string into kernel. 將字符串復(fù)制到內(nèi)核*/ if ((rc = Copy_User_String(state->ebx, length, 1023, (
95、char**) &buf)) != 0) goto done;/* Write to console. 將字符串打印到屏幕 */ Put_Buf(buf, length); }done: if (buf != 0) Free(buf); return rc;}</p><p> ----------------------------------------------
96、</p><p> static int Sys_GetKey(struct Interrupt_State* state){ //TODO("GetKey system call"); return Wait_For_Key(); //返回按鍵碼keyboard.c/Wait_For_Key()</p><p><b> }</b>
97、</p><p> ---------------------------------------------static int Sys_SetAttr(struct Interrupt_State* state){ //TODO("SetAttr system call"); Set_Current_Attr((uchar_t) state->ebx); return
98、 0;</p><p><b> }</b></p><p> ---------------------------------------------</p><p> static int Sys_GetCursor(struct Interrupt_State* state){ //TODO("GetCursor
99、 system call"); int row, col; Get_Cursor(&row, &col); if (!Copy_To_User(state->ebx, &row, sizeof(int)) ||!Copy_To_User(state->ecx, &col, sizeof(int))) return -1; return 0;</p><
100、p><b> }</b></p><p> -----------------------------------------------</p><p> static int Sys_PutCursor(struct Interrupt_State* state){ //TODO("PutCursor system call"
101、;); return Put_Cursor(state->ebx, state->ecx) ? 0 : -1;</p><p><b> }</b></p><p> -----------------------------------------------static int Sys_Spawn(struct Interrupt_State*
102、 state){ //TODO("Spawn system call"); int rc; //函數(shù)返回值 char *program = 0; //進(jìn)程名稱 char *command = 0; //用戶命令 struct Kernel_Thread *process;/* Copy program name and comma
103、nd from user space. */ if ((rc = Copy_User_String(state->ebx, state->ecx, VFS_MAX_PATH_LEN, &program)) != 0) {//從用戶空間復(fù)制進(jìn)程名稱 goto fail; } if(rc = Copy_User_String(state->edx, state->esi, 1023, </p
104、><p> Enable_Interrupts(); //開中斷 rc = Spawn(program, command, &process);//得到進(jìn)程名稱和用戶命令后便可生成一個(gè)新進(jìn)程 if (rc == 0) {//若成功則返回新進(jìn)程ID號(hào) KASSERT(process != 0); rc = process->pid; } Disable_Interrupts();//關(guān)
105、中斷fail://返回小于0的錯(cuò)誤代碼 if (program != 0) Free(program); if (command != 0) Free(command); return rc;</p><p><b> }</b></p><p> -----------------------------------------static i
106、nt Sys_Wait(struct Interrupt_State* state){ //TODO("Wait system call"); int exitCode; struct Kernel_Thread *kthread = Lookup_Thread(state->ebx); if (kthread == 0) return -12; Enable_Interrupts(); e
107、xitCode = Join(kthread); Disable_Interrupts(); return exitCode;}</p><p> ---------------------------------------</p><p> static int Sys_GetPID(struct Interrupt_State* state){ //TODO(&qu
108、ot;GetPID system call"); return g_currentThread->pid;</p><p><b> }</b></p><p> ================= main.c ==================static void Spawn_Init_Process(void){ //TODO
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 操作系統(tǒng)課程設(shè)計(jì)-- geekos操作系統(tǒng)的研究與實(shí)現(xiàn)
- 操作系統(tǒng)課程設(shè)計(jì)——操作系統(tǒng)課程設(shè)計(jì)模擬操作系統(tǒng)
- 操作系統(tǒng)課程設(shè)計(jì)-- 操作系統(tǒng)
- 操作系統(tǒng)課程設(shè)計(jì)--模擬操作系統(tǒng)的實(shí)現(xiàn)
- 內(nèi)存管理(操作系統(tǒng))操作系統(tǒng)課程設(shè)計(jì)
- geekos操作系統(tǒng)全部實(shí)驗(yàn)實(shí)現(xiàn)報(bào)告
- 操作系統(tǒng)程序設(shè)計(jì)課程設(shè)計(jì)報(bào)告-操作系統(tǒng)模擬實(shí)現(xiàn)
- 操作系統(tǒng)課程設(shè)計(jì)---操作系統(tǒng)之文件管理部分的設(shè)計(jì)與實(shí)現(xiàn)
- 操作系統(tǒng)課程設(shè)計(jì)
- 操作系統(tǒng)課程設(shè)計(jì)
- 操作系統(tǒng)課程設(shè)計(jì)
- 操作系統(tǒng)課程設(shè)計(jì)
- 操作系統(tǒng)課程設(shè)計(jì)
- 操作系統(tǒng)課程設(shè)計(jì)
- 操作系統(tǒng)課程設(shè)計(jì)題目
- 操作系統(tǒng)課程設(shè)計(jì)報(bào)告
- 操作系統(tǒng)課程設(shè)計(jì)論文
- 操作系統(tǒng)課程設(shè)計(jì) (4)
- 操作系統(tǒng)課程設(shè)計(jì)1
- 課程設(shè)計(jì)報(bào)告--操作系統(tǒng)
評(píng)論
0/150
提交評(píng)論