版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、西北工業(yè)大學操作系統(tǒng)實驗實驗報告一、實驗目的掌握在GeekOS系統(tǒng)用戶態(tài)模式下加載并運行可執(zhí)行程序的方法。二、實驗要求1.按照實驗講義P127頁中的設計要求,實現(xiàn)在用戶態(tài)模式下加載并運行可 執(zhí)行程序的代碼,給出關(guān)鍵函數(shù)的代碼以與實驗結(jié)果。三、實驗過程與結(jié)果答:核心函數(shù)代碼如下:= user.c =/產(chǎn)生一個進程用戶態(tài)int Spaw n(const char *program, const char *ma nd, struct Kern el_Thread *pThread)TODO(Spaw n a process by read ing an executable from a file
2、system); int rc;char *exeFileData = 0;ulong_t exeFileLe ngth;struct User_C on text *userC on text = 0;struct Kern el_Thread *process = 0;struct Exe_Format exeFormat;if (rc = Read_Fully(program, (void*) & exeFileData, & exeFileLe ngth) != 0 )Print(Failed to Read File %s!n, program);goto fail;if(rc =
3、Parse_ELF_Executable(exeFileData, exeFileLe ngth, &exeFormat) != 0 )Prin t(Failed to Parse ELF File!n ”);goto fail;if(rc = Load_User_Program(exeFileData, exeFileLe ngth, &exeFormat, mand, & userC on text) != 0)Prin t(Failed to Load User Program!n);goto fail;/在堆分配方式下釋放內(nèi)存并再次初始化exeFileDataFree(exeFileD
4、ata);exeFileData = 0;/*開始用戶進程,調(diào)用Start_User_Thread函數(shù)創(chuàng)建一個進程并使其進入準備運行隊列*/process = Start_User_Thread(userC on text, false);if (process != 0) KASSERT(process-refCou nt = 2);/*返回核心進程的指針*/*pThread = process;rc = process-pid;記錄當前進程的IDelserc = ENOMEM;return rc;fail: /如果新進程創(chuàng)建失敗如此注銷User_Context對象if (exeFileDa
5、ta != 0)Free(exeFileData);/ 釋放內(nèi)存if (userCo ntext != 0)Destroy_User_Context(userContext);/ 銷毀進程對象return rc; /切換至用戶上下文void Switch_To_User_C on text(structKernel_Thread* kthread, struct In terrupt_State*state)static struct User_C on text* s_curre ntUserC on text; /* last user con text used */exter n in
6、t userDebug;struct User_C on text* userC on text = kthread-userC on text;KASSERT(!I nterrupts_E nabled();if (userCo ntext = 0) /userC on text為0表示此進程為核心態(tài)進程就不用切換地址空間return;if (userC on text != s_curre ntUserC on text) ulong_t esp0;/if (userDebug) Prin t(A%pn, kthread);Switch_To_Address_Space(userConte
7、xt);/為用戶態(tài)進程時如此切換地址空間esp0 = (ulo ng_t) kthread-stackPage) + PAGE_SIZE;/if (userDebug)/ Prin t(S%lxn, esp0);/*新進程的核心棧 */Set_Kernel_Stack_Poi nter(espO);/ 設置內(nèi)核堆棧指針/* New user con text is active */s_curre ntUserC on text = userC on text;= elf.c =int Parse_ELF_Executable(char *exeFileData, ulong_t exeFil
8、eLength, struct Exe_Format *exeFormat)int i;elfHeader *head=(elfHeader*)exeFileData;programHeader *proHeader=(programHeader *)(exeFileData+head-phoff);KASSERT(exeFileData!=NULL);KASSERT(exeFileLe ngthhead-ehsize+head-phe ntsize*head-ph nu m);KASSERT(head-e ntry%4=0);exeFormat-nu mSegme nts=head-ph n
9、um;exeFormat-e ntryAddr=head-e ntry;for(i=0;iph nu m;i+)exeFormat-segme ntListi.offset InF ile=proHeader-offset;exeFormat-segme ntListien gthI nFile=proHeader-fileSize;exeFormat-segme ntListi.startAddress=proHeader-vaddr;exeFormat-segme ntListi.sizel nM emory=proHeader-memSize;exeFormat-segme ntList
10、tFlags=proHeader-flags;proHeader+;return 0;= userseg.c =需在此文件各函數(shù)前增加一個函數(shù),此函數(shù)的功能是按給定的大小創(chuàng)建一個用戶級進程上下文,具體實現(xiàn)如下:函數(shù)功能:按給定的大小創(chuàng)建一個用戶級進程上下文static struct User_C on text* Create_User_C on text(u long_t size)struct User_C on text * UserC on text;size = Roun d_Up_To_Page(size);UserCo ntext = (struct User_Co n
11、text *)Malloc(sizeof(struct User_Co ntext);if (UserCo ntext != 0)UserC on text-memory = Malloc(size);/為核心態(tài)進程elsegoto fail;內(nèi)存為空if (0 = UserC on text-memory)goto fail;memset(UserC on text-memory, 0, size);UserC on text-size = size;/以下為用戶態(tài)進程創(chuàng)建LDT(段描述符表)新建一個LDT描述符UserC on text-ldtDescriptor = Allocate_S
12、egme nt_Descriptor();if (0 = UserC on text-ldtDescriptor)goto fail;/初始化段描述符In it_LDT_Descriptor(UserCo ntext-ldtDescriptor,UserCo ntext-ldt,NUM_USER_LDT_ENTRIES);新建一個LDT選擇子UserCo ntext-ldtSelector=Selector(KERNEL_PRIVILEGE,true,Get_Descriptor_I ndex(UserC on text-ldtDescriptor);/新建一個文本段描述符Ini t_Code
13、_Segme nt_Descriptor(& UserCo ntext-ldt0,(ulon g_t) UserC on text-memory,size / PAGE_SIZE,USER_PRIVILEGE);/新建一個數(shù)據(jù)段Ini t_Data_Segme nt_Descriptor(& UserCo ntext-ldt1,(ulon g_t) UserC on text-memory,size / PAGE_SIZE,USER_PRIVILEGE);/新建數(shù)據(jù)段和文本段選擇子UserC on text-csSelector = Selector(USER_PRIVILEGE, false
14、, 0);UserCo ntext-dsSelector = Selector(USER_PRIVILEGE, false, 1);/將引用數(shù)清0UserC on text-refCou nt = 0;retur n UserC on text;fail:if (UserCo ntext != 0)if (UserC on text-memory != 0)Free(UserC on text-memory);Free(UserC on text);return 0; /摧毀用戶上下文void Destroy_User_C on text(struct User_C on text* user
15、C on text) TODO(Destroy a User_Co ntext);/釋放占用的LDTFree_Segme nt_Descriptor(userC on text-ldtDescriptor);userC on text-ldtDescriptor=0;/釋放內(nèi)存空間Free(userC on text-memory); userC on text-memory=0;/釋放userContext本身占用的內(nèi)存Free(userC on text);userC on text=0;int Load_User_Program(char *exeFileData,u long_texe
16、FileLe ngth,structExe_Format*exeFormat,c onst char *ma nd,struct User_C on text *pUserC on text)TODO(Load a user executable into a user memory space using segme ntati on ”);int i;ulong_t maxva = 0;/要分配的最大內(nèi)存空間un sig ned nu mArgs;/ 進程數(shù)目ulong_t argBlockSize;/ 參數(shù)塊的大小ulong_t size, argBlockAddr;/ 參數(shù)塊地址str
17、uct User_C on text *userC on text = 0;/計算用戶態(tài)進程所需的最大內(nèi)存空間for (i = 0; i nu mSegme nts; +i) struct Exe_Segme nt *segme nt = & exeFormat-segme ntListi;ulong_t topva = segme nt-startAddress + segme nt-sizel nM emory; /* FIXME: range check */if (topva maxva)maxva = topva;Get_Argume nt_Block_Size(ma nd, &nu
18、 mArgs, &argBlockSize); 獲取參數(shù)塊信息size = Round_ Up_To_Page(maxva) + DEFAULT_USER_STACK_SIZE;argBlockAddr = size;size += argBlockSize;userContext = Create_User_Context(size);/ 按相應大小創(chuàng)建一個進程if (userContext = 0)/如果為核心態(tài)進程return -1;for (i = 0; i nu mSegme nts; +i) struct Exe_Segme nt *segme nt = & exeFormat-s
19、egme ntListi;/根據(jù)段信息將用戶程序中的各段內(nèi)容復制到分配的用戶內(nèi)存空間memcpy(userC on text-memory+segme nt-startAddress,exeFileData +segme nt-offsetl nFile,segme nt-le ngthl nFile);/格式化參數(shù)塊Format_Argume nt_Block(userC on text-memory+ argBlockAddr, nu mArgs, argBlockAddr,man d);/初始化數(shù)據(jù)段,堆棧段與代碼段信息userC on text-e ntryAddr = exeForm
20、at-e ntryAddr;userC on text-argBlockAddr = argBlockAddr;userC on text-stackPoi nterAddr = argBlockAddr;將初始化完畢的 User_Context賦給*pUserContext *pUserC on text = userC on text;return 0;/ 成功 /將用戶態(tài)的進程復制到內(nèi)核緩沖區(qū)bool Copy_From_User(void* dest InKern el, ulong_t srcInU ser, ulong_t bufSize) struct User_C on tex
21、t * UserC on text = g_curre ntThread-userC on text;/-: check if memory if validatedif (!Validate_User_Memory(UserCo ntext,srcl nU ser, bufSize)return false;memcpy(destl nKern el, UserC on text-memory + srcInU ser, bufSize);return true; /將內(nèi)核態(tài)的進程復制到用戶態(tài)bool Copy_To_User(u long_t destl nU ser, void* src
22、InKern el, ulong_t bufSize) struct User_C on text * UserC on text = g_curre ntThread-userC on text;if (!Validate_User_Memory(UserCo ntext, destI nU ser,bufSize)return false;memcpy(UserC on text-memory + destI nU ser, srcInKern el, bufSize); return true; /切換到用戶地址空間void Switch_To_Address_Space(struct
23、User_C on text *userC on text)ushort_t ldtSelector= userC on text-ldtSelector;/* Switch to the LDT of the new user con text */_asmvolatile_ (lldt %0:a(ldtSelector);= kthread.c =添加頭文件 #i nclude /創(chuàng)建一個用戶進程/*static*/ void Setup_User_Thread(struct Kern el_Thread* kthread, struct User_C on text* userC on
24、text)ulo ng_t eflags = EFLAGS_IF;unsigned csSelector=userContext-csSelector;/CS 選擇子unsigned dsSelector=userContext-dsSelector;/DS 選擇子Attach_User_C on text(kthread, userC on text);初始化用戶態(tài)進程堆棧,使之看上去像剛被中斷運行一樣分別調(diào)用Push函數(shù)將以下數(shù)據(jù)壓入堆棧Push (kthread, dsSelector);Push(kthread, userC on text-stackPo in terAddr);Pu
25、sh(kthread, eflags);Push(kthread, csSelector);Push(kthread, userC on text-e ntryAddr);Push (kthread, 0);Push (kthread, 0);/數(shù)據(jù)選擇子堆棧指針/Eflags文本選擇子/程序計數(shù)器錯誤代碼(0)中斷號(0)/初始化通用存放單元,將ESI用戶傳遞參數(shù)塊地址Push(kthread, 0); /* eax */Push(kthread, 0); /* ebx */Push(kthread, 0); /* edx */Push(kthread, 0); /* edx */Push(
26、kthread, userC on text-argBlockAddr); /* esi */Push(kthread, 0); /* edi */Push(kthread, 0); /* ebp */初始化數(shù)據(jù)段存放單元Push(kthread, dsSelector); /* ds */Push(kthread, dsSelector); /* es */Push(kthread, dsSelector); /* fs */Push(kthread, dsSelector); /* gs */開始用戶進程struct Kern el_Thread* Start_User_Thread(st
27、ruct User_C on text* userC on text, bool detached) struct Kernel_Thread* kthread = Create_Thread(PRIORITY_USER, detached);if (kthread != 0)Setup_User_Thread(kthread, userC on text);Make_Ru nn able_Atomic(kthread);return kthread;syscall.c/需在此文件別的函數(shù)前增加一個函數(shù),函數(shù)名為Copy_User_String ,它被函數(shù)Sys_PrintString調(diào)用,具
28、體實現(xiàn)如下:static int Copy_User_Stri ng(u long_t uaddr, ulon g_t le n, ulong_t maxLe n, char *pStr) int rc = 0;char *str;if (le n maxLe n)/超過最大長度return EINV ALID;str = (char*) Malloc(le n+1);/ 為字符串分配空間if (0 = str)rc = ENOMEM;goto fail;if (!Copy_From_User(str, uaddr, le n)從用戶空間中復制數(shù)據(jù)rc = EINV ALID;Free(str
29、);goto fail;strle n = 0:/成功*pStr = str;fail:return rc; static int Sys_Exit(struct Interrupt_State* state) Exit(state-ebx); static int Sys_PrintString(struct Interrupt_State* state)int rc = 0;/ 返回值uint_t length = state-ecx;/ 字符串長度uchar_t* buf = 0;if (le ngth 0) if (rc = Copy_User_String(state-ebx, le
30、ngth, 1023, (char*) &buf) != 0) goto done;Put_Buf(buf, le ngth);done:if (buf != 0)Free(buf);return rc; static int Sys_GetKey(struct Interrupt_State* state)return Wait_For_Key(); / 返回按鍵碼 keyboard.c/Wait_For_Key() static int Sys_SetAttr(struct In terrupt_State* state) Set_Curre nt_Attr(uchar_t) state-
31、ebx); return 0; static int Sys_GetCursor(struct Interrupt_State* state)int row, col;Get_Cursor(&row, & col);if (!Copy_To_User(state-ebx, &row, sizeof( in t) |!Copy_To_User(state-ecx, &col, sizeof( in t) return -1;return 0; static int Sys_PutCursor(struct Interrupt_State* state) retur n Put_Cursor(st
32、ate-ebx, state-ecx) ? 0 : -1; static int Sys_Spaw n( struct In terrupt_State* state)int rc;/函數(shù)返回值char *program = 0;進程名稱char *ma nd = 0;/ 用戶命令struct Kern el_Thread *process;if (rc = Copy_User_Stri ng(state-ebx, state-ecx, VFS_MAX_PATH_LEN, & program) != 0) goto fail;if(rc = Copy_User_Stri ng(state-ed
33、x, state-esi, 1023, &man d) != 0)/從用戶空間復制用戶命令goto fail;En able_I nterrupts();/ 開中斷rc = Spawn(program, mand, &process);/得到進程名稱和用戶命令后便可生成一個新進程if (rc = 0) /假如成功如此返回新進程 ID號KASSERT(process != 0);rc = process-pid;Disable_Interrupts();/ 關(guān)中斷if (program != 0) Free(program);if (ma nd != 0)Free(ma nd); return
34、rc; static int 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;En able_I nterrupts();exitCode = Join( kthread);Disable_I nterrupts();retur n exitCode; static int Sys_GetPID(struct Interr
35、upt_State* state) /TODO(GetPID system call);retur n g_curre ntThread-pid;= main.c = static void Spaw n_lni t_Process(void) /TODO(Spaw n the in it process);struct Kernel_Thread *pThread;Spaw n(”/c/shell.exe,/c/shell.exe,&pThread);實驗結(jié)果如下列圖:C Q dcKhs xB6 emulator, http:;/bochs.sourceforgcnetit- .| | ji
36、iTsijiirercWiSrfcgI ist 1G48E7G bytes in kernEi Jheapkry br)Ard .DHA Caintpoller.-. Cloppy contro1ier.06, hcods2, sectors 18IEE duh tibuller.1333313333 H |jlL,frZl. . FI7TTk35 *|躥% 廉遜緩空,5.航*通耳百ij原理:Geekos提供了一個簡單的shell,保存在PFAT文件系統(tǒng)內(nèi),所以geekos系統(tǒng)啟動后,啟動shell程序/c/shell.exe運行,將作為可執(zhí)行文件傳遞給spawn函數(shù)的program參數(shù),創(chuàng)建第一個用戶態(tài)進程,然后由它來創(chuàng)建其他進程。運行后,geekos就可以掛在這shell,并能運行測試文件c.exe和b.exeo四、實驗分析GeekOS系統(tǒng)最早創(chuàng)建的內(nèi)核進程有Idle、Reaper和Main三個進程,它們 由Ini t
溫馨提示
- 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2023年度河南省政府采購評審專家資格自我提分評估附答案
- 2021年度大學英語六級考試聽力理解及原文
- 《牛傳染性鼻氣管炎》課件
- 《組建創(chuàng)業(yè)團隊》課件
- 《無窮級數(shù)課件》課件
- 2021年初級經(jīng)濟師金融專業(yè)知識與實務 考試題庫
- 2021年浙江省衢州市大學英語6級大學英語六級預測試題(含答案)
- 預防食品安全課件
- 小學五年級機器人編程課 6.《八音盒》活動說課稿001
- 2025年高二化學寒假銜接講練 (人教版)寒假提升練-專題08 鹽類水解(學生版)
- 事故隱患報告和舉報獎勵制度
- 腹部外傷門診病歷
- 品質(zhì)異常處理及要求培訓
- 模具部年終總結(jié)--ppt課件
- 立式熱虹吸再沸器機械設計說明書
- 國家開放大學電大《生產(chǎn)與運作管理》2025-2026期末試題及答案
- 質(zhì)量保證大綱(共14頁)
- 關(guān)于歐盟新版EMC標準EN55032的解析
- 木材材積表0.1-10米.xls
- 輕質(zhì)隔墻板安裝合同協(xié)議書范本標準版
- 車輛管理各崗位績效考核量表
評論
0/150
提交評論