GeekOS操作系統(tǒng)課程設計項目介紹課件_第1頁
GeekOS操作系統(tǒng)課程設計項目介紹課件_第2頁
GeekOS操作系統(tǒng)課程設計項目介紹課件_第3頁
GeekOS操作系統(tǒng)課程設計項目介紹課件_第4頁
GeekOS操作系統(tǒng)課程設計項目介紹課件_第5頁
已閱讀5頁,還剩97頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

一、項目設計目的熟悉GeekOS的項目編譯、調(diào)試和運行環(huán)境,掌握GeekOS運行工作過程。二、項目設計要求1、搭建GeekOS的編譯和調(diào)試平臺,掌握GeekOS的內(nèi)核進程工作原理。2、熟悉鍵盤操作函數(shù),編程實現(xiàn)一個內(nèi)核進程。該進程的功能是:接收鍵盤輸入的字符并顯示到屏幕上,當輸入ctrl+d時,結(jié)束進程的運行。第八章設計項目0

一、項目設計目的第八章設計項目01三、項目0的實現(xiàn)主要由以下步驟完成(在項目0的/src/geekos/main.c中完成):編寫一個C語言函數(shù),函數(shù)功能是:接收鍵盤輸入的按鍵,并將鍵值在顯示器顯示出來,當輸入ctrl+d就退出;在Main函數(shù)體內(nèi)調(diào)用Start_Kernel_Thread函數(shù),將步驟1編寫的函數(shù)地址傳遞給參數(shù)startFunc,利用Setup_Kernel_Thread函數(shù)建立一個待運行的線程。

在Linux環(huán)境下編譯系統(tǒng)得到GeekOS鏡像文件。編寫一個相應的bochs配置文件。在bochs中運行GeekOS系統(tǒng)顯示結(jié)果。三、項目0的實現(xiàn)主要由以下步驟完成(在項目0的/src/ge2第九章設計項目1

一、項目設計目的熟悉ELF文件格式,了解GeekOS系統(tǒng)如何將ELF格式的可執(zhí)行程序裝入到內(nèi)存,建立內(nèi)核進程并運行的實現(xiàn)技術(shù)。二、項目設計要求1、修改/geekos/elf.c文件:在函數(shù)Parse_ELF_Executable()中添加代碼,分析ELF格式的可執(zhí)行文件(包括分析得出ELF文件頭、程序頭,獲取可執(zhí)行文件長度,代碼段、數(shù)據(jù)段等信息),并填充Exe_Format數(shù)據(jù)結(jié)構(gòu)中的域值。2、在Linux環(huán)境下編譯系統(tǒng)得到GeekOS鏡像文件。3、編寫一個相應的bochs配置文件。4、在bochs中運行GeekOS系統(tǒng)顯示結(jié)果。第九章設計項目1一、項目設計目的31、ELF文件格式

三、項目設計提示表1ELF目標文件格式連接程序視圖

執(zhí)行程序視圖

ELF頭部ELF頭部程序頭部表(可選)程序頭部表節(jié)區(qū)1段1...節(jié)區(qū)n段2.........節(jié)區(qū)頭部表節(jié)區(qū)頭部表(可選)1、ELF文件格式三、項目設計提示表1ELF目標文件格式42、內(nèi)存中的可執(zhí)行文件鏡像

2、內(nèi)存中的可執(zhí)行文件鏡像53、內(nèi)核線程的建立流程Spawn_Init_Process()Start_Kernel_Thread()Spawner()Read_Fully()Parse_ELF_Excutable()Spawn_Program()3、內(nèi)核線程的建立流程Spawn_Init_Process(6根據(jù)Exe_Format中的Exe_Segment結(jié)構(gòu)提供的用戶程序段信息,及用戶進程堆棧大小計算用戶進程所需的最大內(nèi)存空間,即要分配給用戶進程的內(nèi)存空間;為用戶程序分配內(nèi)存空間,并全部初始化為零,否則系統(tǒng)后面運行可能出錯;根據(jù)段信息將用戶程序中的各段內(nèi)容復制到分配的用戶內(nèi)存空間。根據(jù)Exe_Segment提供的用戶段信息初始化代碼段、數(shù)據(jù)段以及堆棧段的段描述符和段選擇子。

4、Spawn_Program函數(shù)的功能根據(jù)Exe_Format中的Exe_Segment結(jié)構(gòu)提供的7intParse_ELF_Executable(char*exeFileData,ulong_texeFileLength,structExe_Format*exeFormat)參數(shù):exeFileData——已裝入內(nèi)存的可執(zhí)行文件所占用空間的起始地址exeFileLength——可執(zhí)行文件長度exeFormat——保存分析得到的elf文件信息的結(jié)構(gòu)體指針根據(jù)ELF文件格式,用戶可以從exeFileData指向的內(nèi)容中得到ELF文件頭,繼續(xù)分析可以得到程序頭,程序代碼段等信息。5、Parse_ELF_Excutable函數(shù)intParse_ELF_Executable(char8第十章設計項目2

一、項目設計目的擴充GeekOS操作系統(tǒng)內(nèi)核,使得系統(tǒng)能夠支持用戶級進程的動態(tài)創(chuàng)建和執(zhí)行。二、項目2要求用戶對以下幾個文件進行修改:1)“src/GeekOS/user.c”文件中的函數(shù)Spawn(),其功能是生成一個新的用戶級進程;2)“src/GeekOS/user.c”文件中的函數(shù)Switch_To_User_Context(),調(diào)度程序在執(zhí)行一個新的進程前調(diào)用該函數(shù)以切換用戶地址空間;

3)“src/GeekOS/elf.c”文件中的函數(shù)Parse_ELF_Executable()。該函數(shù)的實現(xiàn)要求和項目1相同。第十章設計項目2一、項目設計目的94)“src/GeekOS/userseg.c”文件中主要是實現(xiàn)一些為實現(xiàn)對“src/GeekOS/user.c”中高層操作支持的函數(shù)。

Destroy_User_Context()函數(shù)的功能是釋放用戶態(tài)進程占用的內(nèi)存資源。

Load_User_Program()函數(shù)的功能通過加載可執(zhí)行文件鏡像創(chuàng)建新進程的User_Context結(jié)構(gòu)。

Copy_From_User()和Copy_To_User()函數(shù)的功能是在用戶地址空間和內(nèi)核地址空間之間復制數(shù)據(jù),在分段存儲器管理模式下,只要段有效,調(diào)用memcpy函數(shù)就可以實現(xiàn)這兩個函數(shù)的功能。

Switch_To_Address_Space()函數(shù)的功能是通過將進程的LDT裝入到LDT寄存器來激活用戶的地址空間;GeekOS操作系統(tǒng)課程設計項目介紹105)“src/GeekOS/kthread.c”文件中的Start_User_Thread函數(shù)和Setup_User_Thread函數(shù)。Setup_User_Thread()函數(shù)的功能是為進程初始化內(nèi)核堆棧,堆棧中是為進程首次進入用戶態(tài)運行時設置處理器狀態(tài)要使用的數(shù)據(jù)。Start_User_Thread()是一個高層操作,該函數(shù)使用User_Context對象開始一個新進程。6)“src/GeekOS/kthread.c”文件中主要是實現(xiàn)用戶程序要求內(nèi)核進行服務的一些系統(tǒng)調(diào)用函數(shù)定義。要求用戶實現(xiàn)的有Sys_Exit()函數(shù)、Sys_PrintString()函數(shù)、Sys_GetKey()、Sys_SetAttr()、Sys_GetCursor()、Sys_PutCursor()、Sys_Spawn()函數(shù)、Sys_Wait()函數(shù)和Sys_GetPID()函數(shù)。7)在main.c文件中改寫生成第一個用戶態(tài)進程的函數(shù)調(diào)用:Spawn_Init_Process(void)。5)“src/GeekOS/kthread.c”文件中的St111、

GeekOS進程狀態(tài)及轉(zhuǎn)換

三、項目設計提示currentrunwait出現(xiàn)需要等待的事件等待的事件發(fā)生調(diào)度時間片到等圖5.1GeekOS進程狀態(tài)轉(zhuǎn)換GeekOS系統(tǒng)最早創(chuàng)建的內(nèi)核進程有Idle、Reaper和Main三個進程,它們由Init_Scheduler函數(shù)創(chuàng)建:最先初始化一個核態(tài)進程mainThread,并將該進程作為當前運行進程,函數(shù)最后還調(diào)用Start_Kernel_Thread函數(shù)創(chuàng)建了兩個系統(tǒng)進程Idle和Reaper。所以,Idle、Reaper和Main三個進程是系統(tǒng)中最早存在的進程。新建1、GeekOS進程狀態(tài)及轉(zhuǎn)換三、項目設計提示curre12GeekOS的內(nèi)核進程對象

include/kthread.h中定義,具體結(jié)構(gòu)如下:structKernel_Thread{ulong_tesp; //進程的內(nèi)核堆棧esp指針volatileulong_tnumTicks; //計時器intpriority; //進程優(yōu)先級DEFINE_LINK(Thread_Queue,Kernel_Thread);//指針指向進程隊列下一進程void*stackPage; //內(nèi)核堆棧頁指針structUser_Context*userContext;//用戶進程上下文structKernel_Thread*owner; //父進程指針intrefCount; //引用計數(shù)boolalive; //是否活躍structThread_QueuejoinQueue; //加入隊列intexitCode; //返回代碼intpid; //進程IDDEFINE_LINK(All_Thread_List,Kernel_Thread);//全局進程鏈表指針#defineMAX_TLOCAL_KEYS128constvoid*tlocalData[MAX_TLOCAL_KEYS]; //本地信息intcurrentReadyQueue; //進程當前所在的運行隊列的索引編號boolblocked; //是否被阻塞};GeekOS的內(nèi)核進程對象include/kt132、GeekOS的用戶態(tài)進程

在GeekOS中為了區(qū)分用戶態(tài)進程和內(nèi)核進程,在Kernel_Thread結(jié)構(gòu)體中設置了一個字段userContext,指向用戶態(tài)進程上下文。對于內(nèi)核進程來說,這個指針為空,而用戶態(tài)進程都擁有自己的用戶上下文(User_Context)。因此,在GeekOS中要判斷一個進程是內(nèi)核進程還是用戶態(tài)進程,只要通過userContext字段是否為空來判斷就可以了。圖10.1用戶態(tài)進程結(jié)構(gòu)2、GeekOS的用戶態(tài)進程在GeekOS中為14User_Context結(jié)構(gòu)結(jié)構(gòu)定義如下(在“include/geekos/user.h”中定義):

structUser_Context{

#defineNUM_USER_LDT_ENTRIES3

structSegment_Descriptorldt[NUM_USER_LDT_ENTRIES];//用戶LDT

structSegment_Descriptor*ldtDescriptor;//LDT描述符

char*memory;//指向用戶空間

ulong_tsize;//用戶空間的大小

ushort_tldtSelector;//ldt選擇子

ushort_tcsSelector;//cs選擇子

ushort_tssSelector;//ss選擇子

ushort_tdsSelector;//ds選擇子

pde_t*pageDir; //頁表指針

ulong_tentryAddr; //用戶程序入口地址

ulong_targBlockAddr; //參數(shù)塊地址

ulong_tstackPointerAddr;//用戶態(tài)進程的堆棧指針

intrefCount; //引用數(shù)

structFile*fileList[USER_MAX_FILES];//打開文件列表

intfileCount; //打開文件計數(shù)

};User_Context結(jié)構(gòu)結(jié)構(gòu)定義如下(在“include154、用戶態(tài)進程空間

每個用戶態(tài)進程都擁有屬于自己的內(nèi)存段空間,如:代碼段、數(shù)據(jù)段、堆棧段等,每個段有一個段描述符(segmentdescriptor),并且每個進程有一個段描述符表(LocalDescriptorTable),用于保存該進程的所有段描述符。操作系統(tǒng)中還設置一個全局描述符表(GDT,GlobalDescriptorTable),用于記錄了系統(tǒng)中所有進程的ldt描述符。圖10.2GDT、LDT和User_Context的關(guān)系4、用戶態(tài)進程空間每個用戶態(tài)進程都擁有屬于自16(1)調(diào)用函數(shù)Allocate_Segment_Descriptor()新建一個LDT描述符;(2)調(diào)用函數(shù)Selector()新建一個LDT選擇子;(3)調(diào)用函數(shù)Init_Code_Segment_Descriptor()新建一個文本段描述符;(4)調(diào)用函數(shù)Init_Data_Segment_Descriptor()新建一個數(shù)據(jù)段;(5)調(diào)用函數(shù)Selector()新建一個數(shù)據(jù)段選擇子;(6)調(diào)用函數(shù)Selector()新建一個文本(可執(zhí)行代碼)段選擇子。5、用戶態(tài)進程創(chuàng)建LDT的步驟

(1)調(diào)用函數(shù)Allocate_Segment_Descri173、用戶態(tài)進程創(chuàng)建流程Spawn()Read_Fully()Parse_ELF_Excutable()Start_User_Thread()Setup_User_Thread()Load_User_Program()Attach_User_Context()3、用戶態(tài)進程創(chuàng)建流程Spawn()Read_Fully184、Spawn函數(shù)的功能intSpawn(constchar*program,constchar*command,structKernel_Thread**pThread)參數(shù)說明:Program對應的是要讀入內(nèi)存緩沖區(qū)的可執(zhí)行文件,Command是用戶執(zhí)行程序執(zhí)行時的命令行字符串,pThread是存放指向剛創(chuàng)建進程的指針。Spawn函數(shù)主要完成的主要功能是:(1)調(diào)用Read_Fully函數(shù)將名為program的可執(zhí)行文件全部讀入內(nèi)存緩沖區(qū)。(2)調(diào)用Parse_ELF_Executable函數(shù),分析ELF格式文件。Parse_ELF_Executable函數(shù)功能在項目1中已經(jīng)實現(xiàn)。(3)調(diào)用Load_User_Program將可執(zhí)行程序的程序段和數(shù)據(jù)段等裝入內(nèi)存,初始化User_context數(shù)據(jù)結(jié)構(gòu)。(4)調(diào)用Start_User_Thread函數(shù)創(chuàng)建一個進程并使該進程進入準備運行隊列。4、Spawn函數(shù)的功能intSpawn(constch195、Load_User_Program函數(shù)Load_User_Program函數(shù)在“/src/geekos/userseg.c”文件中實現(xiàn),代碼也需要開發(fā)人員自己完成,函數(shù)原型如下:intLoad_User_Program(char*exeFileData,ulong_texeFileLength,structExe_Format*exeFormat,constchar*command,structUser_Context**pUserContext)/*參數(shù)說明:exeFileData——保存在內(nèi)存緩沖中的用戶程序可執(zhí)行文件;exeFileLength——可執(zhí)行文件的長度;exeFormat——調(diào)用Parse_ELF_Executable函數(shù)得到的可執(zhí)行文件格式信息;command——用戶輸入的命令行,包括可執(zhí)行文件的名稱及其他參數(shù);pUserContext——指向User_Conetxt的指針,是本函數(shù)完成用戶上下文初始化的對象*/5、Load_User_Program函數(shù)Load_Use20Load_User_Program主要實現(xiàn)功能如下:(1)根據(jù)Parse_ELF_Executable函數(shù)的執(zhí)行結(jié)果Exe_Format中的Exe_Segment結(jié)構(gòu)提供的用戶程序段信息,用戶命令參數(shù)及用戶態(tài)進程堆棧大小計算用戶態(tài)進程所需的最大內(nèi)存空間,即要分配給用戶態(tài)進程的內(nèi)存空間。(2)為用戶程序分配內(nèi)存空間,并初始化。(3)根據(jù)Exe_Segment提供的用戶段信息初始化代碼段、數(shù)據(jù)段以及堆棧段的段描述符和段選擇子。(4)根據(jù)段信息將用戶程序中的各段內(nèi)容復制到分配的用戶內(nèi)存空間。(5)根據(jù)Exe_Format結(jié)構(gòu)初始化User_Context結(jié)構(gòu)中的用戶態(tài)進程代碼段入口entry字段,并根據(jù)command參數(shù)初始化用戶內(nèi)存空間中的參數(shù)塊。(6)初始化User_Context結(jié)構(gòu)的用戶打開文件列表,并添加標準輸入輸出文件。(7)將初始化完畢的User_Context指針賦予*pUserContext,返回0表示成功。Load_User_Program主要實現(xiàn)功能如下:21一、項目設計目的研究進程調(diào)度算法,掌握用信號量實現(xiàn)進程間同步的方法。為GeekOS擴充進程調(diào)度算法——基于時間片輪轉(zhuǎn)的進程多級反饋調(diào)度算法,并能用信號量實現(xiàn)進程協(xié)作。二、項目設計要求(1)實現(xiàn)src/geekos/syscall.c文件中的Sys_SetSchedulingPolicy系統(tǒng)調(diào)用,它的功能是設置系統(tǒng)采用的何種進程調(diào)度策略;(2)實現(xiàn)src/geekos/syscall.c文件中的Sys_GetTimeOfDay系統(tǒng)調(diào)用,它的功能是獲取全局變量g_numTicks的值;(3)實現(xiàn)函數(shù)Change_Scheduling_Policy(),具體實現(xiàn)不同調(diào)度算法的轉(zhuǎn)換。(4)實現(xiàn)syscall.c中信號量有關(guān)的四個系統(tǒng)調(diào)用:sys_createsemaphore()、sys_P()、sys_V()和sys_destroysemaphore()。第11章設計項目3

一、項目設計目的第11章設計項目3221、多級反饋隊列調(diào)度隊列模型三、項目設計提示1、多級反饋隊列調(diào)度隊列模型三、項目設計提示232、多級反饋隊列與分時調(diào)度進程隊列的轉(zhuǎn)換

2、多級反饋隊列與分時調(diào)度進程隊列的轉(zhuǎn)換24(1)添加函數(shù)Chang_Scheduling_Policy(intpolicy,intquantum),policy是設置的調(diào)度策略,quantum是設置的時間片。例如policy為1說明設置的是多級反饋隊列調(diào)度算法,此時若g_SchedPolicy(為系統(tǒng)添加的標識算法的變量,初始化為0)為0,說明當前的調(diào)度算法為輪轉(zhuǎn)調(diào)度,要變成MLF就必須把空閑線程放入3隊列,若g_SchedPolicy為1,說明當前是多級反饋隊列調(diào)度算法,則返回。如果policy為0,則說明設置的是輪轉(zhuǎn)調(diào)度,此時若g_SchedPolicy為1,則必須把4個隊列變成一個隊列,即所有的線程都在隊列0上了。若g_SchedPolicy為0,則返回。3、函數(shù)設計提示(1)添加函數(shù)Chang_Scheduling_Policy25(2)在系統(tǒng)調(diào)用Sys_GetTimeOfDay()中,只需要返回g_numTicks就可以了。在Sys_SetSchedulingPolicy()中,如果state->ebx是1,則設置的是MLF算法,調(diào)用Change_Scheduling_Policy(SCHED_RR,quantum),為0則是RR算法,調(diào)用Change_Scheduling_Policy(SCHED_MLF,quantum)。如果state->ebx為其他值,則返回-1。(3)在Init_Thread()中都是把隊列放在0隊列上的,并且blocked變量為false。(4)在Get_Next_Runnable()中,從最高級的隊列開始,調(diào)用Find_Best()來找線程優(yōu)先級最大的線程,直到在某級隊列中找到符合條件可以運行的線程。(5)在Wait()函數(shù)中,線程被阻塞,所以blocked變量被設置為true,并且如果是MLF算法,則該進程的currentReadyQueue加一,下次運行的時候進入高一級的線程隊列。(2)在系統(tǒng)調(diào)用Sys_GetTimeOfDay()中,只需26GveekOS定義了信號量的結(jié)構(gòu)體:structSemaphore{intsemaphoreID;/*信號量的ID*/char*semaphoreName;/*信號量的名字*/intvalue;/*信號量的值*/intregisteredThreadCount;/*注冊該信號量的線程數(shù)量*/structKernel_Thread*registeredThreads[MAX_REGISTERED_THREADS];/*注冊的線程*/structThread_QueuewaitingThreads;/*等待該信號的線程隊列*/DEFINE_LINK(Semaphore_List,Semaphore);/*連接信號鏈表的域*/}4、信號量定義

GveekOS定義了信號量的結(jié)構(gòu)體:4、信號量定義27信號量操作:Semaphore_Create()Semaphore_Acquire(P操作)Semaphore_Release(V操作)Semaphore_Destroy()Create_Semaphore()函數(shù)首先檢查請求創(chuàng)建的這個信號量的名字是否存在,如果存在,那么就把這個線程加入到這個信號量所注冊的線程鏈表上;如果不存在,則分配內(nèi)存給新的信號量,清空它的線程隊列,把當前的這個線程加入到它的線程隊列中,設置注冊線程數(shù)量為1,初始化信號量的名字,值和信號量的ID,并把這個信號量添加到信號量鏈表上,最后返回信號量的ID。5、信號量PV操作

信號量操作:5、信號量PV操作28P操作Semaphore_Acquire()中,首先檢查傳入的信號量ID是否存在,如果存在,接著檢查當前線程是否注冊使用了這個信號量,如果這兩項檢查任意一項失敗了,那么就返回-1。如果成功了,就把信號量的值減去1,如果減去1后信號量的值小于0,那么就把當前線程放入這個信號量的等待隊列上。V操作Semaphore_Release()中,首先也是檢查傳入的信號量ID是否存在,如果存在,接著檢查當前線程是否注冊使用了這個信號量,如果這兩項檢查任意一項失敗了,那么就返回-1。如果成功了,那就把信號量的值加上1,如果加上1后信號量的值小于或等于0,則要把該信號量里等待隊列上的一個線程喚醒。Semaphore_Destroy()中,首先也是檢查傳入的信號量ID是否存在,如果存在,接著檢查當前線程是否注冊使用了這個信號量,如果這兩項檢查任意一項失敗了,那么就返回-1。如果成功了,就把該線程從這個信號量的注冊的線程數(shù)組中刪除,并把注冊的線程數(shù)量減去1。如果這個信號量的注冊線程為0了,則把這個信號量從信號量鏈表中刪除,并釋放它的內(nèi)存。P操作Semaphore_Acquire()中,首先檢查傳入29第12章設計項目4

一、項目設計目的了解虛擬存儲器管理設計原理,掌握請求分頁虛擬存儲管理的具體實現(xiàn)技術(shù)。二、項目設計要求(1)在<src/geekos/paging.c>文件中編寫代碼完成以下函數(shù):Init_VM()(definedin)函數(shù)將建立一個初始的內(nèi)存頁目錄和頁表,并且安裝一個頁面出錯處理函數(shù)。Init_Paging()函數(shù)(定義在src/geekos/paging.c)初始化操作頁面調(diào)度文件所需的所有數(shù)據(jù)結(jié)構(gòu)。就如前面說到的,Get_Paging_Device()函數(shù)指定分頁調(diào)度文件定位在哪一個設備和占用磁盤塊的地址范圍。Find_Space_On_Paging_File()函數(shù)應該在分頁調(diào)度文件里面找到一個空閑的足夠大的頁空間。它將返回這個大塊的索引,或者當沒有合適的空間就返回-1。第12章設計項目4一、項目設計目的30Free_Space_On_Paging_File()函數(shù)將釋放由Find_Space_On_Paging_File()函數(shù)在分頁調(diào)度文件里所分配的的磁盤塊。Write_To_Paging_File()函數(shù)將把存儲在內(nèi)存的一頁數(shù)據(jù)寫出到分頁調(diào)度文件里。Read_From_Paging_File()函數(shù)將讀取分頁調(diào)度文件里的一頁數(shù)據(jù)到內(nèi)存空間。(2)在<src/geekos/uservm.c>文件中編寫代碼完成以下函數(shù):Destroy_User_Context()釋放進程所占用的所有內(nèi)存和其它資源。Load_User_Program()裝載可執(zhí)行文件到內(nèi)存里,創(chuàng)建一個就緒的用戶地址空間,功能類似于分段系統(tǒng)的實現(xiàn)。Copy_From_User()從一個用戶緩沖區(qū)復制數(shù)據(jù)到一個內(nèi)核緩沖區(qū)。Copy_To_User()從一個內(nèi)核緩沖區(qū)復制數(shù)據(jù)到一個用戶緩沖區(qū)。Switch_To_Address_Space()利用它裝載相應頁目錄和LDT來切換到一個用戶地址空間。Free_Space_On_Paging_File()函數(shù)將311、地址轉(zhuǎn)換三、項目設計提示

1、地址轉(zhuǎn)換三、項目設計提示32GeekOS操作系統(tǒng)課程設計項目介紹33線性地址到物理地址的轉(zhuǎn)換過程線性地址到物理地址的轉(zhuǎn)換過程342、用戶進程的線性地址空間2、用戶進程的線性地址空間353、請求分頁系統(tǒng)實現(xiàn)操作系統(tǒng)將需要在磁盤設備上創(chuàng)建一個pagefile文件暫時保存從內(nèi)存中替換出去的頁,實現(xiàn)一個類LRU算法在內(nèi)存中選取一個替換頁把它寫到磁盤的pagefile文件中。缺頁中斷處理

表12-1缺頁處理表缺頁情況標識相應處理堆棧生長到新頁超出原來分配一頁的限制分配一個新頁進程繼續(xù)此頁保存在磁盤上數(shù)據(jù)標識這一頁在pagefile中存在從pagefile讀入需要的頁繼續(xù)因為無效地址缺頁非法地址訪問終止用戶進程3、請求分頁系統(tǒng)實現(xiàn)操作系統(tǒng)將需要在磁盤設備上創(chuàng)建一個pag36在“/src/geekos/mem.c”文件中,已經(jīng)定義了一個函數(shù)Alloc_Pageable_Page實現(xiàn)交換一頁到磁盤的操作,具體執(zhí)行步驟如下:調(diào)用mem.c文件中已經(jīng)實現(xiàn)的Find_Page_To_Page_Out函數(shù)來確定要替換的頁(這個函數(shù)依賴于頁數(shù)據(jù)結(jié)構(gòu)中的clock域)。調(diào)用paging.c文件中已經(jīng)實現(xiàn)的Find_Space_On_Paging_File函數(shù)在pagefile中找到空閑的存儲空間。調(diào)用paging.c文件中已經(jīng)實現(xiàn)的Write_To_Paging_File函數(shù)把被替換的頁寫到pagefile文件中。修改頁表的相應表項,清除頁存在的標志,標識為此頁在內(nèi)存為不存在。修改頁表項的頁基地址為包含這一頁的第一個磁盤塊號。修改頁表項的kernelInfo位標識為KINFO_PAGE_ON_DISK狀態(tài)(標識這一頁是在磁盤上存在,而不是沒有效)。調(diào)用lowlevel.asm文件中已經(jīng)實現(xiàn)的Flush_TLB來刷新TLB。在“/src/geekos/mem.c”文件中,已經(jīng)定義了一37第13章設計項目5

一、項目設計目的了解文件系統(tǒng)的設計原理。掌握操作系統(tǒng)文件系統(tǒng)的具體實現(xiàn)技術(shù)。二、項目設計要求(1)為實現(xiàn)GOSFS文件系統(tǒng),用戶在“/src/geeekos/gosfs.c”中添加代碼,實現(xiàn)以下函數(shù)。GOSFS_Fstat()函數(shù):為給定的文件得到元數(shù)據(jù)。GOSFS_Read()函數(shù):從給定文件的當前位置讀數(shù)據(jù)。GOSFS_Write()函數(shù):從給定文件的當前位置寫數(shù)據(jù)。GOSFS_Seek()函數(shù):在給定文件中定位。GOSFS_Close()函數(shù):關(guān)閉給定文件。

第13章設計項目5一、項目設計目的38項目設計要求

GOSFS_Fstat_Directory()函數(shù):為一個打開的目錄得到元數(shù)據(jù)。GOSFS_Close_Directory()函數(shù):關(guān)閉給定目錄。GOSFS_Read_Entry()函數(shù):從打開的目錄表讀一個目錄項。GOSFS_Open()函數(shù):為給定的路徑名打開一個文件。GOSFS_Create_Directory()函數(shù):為給定的路徑創(chuàng)建一個目錄。GOSFS_Open_Directory()函數(shù):為給定的路徑打開一個目錄。GOSFS_Delete()函數(shù):為給定的路徑名刪除一個文件。GOSFS_stat()函數(shù):為給定的路徑得到元數(shù)據(jù)(大小,權(quán)限等信息)。GOSFS_Sync()函數(shù):對磁盤上的文件系統(tǒng)數(shù)據(jù)實現(xiàn)同步操作。GOSFS_Format()函數(shù):格式化GOSFS文件系統(tǒng)操作。GOSFS_Mount()函數(shù):掛載文件系統(tǒng)操作。

項目設計要求GOSFS_Fstat_Directory391、

GeekOS文件系統(tǒng)框架

三、項目設計提示1、GeekOS文件系統(tǒng)框架三、項目設計提示402、GOSFS讀文件處理流程

用戶進程調(diào)用C語言庫函數(shù)Read函數(shù)軟件中斷,內(nèi)核調(diào)用Sys_Read()函數(shù)虛擬文件系統(tǒng)層的Read()函數(shù)讀出文件的數(shù)據(jù)Sys_Read()函數(shù)將數(shù)據(jù)拷貝到用戶緩沖區(qū)GOSFS讀文件過程※系統(tǒng)已經(jīng)實現(xiàn)PFAT文件系統(tǒng),用戶要實現(xiàn)的是GOSFS文件系統(tǒng),可依照PFAT文件的實現(xiàn)原理2、GOSFS讀文件處理流程用戶進程調(diào)用軟件中斷,內(nèi)核調(diào)用41User_Context結(jié)構(gòu)結(jié)構(gòu)定義如下(在“include/geekos/user.h”中定義):

structUser_Context{

#defineNUM_USER_LDT_ENTRIES3

structSegment_Descriptorldt[NUM_USER_LDT_ENTRIES];//用戶LDT

structSegment_Descriptor*ldtDescriptor;//LDT描述符

char*memory;//指向用戶空間

ulong_tsize;//用戶空間的大小

ushort_tldtSelector;//ldt選擇子

ushort_tcsSelector;//cs選擇子

ushort_tssSelector;//ss選擇子

ushort_tdsSelector;//ds選擇子

pde_t*pageDir; //頁表指針

ulong_tentryAddr; //用戶程序入口地址

ulong_targBlockAddr; //參數(shù)塊地址

ulong_tstackPointerAddr;//用戶態(tài)進程的堆棧指針

intrefCount; //引用數(shù)

structFile*fileList[USER_MAX_FILES];//打開文件列表

intfileCount; //打開文件計數(shù)

};2、GOSFS文件系統(tǒng)結(jié)構(gòu)

User_Context結(jié)構(gòu)結(jié)構(gòu)定義如下(在“include42(1)磁盤邏輯結(jié)構(gòu)2、GOSFS文件系統(tǒng)結(jié)構(gòu)

(1)磁盤邏輯結(jié)構(gòu)2、GOSFS文件系統(tǒng)結(jié)構(gòu)43MAX_FILES_PER_DIRGOSFS_Dir_Entryfilename[128]flagssizeacl[10]blockList[10]目錄項GOSFS_Dir_EntryGOSFS_Dir_EntryGOSFS_Dir_EntryGOSFS_Dir_EntryGOSFS_Dir_EntryGOSFS_Dir_EntryGOSFS_Dir_Entry目錄塊文件目錄

數(shù)據(jù)塊數(shù)據(jù)塊MAX_FILES_PER_DIRGOSFS_Dir_En44數(shù)據(jù)存儲分配–直接映射01234567894KBdatablockGOSFS_Dir_Entry.blockList[10]4KBdatablock4KBdatablock磁盤=已分配12KB大小的文件數(shù)據(jù)存儲分配–直接映射01234567894KBdata454KBdatablock4KBdatablock4KBdatablock磁盤0123456789001234...1022102304KBdatablock4KBdatablock40KB大小的文件一級間接索引塊….GOSFS_Dir_Entry.blockList[10]數(shù)據(jù)存儲分配–一級間接映射4KBdatablock4KBdatablock4K464KBdatablock4KBdatablock4KBdatablock磁盤012345678904KBdatablock4KBdatablock4136KB大小的文件1022102301234...0一級索引塊….1022102301234...01022102301234...0一級索引塊二級索引塊GOSFS_Dir_Entry.blockList[10]數(shù)據(jù)存儲分配–二級間接映射4KBdatablock4KBdatablock4K47[0,32KB]–僅僅使用直接映射方法(32KB,4128KB]–使用直接映射方法+一級間接索引塊方法(4128KB,32MB]–使用直接映射方法+一級間接索引塊方法+二級間接索引塊方法數(shù)據(jù)存儲空間分配總結(jié)[0,32KB]–僅僅使用直接映射方法數(shù)據(jù)存儲空間分配總484、GOSFS的操作

(1)FORMAT格式化操作SYS_FORMATFormat(char*dev,char*fstype)初始化磁盤格式,即各系統(tǒng)數(shù)據(jù)初始化Format操作完成文件系統(tǒng)的格式化操作。在系統(tǒng)編譯時GeekOS會自動生成10兆大小的磁盤鏡像,并初始化內(nèi)容為全零。GOSFS_Format將這種原始磁盤格式化為GOSFS格式的磁盤,操作包括寫入引導塊,文件系統(tǒng)初始超級塊以及根目錄信息節(jié)點。只是針對GOSFS,不能格式化PFAT4、GOSFS的操作(1)FORMAT格式化操作SYS49(2)掛載GOSFSSYS_MOUNTvsf.c:Mount(char*devname,char*pathPrefix,char*fstype)gosfs.c:GOSFS_Mount(structMount_Point*mountPoint)GOSFS_Mount操作負責將一塊GOSFS格式的磁盤掛載到GeekOS。這個操作必須在磁盤訪問操作進行之前完成。掛載操作首先初始化內(nèi)存中的實體超級塊,之后初始化虛擬超級塊,最后初始化GOSFS根目錄“d”。掛載操作成功完成后,文件系統(tǒng)就可以訪問超級塊與文件系統(tǒng)根目錄,并完成相應操作。(2)掛載GOSFSSYS_MOUNT505、高速緩沖區(qū)思想:保留一些磁盤數(shù)據(jù)塊在內(nèi)存中(buffers);內(nèi)存中的數(shù)據(jù)讀寫比磁盤中讀寫數(shù)據(jù)要快得多。緩沖區(qū)使用過程申請–修改–釋放bufcache.cCreate_FS_Buffer_Cache(structBlock_Device*dev,…)Get_FS_Buffer()Modify_FS_Buffer()Sync_FS_Buffer()Release_FS_Buffer()5、高速緩沖區(qū)思想:保留一些磁盤數(shù)據(jù)塊在內(nèi)存中(buff51一、項目設計目的熟悉GeekOS的項目編譯、調(diào)試和運行環(huán)境,掌握GeekOS運行工作過程。二、項目設計要求1、搭建GeekOS的編譯和調(diào)試平臺,掌握GeekOS的內(nèi)核進程工作原理。2、熟悉鍵盤操作函數(shù),編程實現(xiàn)一個內(nèi)核進程。該進程的功能是:接收鍵盤輸入的字符并顯示到屏幕上,當輸入ctrl+d時,結(jié)束進程的運行。第八章設計項目0

一、項目設計目的第八章設計項目052三、項目0的實現(xiàn)主要由以下步驟完成(在項目0的/src/geekos/main.c中完成):編寫一個C語言函數(shù),函數(shù)功能是:接收鍵盤輸入的按鍵,并將鍵值在顯示器顯示出來,當輸入ctrl+d就退出;在Main函數(shù)體內(nèi)調(diào)用Start_Kernel_Thread函數(shù),將步驟1編寫的函數(shù)地址傳遞給參數(shù)startFunc,利用Setup_Kernel_Thread函數(shù)建立一個待運行的線程。

在Linux環(huán)境下編譯系統(tǒng)得到GeekOS鏡像文件。編寫一個相應的bochs配置文件。在bochs中運行GeekOS系統(tǒng)顯示結(jié)果。三、項目0的實現(xiàn)主要由以下步驟完成(在項目0的/src/ge53第九章設計項目1

一、項目設計目的熟悉ELF文件格式,了解GeekOS系統(tǒng)如何將ELF格式的可執(zhí)行程序裝入到內(nèi)存,建立內(nèi)核進程并運行的實現(xiàn)技術(shù)。二、項目設計要求1、修改/geekos/elf.c文件:在函數(shù)Parse_ELF_Executable()中添加代碼,分析ELF格式的可執(zhí)行文件(包括分析得出ELF文件頭、程序頭,獲取可執(zhí)行文件長度,代碼段、數(shù)據(jù)段等信息),并填充Exe_Format數(shù)據(jù)結(jié)構(gòu)中的域值。2、在Linux環(huán)境下編譯系統(tǒng)得到GeekOS鏡像文件。3、編寫一個相應的bochs配置文件。4、在bochs中運行GeekOS系統(tǒng)顯示結(jié)果。第九章設計項目1一、項目設計目的541、ELF文件格式

三、項目設計提示表1ELF目標文件格式連接程序視圖

執(zhí)行程序視圖

ELF頭部ELF頭部程序頭部表(可選)程序頭部表節(jié)區(qū)1段1...節(jié)區(qū)n段2.........節(jié)區(qū)頭部表節(jié)區(qū)頭部表(可選)1、ELF文件格式三、項目設計提示表1ELF目標文件格式552、內(nèi)存中的可執(zhí)行文件鏡像

2、內(nèi)存中的可執(zhí)行文件鏡像563、內(nèi)核線程的建立流程Spawn_Init_Process()Start_Kernel_Thread()Spawner()Read_Fully()Parse_ELF_Excutable()Spawn_Program()3、內(nèi)核線程的建立流程Spawn_Init_Process(57根據(jù)Exe_Format中的Exe_Segment結(jié)構(gòu)提供的用戶程序段信息,及用戶進程堆棧大小計算用戶進程所需的最大內(nèi)存空間,即要分配給用戶進程的內(nèi)存空間;為用戶程序分配內(nèi)存空間,并全部初始化為零,否則系統(tǒng)后面運行可能出錯;根據(jù)段信息將用戶程序中的各段內(nèi)容復制到分配的用戶內(nèi)存空間。根據(jù)Exe_Segment提供的用戶段信息初始化代碼段、數(shù)據(jù)段以及堆棧段的段描述符和段選擇子。

4、Spawn_Program函數(shù)的功能根據(jù)Exe_Format中的Exe_Segment結(jié)構(gòu)提供的58intParse_ELF_Executable(char*exeFileData,ulong_texeFileLength,structExe_Format*exeFormat)參數(shù):exeFileData——已裝入內(nèi)存的可執(zhí)行文件所占用空間的起始地址exeFileLength——可執(zhí)行文件長度exeFormat——保存分析得到的elf文件信息的結(jié)構(gòu)體指針根據(jù)ELF文件格式,用戶可以從exeFileData指向的內(nèi)容中得到ELF文件頭,繼續(xù)分析可以得到程序頭,程序代碼段等信息。5、Parse_ELF_Excutable函數(shù)intParse_ELF_Executable(char59第十章設計項目2

一、項目設計目的擴充GeekOS操作系統(tǒng)內(nèi)核,使得系統(tǒng)能夠支持用戶級進程的動態(tài)創(chuàng)建和執(zhí)行。二、項目2要求用戶對以下幾個文件進行修改:1)“src/GeekOS/user.c”文件中的函數(shù)Spawn(),其功能是生成一個新的用戶級進程;2)“src/GeekOS/user.c”文件中的函數(shù)Switch_To_User_Context(),調(diào)度程序在執(zhí)行一個新的進程前調(diào)用該函數(shù)以切換用戶地址空間;

3)“src/GeekOS/elf.c”文件中的函數(shù)Parse_ELF_Executable()。該函數(shù)的實現(xiàn)要求和項目1相同。第十章設計項目2一、項目設計目的604)“src/GeekOS/userseg.c”文件中主要是實現(xiàn)一些為實現(xiàn)對“src/GeekOS/user.c”中高層操作支持的函數(shù)。

Destroy_User_Context()函數(shù)的功能是釋放用戶態(tài)進程占用的內(nèi)存資源。

Load_User_Program()函數(shù)的功能通過加載可執(zhí)行文件鏡像創(chuàng)建新進程的User_Context結(jié)構(gòu)。

Copy_From_User()和Copy_To_User()函數(shù)的功能是在用戶地址空間和內(nèi)核地址空間之間復制數(shù)據(jù),在分段存儲器管理模式下,只要段有效,調(diào)用memcpy函數(shù)就可以實現(xiàn)這兩個函數(shù)的功能。

Switch_To_Address_Space()函數(shù)的功能是通過將進程的LDT裝入到LDT寄存器來激活用戶的地址空間;GeekOS操作系統(tǒng)課程設計項目介紹615)“src/GeekOS/kthread.c”文件中的Start_User_Thread函數(shù)和Setup_User_Thread函數(shù)。Setup_User_Thread()函數(shù)的功能是為進程初始化內(nèi)核堆棧,堆棧中是為進程首次進入用戶態(tài)運行時設置處理器狀態(tài)要使用的數(shù)據(jù)。Start_User_Thread()是一個高層操作,該函數(shù)使用User_Context對象開始一個新進程。6)“src/GeekOS/kthread.c”文件中主要是實現(xiàn)用戶程序要求內(nèi)核進行服務的一些系統(tǒng)調(diào)用函數(shù)定義。要求用戶實現(xiàn)的有Sys_Exit()函數(shù)、Sys_PrintString()函數(shù)、Sys_GetKey()、Sys_SetAttr()、Sys_GetCursor()、Sys_PutCursor()、Sys_Spawn()函數(shù)、Sys_Wait()函數(shù)和Sys_GetPID()函數(shù)。7)在main.c文件中改寫生成第一個用戶態(tài)進程的函數(shù)調(diào)用:Spawn_Init_Process(void)。5)“src/GeekOS/kthread.c”文件中的St621、

GeekOS進程狀態(tài)及轉(zhuǎn)換

三、項目設計提示currentrunwait出現(xiàn)需要等待的事件等待的事件發(fā)生調(diào)度時間片到等圖5.1GeekOS進程狀態(tài)轉(zhuǎn)換GeekOS系統(tǒng)最早創(chuàng)建的內(nèi)核進程有Idle、Reaper和Main三個進程,它們由Init_Scheduler函數(shù)創(chuàng)建:最先初始化一個核態(tài)進程mainThread,并將該進程作為當前運行進程,函數(shù)最后還調(diào)用Start_Kernel_Thread函數(shù)創(chuàng)建了兩個系統(tǒng)進程Idle和Reaper。所以,Idle、Reaper和Main三個進程是系統(tǒng)中最早存在的進程。新建1、GeekOS進程狀態(tài)及轉(zhuǎn)換三、項目設計提示curre63GeekOS的內(nèi)核進程對象

include/kthread.h中定義,具體結(jié)構(gòu)如下:structKernel_Thread{ulong_tesp; //進程的內(nèi)核堆棧esp指針volatileulong_tnumTicks; //計時器intpriority; //進程優(yōu)先級DEFINE_LINK(Thread_Queue,Kernel_Thread);//指針指向進程隊列下一進程void*stackPage; //內(nèi)核堆棧頁指針structUser_Context*userContext;//用戶進程上下文structKernel_Thread*owner; //父進程指針intrefCount; //引用計數(shù)boolalive; //是否活躍structThread_QueuejoinQueue; //加入隊列intexitCode; //返回代碼intpid; //進程IDDEFINE_LINK(All_Thread_List,Kernel_Thread);//全局進程鏈表指針#defineMAX_TLOCAL_KEYS128constvoid*tlocalData[MAX_TLOCAL_KEYS]; //本地信息intcurrentReadyQueue; //進程當前所在的運行隊列的索引編號boolblocked; //是否被阻塞};GeekOS的內(nèi)核進程對象include/kt642、GeekOS的用戶態(tài)進程

在GeekOS中為了區(qū)分用戶態(tài)進程和內(nèi)核進程,在Kernel_Thread結(jié)構(gòu)體中設置了一個字段userContext,指向用戶態(tài)進程上下文。對于內(nèi)核進程來說,這個指針為空,而用戶態(tài)進程都擁有自己的用戶上下文(User_Context)。因此,在GeekOS中要判斷一個進程是內(nèi)核進程還是用戶態(tài)進程,只要通過userContext字段是否為空來判斷就可以了。圖10.1用戶態(tài)進程結(jié)構(gòu)2、GeekOS的用戶態(tài)進程在GeekOS中為65User_Context結(jié)構(gòu)結(jié)構(gòu)定義如下(在“include/geekos/user.h”中定義):

structUser_Context{

#defineNUM_USER_LDT_ENTRIES3

structSegment_Descriptorldt[NUM_USER_LDT_ENTRIES];//用戶LDT

structSegment_Descriptor*ldtDescriptor;//LDT描述符

char*memory;//指向用戶空間

ulong_tsize;//用戶空間的大小

ushort_tldtSelector;//ldt選擇子

ushort_tcsSelector;//cs選擇子

ushort_tssSelector;//ss選擇子

ushort_tdsSelector;//ds選擇子

pde_t*pageDir; //頁表指針

ulong_tentryAddr; //用戶程序入口地址

ulong_targBlockAddr; //參數(shù)塊地址

ulong_tstackPointerAddr;//用戶態(tài)進程的堆棧指針

intrefCount; //引用數(shù)

structFile*fileList[USER_MAX_FILES];//打開文件列表

intfileCount; //打開文件計數(shù)

};User_Context結(jié)構(gòu)結(jié)構(gòu)定義如下(在“include664、用戶態(tài)進程空間

每個用戶態(tài)進程都擁有屬于自己的內(nèi)存段空間,如:代碼段、數(shù)據(jù)段、堆棧段等,每個段有一個段描述符(segmentdescriptor),并且每個進程有一個段描述符表(LocalDescriptorTable),用于保存該進程的所有段描述符。操作系統(tǒng)中還設置一個全局描述符表(GDT,GlobalDescriptorTable),用于記錄了系統(tǒng)中所有進程的ldt描述符。圖10.2GDT、LDT和User_Context的關(guān)系4、用戶態(tài)進程空間每個用戶態(tài)進程都擁有屬于自67(1)調(diào)用函數(shù)Allocate_Segment_Descriptor()新建一個LDT描述符;(2)調(diào)用函數(shù)Selector()新建一個LDT選擇子;(3)調(diào)用函數(shù)Init_Code_Segment_Descriptor()新建一個文本段描述符;(4)調(diào)用函數(shù)Init_Data_Segment_Descriptor()新建一個數(shù)據(jù)段;(5)調(diào)用函數(shù)Selector()新建一個數(shù)據(jù)段選擇子;(6)調(diào)用函數(shù)Selector()新建一個文本(可執(zhí)行代碼)段選擇子。5、用戶態(tài)進程創(chuàng)建LDT的步驟

(1)調(diào)用函數(shù)Allocate_Segment_Descri683、用戶態(tài)進程創(chuàng)建流程Spawn()Read_Fully()Parse_ELF_Excutable()Start_User_Thread()Setup_User_Thread()Load_User_Program()Attach_User_Context()3、用戶態(tài)進程創(chuàng)建流程Spawn()Read_Fully694、Spawn函數(shù)的功能intSpawn(constchar*program,constchar*command,structKernel_Thread**pThread)參數(shù)說明:Program對應的是要讀入內(nèi)存緩沖區(qū)的可執(zhí)行文件,Command是用戶執(zhí)行程序執(zhí)行時的命令行字符串,pThread是存放指向剛創(chuàng)建進程的指針。Spawn函數(shù)主要完成的主要功能是:(1)調(diào)用Read_Fully函數(shù)將名為program的可執(zhí)行文件全部讀入內(nèi)存緩沖區(qū)。(2)調(diào)用Parse_ELF_Executable函數(shù),分析ELF格式文件。Parse_ELF_Executable函數(shù)功能在項目1中已經(jīng)實現(xiàn)。(3)調(diào)用Load_User_Program將可執(zhí)行程序的程序段和數(shù)據(jù)段等裝入內(nèi)存,初始化User_context數(shù)據(jù)結(jié)構(gòu)。(4)調(diào)用Start_User_Thread函數(shù)創(chuàng)建一個進程并使該進程進入準備運行隊列。4、Spawn函數(shù)的功能intSpawn(constch705、Load_User_Program函數(shù)Load_User_Program函數(shù)在“/src/geekos/userseg.c”文件中實現(xiàn),代碼也需要開發(fā)人員自己完成,函數(shù)原型如下:intLoad_User_Program(char*exeFileData,ulong_texeFileLength,structExe_Format*exeFormat,constchar*command,structUser_Context**pUserContext)/*參數(shù)說明:exeFileData——保存在內(nèi)存緩沖中的用戶程序可執(zhí)行文件;exeFileLength——可執(zhí)行文件的長度;exeFormat——調(diào)用Parse_ELF_Executable函數(shù)得到的可執(zhí)行文件格式信息;command——用戶輸入的命令行,包括可執(zhí)行文件的名稱及其他參數(shù);pUserContext——指向User_Conetxt的指針,是本函數(shù)完成用戶上下文初始化的對象*/5、Load_User_Program函數(shù)Load_Use71Load_User_Program主要實現(xiàn)功能如下:(1)根據(jù)Parse_ELF_Executable函數(shù)的執(zhí)行結(jié)果Exe_Format中的Exe_Segment結(jié)構(gòu)提供的用戶程序段信息,用戶命令參數(shù)及用戶態(tài)進程堆棧大小計算用戶態(tài)進程所需的最大內(nèi)存空間,即要分配給用戶態(tài)進程的內(nèi)存空間。(2)為用戶程序分配內(nèi)存空間,并初始化。(3)根據(jù)Exe_Segment提供的用戶段信息初始化代碼段、數(shù)據(jù)段以及堆棧段的段描述符和段選擇子。(4)根據(jù)段信息將用戶程序中的各段內(nèi)容復制到分配的用戶內(nèi)存空間。(5)根據(jù)Exe_Format結(jié)構(gòu)初始化User_Context結(jié)構(gòu)中的用戶態(tài)進程代碼段入口entry字段,并根據(jù)command參數(shù)初始化用戶內(nèi)存空間中的參數(shù)塊。(6)初始化User_Context結(jié)構(gòu)的用戶打開文件列表,并添加標準輸入輸出文件。(7)將初始化完畢的User_Context指針賦予*pUserContext,返回0表示成功。Load_User_Program主要實現(xiàn)功能如下:72一、項目設計目的研究進程調(diào)度算法,掌握用信號量實現(xiàn)進程間同步的方法。為GeekOS擴充進程調(diào)度算法——基于時間片輪轉(zhuǎn)的進程多級反饋調(diào)度算法,并能用信號量實現(xiàn)進程協(xié)作。二、項目設計要求(1)實現(xiàn)src/geekos/syscall.c文件中的Sys_SetSchedulingPolicy系統(tǒng)調(diào)用,它的功能是設置系統(tǒng)采用的何種進程調(diào)度策略;(2)實現(xiàn)src/geekos/syscall.c文件中的Sys_GetTimeOfDay系統(tǒng)調(diào)用,它的功能是獲取全局變量g_numTicks的值;(3)實現(xiàn)函數(shù)Change_Scheduling_Policy(),具體實現(xiàn)不同調(diào)度算法的轉(zhuǎn)換。(4)實現(xiàn)syscall.c中信號量有關(guān)的四個系統(tǒng)調(diào)用:sys_createsemaphore()、sys_P()、sys_V()和sys_destroysemaphore()。第11章設計項目3

一、項目設計目的第11章設計項目3731、多級反饋隊列調(diào)度隊列模型三、項目設計提示1、多級反饋隊列調(diào)度隊列模型三、項目設計提示742、多級反饋隊列與分時調(diào)度進程隊列的轉(zhuǎn)換

2、多級反饋隊列與分時調(diào)度進程隊列的轉(zhuǎn)換75(1)添加函數(shù)Chang_Scheduling_Policy(intpolicy,intquantum),policy是設置的調(diào)度策略,quantum是設置的時間片。例如policy為1說明設置的是多級反饋隊列調(diào)度算法,此時若g_SchedPolicy(為系統(tǒng)添加的標識算法的變量,初始化為0)為0,說明當前的調(diào)度算法為輪轉(zhuǎn)調(diào)度,要變成MLF就必須把空閑線程放入3隊列,若g_SchedPolicy為1,說明當前是多級反饋隊列調(diào)度算法,則返回。如果policy為0,則說明設置的是輪轉(zhuǎn)調(diào)度,此時若g_SchedPolicy為1,則必須把4個隊列變成一個隊列,即所有的線程都在隊列0上了。若g_SchedPolicy為0,則返回。3、函數(shù)設計提示(1)添加函數(shù)Chang_Scheduling_Policy76(2)在系統(tǒng)調(diào)用Sys_GetTimeOfDay()中,只需要返回g_numTicks就可以了。在Sys_SetSchedulingPolicy()中,如果state->ebx是1,則設置的是MLF算法,調(diào)用Change_Scheduling_Policy(SCHED_RR,quantum),為0則是RR算法,調(diào)用Change_Scheduling_Policy(SCHED_MLF,quantum)。如果state->ebx為其他值,則返回-1。(3)在Init_Thread()中都是把隊列放在0隊列上的,并且blocked變量為false。(4)在Get_Next_Runnable()中,從最高級的隊列開始,調(diào)用Find_Best()來找線程優(yōu)先級最大的線程,直到在某級隊列中找到符合條件可以運行的線程。(5)在Wait()函數(shù)中,線程被阻塞,所以blocked變量被設置為true,并且如果是MLF算法,則該進程的currentReadyQueue加一,下次運行的時候進入高一級的線程隊列。(2)在系統(tǒng)調(diào)用Sys_GetTimeOfDay()中,只需77GveekOS定義了信號量的結(jié)構(gòu)體:structSemaphore{intsemaphoreID;/*信號量的ID*/char*semaphoreName;/*信號量的名字*/intvalue;/*信號量的值*/intregisteredThreadCount;/*注冊該信號量的線程數(shù)量*/structKernel_Thread*registeredThreads[MAX_REGISTERED_THREADS];/*注冊的線程*/structThread_QueuewaitingThreads;/*等待該信號的線程隊列*/DEFINE_LINK(Semaphore_List,Semaphore);/*連接信號鏈表的域*/}4、信號量定義

GveekOS定義了信號量的結(jié)構(gòu)體:4、信號量定義78信號量操作:Semaphore_Create()Semaphore_Acquire(P操作)Semaphore_Release(V操作)Semaphore_Destroy()Create_Semaphore()函數(shù)首先檢查請求創(chuàng)建的這個信號量的名字是否存在,如果存在,那么就把這個線程加入到這個信號量所注冊的線程鏈表上;如果不存在,則分配內(nèi)存給新的信號量,清空它的線程隊列,把當前的這個線程加入到它的線程隊列中,設置注冊線程數(shù)量為1,初始化信號量的名字,值和信號量的ID,并把這個信號量添加到信號量鏈表上,最后返回信號量的ID。5、信號量PV操作

信號量操作:5、信號量PV操作79P操作Semaphore_Acquire()中,首先檢查傳入的信號量ID是否存在,如果存在,接著檢查當前線程是否注冊使用了這個信號量,如果這兩項檢查任意一項失敗了,那么就返回-1。如果成功了,就把信號量的值減去1,如果減去1后信號量的值小于0,那么就把當前線程放入這個信號量的等待隊列上。V操作Semaphore_Release()中,首先也是檢查傳入的信號量ID是否存在,如果存在,接著檢查當前線程是否注冊使用了這個信號量,如果這兩項檢查任意一項失敗了,那么就返回-1。如果成功了,那就把信號量的值加上1,如果加上1后信號量的值小于或等于0,則要把該信號量里等待隊列上的一個線程喚醒。Semaphore_Destroy()中,首先也是檢查傳入的信號量ID是否存在,如果存在,接著檢查當前線程是否注冊使用了這個信號量,如果這兩項檢查任意一項失敗了,那么就返回-1。如果成功了,就把該線程從這個信號量的注冊的線程數(shù)組中刪除,并把注冊的線程數(shù)量減去1。如果這個信號量的注冊線程為0了,則把這個信號量從信號量鏈表中刪除,并釋放它的內(nèi)存。P操作Semaphore_Acquire()中,首先檢查傳入80第12章設計項目4

一、項目設計目的了解虛擬存儲器管理設計原理,掌握請求分頁虛擬存儲管理的具體實現(xiàn)技術(shù)。二、項目設計要求(1)在<src/geekos/paging.c>文件中編寫代碼完成以下函數(shù):Init_VM()(definedin)函數(shù)將建立一個初始的內(nèi)存頁目錄和頁表,并且安裝一個頁面出錯處理函數(shù)。Init_Paging()函數(shù)(定義在src/geekos/paging.c)初始化操作頁面調(diào)度文件所需的所有數(shù)據(jù)結(jié)構(gòu)。就如前面說到的,Get_Paging_Device()函數(shù)指定分頁調(diào)度文件定位在哪一個設備和占用磁盤塊的地址范圍。Find_Space_On_Paging_File()函數(shù)應該在分頁調(diào)度文件里面找到一個空閑的足夠大的頁空間。它將返回這個大塊的索引,或者當沒有合適的空間就返回-1。第12章設計項目4一、項目設計目的81Free_Space_On_Paging_File()函數(shù)將釋放由Find_Space_On_Paging_File()函數(shù)在分頁調(diào)度文件里所分配的的磁盤塊。Write_To_Paging_File()函數(shù)將把存儲在內(nèi)存的一頁數(shù)據(jù)寫出到分頁調(diào)度文件里。Read_From_Paging_File()函數(shù)將讀取分頁調(diào)度文件里的一頁數(shù)據(jù)到內(nèi)存空間。(2)在<src/geekos/uservm.c>文件中編寫代碼完成以下函數(shù):Destroy_User_Context()釋放進程所占用的所有內(nèi)存和其它資源。Load_User_Program()裝載可執(zhí)行文件到內(nèi)存里,創(chuàng)建一個就緒的用戶地址空間,功能類似于分段系統(tǒng)的實現(xiàn)。Copy_From_User()從一個用戶緩沖區(qū)復制數(shù)據(jù)到一個內(nèi)核緩沖區(qū)。Copy_To_User()從一個內(nèi)核緩沖區(qū)復制數(shù)據(jù)到一個用戶緩沖區(qū)。Switch_To_Address_Space()利用它裝載相應頁目錄和LDT來切換到一個用戶地址空間。Free_Space_On_Paging_File()函數(shù)將821、地址轉(zhuǎn)換三、項目設計提示

1、地址轉(zhuǎn)換三、項目設計提示83GeekOS操作系統(tǒng)課程設計項目介紹84線性地址到物理地址的轉(zhuǎn)換過程線性地址到物理地址的轉(zhuǎn)換過程852、用戶進程的線性地址空間2、用戶進程的線性地址空間863、請求分頁系統(tǒng)實現(xiàn)操作系統(tǒng)將需要在磁盤設備上創(chuàng)建一個pagefile文件暫時保存從內(nèi)存中替換出去的頁,實現(xiàn)一個類LRU算法在內(nèi)存中選取一個替換頁把它寫到磁盤的pagefile文件中。缺頁中斷處理

表12-1缺頁處理表缺頁情況標識相應處理堆棧生長到新頁超出原來分配一頁的限制分配一個新頁進程繼續(xù)此頁保存在磁盤上數(shù)據(jù)標識這一頁在pagefile中存在從pagefile讀入需要的頁繼續(xù)因為無效地址缺頁非法地址訪問終止用戶進程3、請求分頁系統(tǒng)實現(xiàn)操作系統(tǒng)將需要在磁盤設備上創(chuàng)建一個pag87在“/src/geekos/mem.c”文件中,已經(jīng)定義了一個函數(shù)Alloc_Pageable_Page實現(xiàn)交換一頁到磁盤的操作,具體執(zhí)行步驟如下:調(diào)用mem.c文件中已經(jīng)實現(xiàn)的Find_Page_To_Page_Out函數(shù)來確定要替換的頁(這個函數(shù)依賴于頁數(shù)據(jù)結(jié)構(gòu)中的clock域)。調(diào)用paging.c文件中已經(jīng)實現(xiàn)的Find_Space_On_Paging_File函數(shù)在pagefile中找到空閑的存儲空間。調(diào)用paging.c文件中已經(jīng)實現(xiàn)的Write_To_Paging_File函數(shù)把被替換的頁寫到pagefile文件中。修改頁表的相應表項,清除頁存在的標志,標識為此頁在內(nèi)存為不存在。修改頁表項的頁基地址為包含這一頁的第一個磁盤塊號。修改頁表項的kernelInfo位標識為KINFO_PAGE_ON_DISK狀態(tài)(標識這一頁是在磁盤上存在,而不是沒有效)。調(diào)用lowlevel.asm文件中已經(jīng)實現(xiàn)的Flush_TLB來刷新TLB。在“/src/geekos/mem.c”文件中,已經(jīng)定義了一88

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 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

提交評論