




版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、合肥工業(yè)大學計算機與信息學院實驗報告課 程: 計算機操作系統(tǒng)專業(yè)班級: 計算機科學與技術2班學 號: 姓 名: 實驗1 實驗環(huán)境的使用一.實驗目的1.熟悉操作系統(tǒng)集成實驗環(huán)境OS Lab的基本使用方法。 2.練習編譯、調(diào)試EOS操作系統(tǒng)內(nèi)核以及EOS應用程序。二.實驗內(nèi)容1啟動OS Lab2. 學習OS Lab的基本使用方法2.1新建Windows控制臺應用程序項目 2.2生成項目2.3執(zhí)行項目2.4調(diào)試項目 2.4.1 使用斷點中斷執(zhí)行 2.4.2單步調(diào)試 2.4.3查看變量的值 2.4.4調(diào)用堆棧3. EOS內(nèi)核項目的生成和調(diào)試 3.1新建EOS內(nèi)核項目 3.2生成項目3.3調(diào)試項目3.4
2、查看軟盤鏡像文件中的內(nèi)容3.5查看EOS SDK(Software Development Kit)文件夾4. EOS應用程序項目的生成和調(diào)試 4.1新建EOS應用程序項目 4.2生成項目 4.3調(diào)試項目4.4查看軟盤鏡像文件中的內(nèi)容4.5修改EOS應用程序項目名稱5 退出OS Lab6 保存EOS內(nèi)核項目三.實驗結果本實驗主要是熟悉EOS操作系統(tǒng)的基本操作,練習了:(1)新Windows控制臺應用程序項,1.“文件”菜單中選擇“新建”,然后單擊“項目”。2. 在“新建項目”對話框中,選擇項目模板“控制臺應用程序 (c)”。3. 在“名稱”中輸入新項目使用的文件夾名稱“oslab”。4. 在“
3、位置”中輸入新項目保存在磁盤上的位置“C:test”。新建完畢后, OS Lab 會自動打開這個新建的項目。(2)在“生成”菜單中選擇“生成項目”。結果如圖(3)執(zhí)行項目:選擇“調(diào)試”菜單中的“開始執(zhí)行”(4)調(diào)試項目:1. 右鍵點擊“項目管理器”窗口中的“源文件”文件夾節(jié)點,在彈出的快捷菜單中選擇“添加”中的“添加新文件”。 2. 在彈出的“添加新文件”對話框中選擇“C 源文件”模板。 3. 在“名稱”中輸入文件名稱“func”。 4. 點擊“添加”按鈕,添加并自動打開文件func.c,此時的“項目管理器”窗口會如圖: (5). 在 func.c 文件中添加函數(shù): int Func (int
4、 n) n = n + 1; return n; (6). 點擊源代碼編輯器上方的console.c標簽,切換到console.c文件。將 main 函數(shù)修改為: int main (int argc, char* argv) int Func (int n); / 聲明Func函數(shù) int n = 0; n = Func(10); printf ("Hello World!n"); return 0; 代碼修改完畢后按F7實驗結果為輸出:Hello World!(7). 在main函數(shù)中定義變量n的代碼行 int n = 0; 上點擊鼠標右鍵,在彈出的快捷菜單中選擇“插入
5、/刪除斷點”,會在此行左側的空白處顯示一個紅色圓點,表示已經(jīng)成功在此行代碼添加了一個斷點練習使用“逐過程”, “逐語句”,“跳出”功能(8).在源代碼編輯器中變量n的名稱上點擊鼠標右鍵,在彈出的快捷菜單中選擇“快速監(jiān)視”,進行單步測試,觀察n結果依次為0,11(9)調(diào)用堆棧,選擇“調(diào)試”菜單“窗口”中的“調(diào)用堆?!保せ睢罢{(diào)用堆?!贝翱???梢钥吹疆斍啊罢{(diào)用堆?!贝翱谥兄挥幸粋€main函數(shù)(顯示的內(nèi)容還包括了參數(shù)值和函數(shù)地址)。 按F11(“逐語句”功能的快捷鍵)調(diào)試,直到進入Func函數(shù) ,其中當前正在調(diào)試的Func函數(shù)在棧頂位置,main函數(shù)在棧底位置。說明是在main函數(shù)中調(diào)用了Func函
6、數(shù)。 (10)查看軟盤鏡像文件中的內(nèi)容,在“項目管理器”窗口中雙擊軟盤鏡像文件Floppy.img四.實驗總結今天第一次進行操作系統(tǒng)這門課的實驗,這也是將抽象的理論知識應用到實踐的一個很好的機會,同時,我們也學習了使用OS Lab的這個實驗環(huán)境,OS Lab的操作界面和Microsoft Visual Studio 2010很像,所以使用起來很快就能上手,對于實驗內(nèi)容,今天主要練習了:新建Windows控制臺應用程序項目、生成項目、執(zhí)行項目、調(diào)試項目以及EOS應用程序項目的生成和調(diào)試;設置間斷點,并且在它的基礎上進行了單步操作;詳細觀察了通過“快速監(jiān)視“標記的數(shù)的值的變化過程等基本操作,這也為
7、以后實驗的順利進行打下了良好的基礎。5. 實驗截圖實驗2 操作系統(tǒng)的啟動一.實驗目的1.跟蹤調(diào)試EOS在PC機上從加電復位到成功啟動的全過程,了解操作系統(tǒng)的啟動過程。 2.查看EOS啟動后的狀態(tài)和行為,理解操作系統(tǒng)啟動后的工作方式。 二.實驗內(nèi)容1 準備實驗2 調(diào)試EOS操作系統(tǒng)的啟動過程2.1 使用Bochs做為遠程目標機2.2 調(diào)試BIOS程序2.3 調(diào)試軟盤引導扇區(qū)程序2.4 調(diào)試加載程序2.5 調(diào)試內(nèi)核2.6 EOS啟動后的狀態(tài)和行為三.實驗結果1.新建一個EOS Kernel項目。 2.使用Bochs做為遠程目標機(1)在“項目管理器”窗口中,右鍵點擊項目節(jié)點,在彈出的快捷菜單中選擇
8、“屬性”。 (2) 在彈出的“屬性頁”對話框右側的屬性列表中找到“遠程目標機”屬性,將此屬性值修改為“Bochs Debug” (3)點擊“確定”按鈕關閉“屬性頁”對話框。接下來就可以使用Bochs模擬器調(diào)試BIOS程序和軟盤引導扇區(qū)程序了。 3.按F5啟動調(diào)試,此時會彈出兩個Bochs窗口。標題為“Bochs for windows - Display”的窗口相當于計算機的顯示器,顯示操作系統(tǒng)的輸出。標題為“Bochs for windows - Console”的窗口是Bochs的控制臺,用來輸入調(diào)試命令,輸出各種調(diào)試信息。4.啟動調(diào)試后,Bochs在CPU要執(zhí)行的第一條指令(即BIOS的
9、第一條指令)處中斷。 此時,Display窗口沒有顯示任何內(nèi)容,Console窗口顯示要執(zhí)行的BIOS第一條指令的相關信息,并等待用戶輸入調(diào)試命令5.然后查看CPU在沒有執(zhí)行任何指令之前主要寄存器中的數(shù)據(jù),以及內(nèi)存中的數(shù)據(jù)(1)在Console窗口中輸入調(diào)試命令sreg后按回車,顯示當前CPU中各個段寄存器的值(2)輸入調(diào)試命令r后按回車,顯示當前CPU中各個通用寄存器的值(3)輸入調(diào)試命令xp /1024b 0x0000,查看開始的1024個字節(jié)的物理內(nèi)存。在Console中輸出的這1K物理內(nèi)存的值都為0,說明BIOS中斷向量表還沒有被加載到此處。 (4)輸入調(diào)試命令xp /512b 0x7
10、c00,查看軟盤引導扇區(qū)應該被加載到的內(nèi)存位置。輸出的內(nèi)存值都為0,說明軟盤引導扇區(qū)還沒有被加載到此處。 6.EOS啟動后的狀態(tài)和行為(1) 在控制臺中輸入命令“ver”后按回車。結果如圖 (2)查看EOS啟動后的進程和線程的信息: 在控制臺中輸入命令“pt”后按回車。輸出的進程和線程信息如圖所示四.實驗總結今天的實驗在實驗一的基礎上學習了EOS操作系統(tǒng)的啟動、跟蹤調(diào)試以及EOS在PC機上從加電復位到成功啟動的全過程,這讓我們對EOS這個平臺有了初步的掌握,同時我們也練習了查看了EOS啟動后的狀態(tài)和行為,學會了查看CPU主要寄存器中以及內(nèi)存中的數(shù)據(jù)的方法。五.實驗截圖實驗3進程的創(chuàng)建一,實驗目
11、的:1,練習使用 EOS API 函數(shù) CreateProcess 創(chuàng)建一個進程, 掌握創(chuàng)建進程的方法, 理解進程和程序的區(qū)別。2,調(diào)試跟蹤 CreateProcess 函數(shù)的執(zhí)行過程,了解進程的創(chuàng)建過程,理解進程是資源分配的單位。二,預備知識:閱讀本書第 5.1 節(jié),重點理解程序和進程的關系,熟悉進程控制塊結構體以及進程創(chuàng)建的過程。仔細學習CreateProcess函數(shù)和其它與創(chuàng)建進程相關的函數(shù)的說明, 注意理解這些函數(shù)的參數(shù)和返回值的意義。三,主要實驗內(nèi)容及步驟:1, 準備實驗;2, 練習使用控制臺命令創(chuàng)建EOS 應用程序的進程:練習使用控制臺命令創(chuàng)建 EOS 應用程序進程的具體步驟如下:
12、(1) 在 EOS 應用程序項目的“項目管理器”窗口中雙擊 Floppy.img 文件,使用 FloppyImageEditor工具打開此軟盤鏡像文件。(2)將本實驗文件夾中的 Hello.exe 文件拖動到 FloppyImageEditor 工具窗口的文件列表中釋放,Hello.exe 文件即被添加到軟盤鏡像文件中。Hello.exe 一個 EOS 應用程序,其源代碼可以參見本實驗文件夾中的 Hello.c 源文件。(3)在 FloppyImageEditor 中選擇“文件”菜單中的“保存”后關閉 FloppyImageEditor。(4)按 F7 生成 EOS 應用項目。(5)按 F5
13、啟動調(diào)試。OS Lab 會彈出一個調(diào)試異常對話框,并中斷應用程序的執(zhí)行。(6) 在調(diào)試異常對話框中選擇“否”,忽略異常繼續(xù)執(zhí)行應用程序。(7) 激活虛擬機窗口,待該應用程序執(zhí)行完畢后,在 EOS 的控制臺中輸入命令“A:Hello.exe”后回車。(8) Hello.exe 應用程序開始執(zhí)行,觀察其輸出如圖 11-1。(9)待 Hello.exe 執(zhí)行完畢后可以重復第 7 步,或者結束此次調(diào)試。3. 練習通過編程的方式讓應用程序創(chuàng)建另一個應用程序的進程使用 OS Lab 打開本實驗文件夾中的 NewProc.c 文件(將此文件拖動到 OS Lab 窗口中釋放即可) 按照下面的步驟查看應用程序創(chuàng)
14、建另一個應用程序的進程的執(zhí)行結果:(1) 使用NewProc.c文件中的源代碼替換之前創(chuàng)建的EOS應用程序項目中的EOSApp.c文件內(nèi)的源代碼。(2)按 F7 生成修改后的 EOS 應用程序項目。(3) 按 F5 啟動調(diào)試。OS Lab 會首先彈出一個調(diào)試異常對話框。(4) 在調(diào)試異常對話框中選擇“否”,繼續(xù)執(zhí)行。(5)激活虛擬機窗口查看應用程序輸出的內(nèi)容, 如圖 11-2。 結合圖 11-1, 可以看到父進程 (EOSApp.exe)首先開始執(zhí)行并輸出內(nèi)容,父進程創(chuàng)建了子進程(Hello.exe)后,子進程開始執(zhí)行并輸出內(nèi)容,待子進程結束后父進程再繼續(xù)執(zhí)行。(6)結束此次調(diào)試。4.調(diào)試 C
15、reateProcess 函數(shù)按照下面的步驟調(diào)試 CreateProcess 函數(shù)創(chuàng)建進程的過程:(1) 按 F5 啟動調(diào)試 EOS 應用程序,OS Lab 會首先彈出一個調(diào)試異常對話框。(2) 選擇“是”調(diào)試異常,調(diào)試會中斷。(3)在 main 函數(shù)中調(diào)用 CreateProcess 函數(shù)的代碼行(第 57 行)添加一個斷點。(4)按 F5 繼續(xù)調(diào)試,在斷點處中斷。(5)按 F11 調(diào)試進入 CreateProcess 函數(shù)。此時已經(jīng)開始進入 EOS 內(nèi)核進行調(diào)試。.5, 調(diào)試PsCreateProcess 函數(shù) 創(chuàng)建進程最主要的操作就是創(chuàng)建進程控制塊(PCB),并初始化其中的各種信息(也就
16、是為進程分配各種資源) 。所以在 PsCreateProcess 函數(shù)中首先調(diào)用了 PspCreateProcessEnvironment 函數(shù)來創(chuàng)建進程控制塊。調(diào)試 PspCreateProcessEnvironment 函數(shù)的步驟如下:(1)在 PsCreateProcess 函數(shù)中找到調(diào)用 PspCreateProcessEnvironment 函數(shù)的代碼行(create.c文件的第 163 行) ,并在此行添加一個斷點。(2) 按 F5 繼續(xù)調(diào)試,到此斷點處中斷。(3) 按 F11 調(diào)試進入 PspCreateProcessEnvironment 函數(shù)。由于 PspCreateProc
17、essEnvironment 函數(shù)的主要功能是創(chuàng)建進程控制塊并初始化其中的部分信息,所以在此函數(shù)的開始,定義了一個進程控制塊的指針變量 NewProcess。在此函數(shù)中查找到創(chuàng)建進程控制塊的代碼行(create.c 文件的第 418 行)Status = ObCreateObject( PspProcessType,NULL,sizeof(PROCESS) + ImageNameSize + CmdLineSize,0,(PVOID*)&NewProcess );這里的 ObCreateObject 函數(shù)會在由 EOS 內(nèi)核管理的內(nèi)存中創(chuàng)建了一個新的進程控制塊(也就是分配了一塊內(nèi)存)
18、,并由 NewProcess 返回進程控制塊的指針(也就是所分配內(nèi)存的起始地址) 。按照下面的步驟調(diào)試進程控制塊的創(chuàng)建過程:(1)在調(diào)用 ObCreateObject 函數(shù)的代碼行(create.c 文件的第 418 行)添加一個斷點。(2)按 F5 繼續(xù)調(diào)試,到此斷點處中斷。(3) 按 F10 執(zhí)行此函數(shù)后中斷。(4) 此時為了查看進程控制塊中的信息,將表達式*NewProcess 添加到“監(jiān)視”窗口中。(5) 將鼠標移動到“監(jiān)視”窗口中此表達式的“值”屬性上,會彈出一個臨時窗口,在臨時窗口中會按照進程控制塊的結構顯示各個成員變量的值(可以參考 PROCESS 結構體的定義) 。由于只是新建
19、了進程控制塊,還沒有初始化其中成員變量,所以值都為 0。接下來調(diào)試初始化進程控制塊中各個成員變量的過程:(1)首先創(chuàng)建進程的地址空間,即 4G 虛擬地址空間。在代碼行(create.c 文件的第 437 行)NewProcess->Pas = MmCreateProcessAddressSpace();添加一個斷點。(2) 按 F5 繼續(xù)調(diào)試,到此斷點處中斷。(3)按 F10 執(zhí)行此行代碼后中斷。(4)在“監(jiān)視”窗口中查看進程控制塊的成員變量 Pas 的值已經(jīng)不再是 0。說明已經(jīng)初始化了進程的4G 虛擬地址空間。(5)使用 F10 一步步調(diào)試 PspCreateProcessEnviro
20、nment 函數(shù)中后面的代碼,在調(diào)試的過程中根據(jù)執(zhí)行的源代碼,查看“監(jiān)視”窗口中*NewProcess 表達式的值,觀察進程控制塊中哪些成員變量是被哪些代碼初始化的,哪些成員變量還沒有被初始化。(6)當從 PspCreateProcessEnvironment 函數(shù)返回到 PsCreateProcess 函數(shù)后, 停止按 F10。 此時 “監(jiān)視”窗口中已經(jīng)不能再顯示表達式*NewProcess 的值了,在 PsCreateProcess 函數(shù)中是使用ProcessObject 指針指向進程控制塊的,所以將表達式*ProcessObject 添加到“監(jiān)視”窗口中就可以繼續(xù)觀察新建進程控制塊中的信
21、息。(7)接下來繼續(xù)使用 F10 一步步調(diào)試 PsCreateProcess 函數(shù)中的代碼,同樣要注意觀察執(zhí)行后的代碼修改了進程控制塊中的哪些成員變量。當調(diào)試到 PsCreateProcess 函數(shù)的最后一行代碼時,查看進程控制塊中的信息, 此時所有的成員變量都已經(jīng)被初始化了 (注意觀察成員 ImageName 的值) 。(8)按 F5 繼續(xù)執(zhí)行,EOS 內(nèi)核會為剛剛初始化完畢的進程控制塊新建一個進程。激活虛擬機窗口查看新建進程執(zhí)行的結果。(9)在 OS Lab 中選擇“調(diào)試”菜單中的“停止調(diào)試”結束此次調(diào)試。(10)選擇“調(diào)試”菜單中的“刪除所有斷點” 。6, 練習通過編程的方式創(chuàng)建應用程序
22、的多個進程.四實驗收獲及感悟:通過本次實驗熟悉了進程的創(chuàng)建,對進程更加的了解。也讓我更加熟悉OS Lab這個軟件,對于EOS操作系統(tǒng)的理解也更加深刻。5 實驗截圖實驗4:線程的狀態(tài)和轉換一,實驗目的:1,調(diào)試線程在各種狀態(tài)間的轉換過程,熟悉線程的狀態(tài)和轉換。2,通過為線程增加掛起狀態(tài),加深對線程狀態(tài)的理解。二,預備知識:閱讀本書第 5.2.3 節(jié),了解線程都有哪些狀態(tài)以及 EOS 是如何定義這些狀態(tài)的。了解線程是如何在這些狀態(tài)之間進行轉換的,特別是要閱讀一下 EOS 中用于線程轉換的相關函數(shù)的源代碼。閱讀本書第 5.2.4節(jié), 了解 EOS 為線程添加的掛起狀態(tài), 以及 Suspend 和 R
23、esume 原語操作。 線程狀態(tài)的轉換和線程的同步、線程的調(diào)度是不可分割的,所以建議讀者簡單學習一下第 5.3 和 5.4 節(jié)中的內(nèi)容。此外,由于本實驗需要觀察“控制臺派遣線程”在不同狀態(tài)間的轉換過程,所以讀者也需要對該線程有一個簡單的了解。控制臺派遣線程做為一個系統(tǒng)線程(優(yōu)先級為 24) ,在 EOS 啟動后就會被創(chuàng)建,但是該線程絕大部分時間都處于阻塞狀態(tài),只有當發(fā)生鍵盤事件(例如鍵被按下)時才會被喚醒,當該線程將鍵盤事件派遣到當前活動的控制臺后,該線程就會重新回到阻塞狀態(tài)等待下一個鍵盤事件到來。該線程的線程函數(shù)是文件 io/console.c 中的 IopConsoleDispatchTh
24、read 函數(shù)(第 567 行) 。三,主要實驗內(nèi)容及步驟:1,準備實驗;2,調(diào)試線程狀態(tài)的轉換過程;在本練習中,會在與線程狀態(tài)轉換相關的函數(shù)中添加若干個斷點,并引導讀者單步調(diào)試這些函數(shù),使讀者對 EOS 中的下列線程狀態(tài)轉換過程有一個全面的認識:l 線程由阻塞狀態(tài)進入就緒狀態(tài)。l 線程由運行狀態(tài)進入就緒狀態(tài)。l 線程由就緒狀態(tài)進入運行狀態(tài)。l 線程由運行狀態(tài)進入阻塞狀態(tài)。為了完成這個練習,EOS 準備了一個控制臺命令“l(fā)oop” ,這個命令的命令函數(shù)是 ke/sysproc.c 文件中的 ConsoleCmdLoop 函數(shù)(第 797 行) ,在此函數(shù)中使用 LoopThreadFuncti
25、on 函數(shù)(第 755 行)創(chuàng)建了一個優(yōu)先級為 8 的線程(后面簡稱為“l(fā)oop 線程” ) ,該線程會在控制臺中不停的(死循環(huán))輸出該線程的ID 和執(zhí)行計數(shù),執(zhí)行計數(shù)會不停的增長以表示該線程在不停的運行??梢园凑障旅娴牟襟E查看一下 loop命令執(zhí)行的效果:(1) 按 F7 生成在本實驗 3.1 中創(chuàng)建的 EOS Kernel 項目。(2) 按 F5 啟動調(diào)試。(3) 待 EOS 啟動完畢,在 EOS 控制臺中輸入命令“l(fā)oop”后按回車。(4) 結束此次調(diào)試。接下來按照下面的步驟調(diào)試線程狀態(tài)轉換的過程:(1) 在 ke/sysproc.c 文件的 LoopThreadFunction 函數(shù)中
26、,開始死循環(huán)的代碼行(第 787 行)添加一個斷點。(2)按 F5 啟動調(diào)試。(3) 待 EOS 啟動完畢,在 EOS 控制臺中輸入命令“l(fā)oop”后按回車。EOS 會在斷點處中斷執(zhí)行,表明 loop 線程已經(jīng)開始死循環(huán)了。此時,EOS 中所有的系統(tǒng)線程要么處于就緒狀態(tài)(其優(yōu)先級一定小于 8,例如系統(tǒng)空閑線程) ,要么就處于阻塞狀態(tài)(例如控制臺派遣線程或控制臺線程) ,所以,只有優(yōu)先級為 8 的 loop 線程能夠在處理器上執(zhí)行。接下來按照下面的步驟對斷點進行一些調(diào)整:(1)刪除所有斷點。(2)打開 ps/sched.c 文件,在與線程狀態(tài)轉換相關的函數(shù)中添加斷點,這樣,一旦有線程的狀態(tài)發(fā)生改
27、變,EOS 會中斷執(zhí)行,就可以觀察線程狀態(tài)轉換的詳細過程了。需要添加的斷點有:l 在 PspReadyThread 函數(shù)體中添加一個斷點(第 130 行) 。l 在 PspUnreadyThread 函數(shù)體中添加一個斷點(第 158 行) 。l 在 PspWait 函數(shù)體中添加一個斷點(第 223 行) 。l 在 PspUnwaitThread 函數(shù)體中添加一個斷點(第 282 行) 。l 在 PspSelectNextThread 函數(shù)體中添加一個斷點(第 395 行) 。(3)按 F5 繼續(xù)執(zhí)行,然后激活虛擬機窗口。此時在虛擬機窗口中會看到 loop 線程在不停執(zhí)行,而之前添加的斷點都沒有
28、被命中,說明此時還沒有任何線程的狀態(tài)發(fā)生改變。在開始觀察線程狀態(tài)轉換過程之前還有必要做一個說明。在后面的練習中,會在 loop 線程執(zhí)行的過程中按一次空格鍵,這會導致 EOS 依次執(zhí)行下面的操作:(1)控制臺派遣線程被喚醒,由阻塞狀態(tài)進入就緒狀態(tài)。(2)loop 線程由運行狀態(tài)進入就緒狀態(tài)。(3) 控制臺派遣線程由就緒狀態(tài)進入運行狀態(tài)。(4) 待控制臺派遣線程處理完畢由于空格鍵被按下而產(chǎn)生的鍵盤事件后,派遣線程會由運行狀態(tài)重新進入阻塞狀態(tài),開始等待下一個鍵盤事件到來。(5) loop 線程由就緒狀態(tài)進入運行狀態(tài),繼續(xù)執(zhí)行死循環(huán)2.1,線程由阻塞狀態(tài)進入就緒狀態(tài)按照下面的步驟調(diào)試線程狀態(tài)轉換的過
29、程:1. 在虛擬機窗口中按下一次空格鍵。2. 此時 EOS 會在 PspUnwaitThread 函數(shù)中的斷點處中斷。在“調(diào)試”菜單中選擇“快速監(jiān)視” ,在快速監(jiān)視對話框的表達式編輯框中輸入表達式“*Thread” ,然后點擊“重新計算”按鈕,即可查看線程控制塊(TCB)中的信息。其中 State 域的值為 3(Waiting) ,雙向鏈表項 StateListEntry的 Next 和 Prev 指針的值都不為 0,說明這個線程還處于阻塞狀態(tài),并在某個同步對象的等待隊列中;StartAddr 域的值為 IopConsoleDispatchThread,說明這個線程就是控制臺派遣線程。3. 關
30、閉快速監(jiān)視對話框,激活“調(diào)用堆?!贝翱凇8鶕?jù)當前的調(diào)用堆棧,可以看到是由鍵盤中斷服務程序(KdbIsr)進入的。當按下空格鍵后,就會發(fā)生鍵盤中斷,從而觸發(fā)鍵盤中斷服務程序。在該服務程序的最后中會喚醒控制臺派遣線程,將鍵盤事件派遣到活動的控制臺。4. 在“調(diào)用堆?!贝翱谥须p擊 PspWakeThread 函數(shù)對應的堆棧項??梢钥吹皆诖撕瘮?shù)中連續(xù)調(diào)用了PspUnwaitThread 函數(shù)和 PspReadyThread 函數(shù), 從而使處于阻塞狀態(tài)的控制臺派遣線程進入就緒狀態(tài)。5. 在“調(diào)用堆?!贝翱谥须p擊 PspUnwaitThread 函數(shù)對應的堆棧項,先來看看此函數(shù)是如何改變線程狀態(tài)的。按 F
31、10 單步調(diào)試直到此函數(shù)的最后,然后再從快速監(jiān)視對話框中觀察“*Thread”表達式的值。此時 State 域的值為 0(Zero) ,雙向鏈表項 StateListEntry 的 Next 和 Prev 指針的值都為 0,說明這個線程已經(jīng)處于游離狀態(tài),并已不在任何線程狀態(tài)的隊列中。仔細閱讀PspUnwaitThread 函數(shù)中的源代碼,理解這些源代碼是如何改變線程狀態(tài)的。6. 按 F5 繼續(xù)執(zhí)行,在 PspReadyThread 函數(shù)中的斷點處中斷。按 F10 單步調(diào)試直到此函數(shù)的最后,然后再從快速監(jiān)視對話框中觀察“*Thread”表達式的值。此時 State 域的值為 1(Ready) ,
32、雙向鏈表項 StateListEntry 的 Next 和 Prev 指針的值都不為 0,說明這個線程已經(jīng)處于就緒狀態(tài),并已經(jīng)被放入優(yōu)先級為 24 的就緒隊列中。仔細閱讀 PspReadyThread 函數(shù)中的源代碼,理解這些源代碼是如何改變線程狀態(tài)的。通過以上的調(diào)試,可以將線程由阻塞狀態(tài)進入就緒狀態(tài)的步驟總結如下:(1) 將線程從等待隊列中移除。(2) 將線程的狀態(tài)由 Waiting 修改為 Zero。(3) 將線程插入其優(yōu)先級對應的就緒隊列的隊尾。(4) 將線程的狀態(tài)由 Zero 修改為 Ready。至此,控制臺派遣線程已經(jīng)進入就緒狀態(tài)了,因為其優(yōu)先級(24)比當前處于運行狀態(tài)的 loop
33、 線程的優(yōu)先級(8)要高,根據(jù) EOS 已實現(xiàn)的基于優(yōu)先級的搶先式調(diào)度算法,loop 線程會進入就緒狀態(tài),控制臺派遣線程會搶占處理器從而進入運行狀態(tài)。接下來調(diào)試這兩個轉換過程。2.2,線程由運行狀態(tài)進入就緒狀態(tài)按照下面的步驟調(diào)試線程狀態(tài)轉換的過程:1. 按 F5 繼續(xù)執(zhí)行,在 PspSelectNextThread 函數(shù)中的斷點處中斷。在快速監(jiān)視對話框中查看“*PspCurrentThread”表達式的值,觀察當前占用處理器的線程的情況。其中 State 域的值為 2(Running) ,雙向鏈表項 StateListEntry 的 Next 和 Prev 指針的值都為 0,說明這個線程仍然處
34、于運行狀態(tài),由于只能有一個處于運行狀態(tài)的線程,所以這個線程不在任何線程狀態(tài)的隊列中;StartAddr 域的值為 LoopThreadFunction,說明這個線程就是 loop 線程。注意,在本次斷點被命中之前,loop 線程就已經(jīng)被中斷執(zhí)行了,并且其上下文已經(jīng)保存在線程控制塊中。2. 按 F10 單步調(diào)試,直到對當前線程的操作完成(也就是花括號中的操作完成) 。再從快速監(jiān)視對話框中查看“*PspCurrentThread”表達式的值。其中 State 域的值為 1(Ready) ,雙向鏈表項StateListEntry 的 Next 和 Prev 指針的值都不為 0,說明 loop 線程已
35、經(jīng)進入了就緒狀態(tài),并已經(jīng)被放入優(yōu)先級為 8 的就緒隊列中。 仔細閱讀 PspSelectNextThread 函數(shù)這個花括號中的源代碼,理解這些源代碼是如何改變線程狀態(tài)的,并與 PspReadyThread 函數(shù)中的源代碼進行比較,說明這兩段源代碼的異同,體會為什么在這里不能直接調(diào)用 PspReadyThread 函數(shù)。通過以上的調(diào)試,可以將線程由運行狀態(tài)進入就緒狀態(tài)的步驟總結如下:(1) 線程中斷運行,將線程中斷運行時的上下文保存到線程控制塊中。(2) 如果處于運行狀態(tài)的線程被更高優(yōu)先級的線程搶先,就需要將該線程插入其優(yōu)先級對應的就緒隊列的隊首。 (注意,如果處于運行狀態(tài)的線程主動讓出處理器
36、,例如時間片用完,就需要將程插入其優(yōu)先級對應的就緒隊列的隊尾。 )(3) 將線程的狀態(tài)由 Running 修改為 Ready。至此, loop 線程已經(jīng)進入就緒狀態(tài)了, 接下來調(diào)試控制臺派遣線程會得到處理器進入運行狀態(tài)的過程。2.3: 線程由就緒狀態(tài)進入運行狀態(tài)按照下面的步驟調(diào)試線程狀態(tài)轉換的過程:1. 按 F5 繼續(xù)執(zhí)行, 在 PspUnreadyThread 函數(shù)中的斷點處中斷。 在快速監(jiān)視對話框中查看 “*Thread”表達式的值。其中 State 域的值為 1(Ready) ,雙向鏈表項 StateListEntry 的 Next 和 Prev 指針的值都不為 0,說明這個線程處于就緒
37、狀態(tài),并在優(yōu)先級為 24 的就緒隊列中;StartAddr 域的值為 IopConsoleDispatchThread, 說明這個線程就是控制臺派遣線程。 仔細閱讀 PspUnreadyThread函數(shù)中的源代碼,理解這些源代碼是如何改變線程狀態(tài)的。2. 關閉快速監(jiān)視對話框后,在“調(diào)用堆棧”窗口中激活 PspSelectNextThread 函數(shù)對應的堆棧項,可以看到在 PspSelectNextThread 函數(shù)中已經(jīng)將 PspCurrentThread 全局指針指向了控制臺派遣線程,并在調(diào)用 PspUnreadyThread 函數(shù)后,將當前線程的狀態(tài)改成了 Running。3. 在“調(diào)用堆
38、?!贝翱谥屑せ?PspUnreadyThread 函數(shù)對應的堆棧項,然后按 F10 單步調(diào)試,直到返回 PspSelectNextThread 函數(shù)并將線程狀態(tài)修改為 Running。再從快速監(jiān)視對話框中查看“*PspCurrentThread”表達式的值,觀察當前占用處理器的線程的情況。其中 State 域的值為 2(Running) ,雙向鏈表項 StateListEntry 的 Next 和 Prev 指針的值都為 0,說明控制臺派遣線程已經(jīng)處于運行狀態(tài)了。接下來,會將該線程的上下文從線程控制塊(TCB)復制到處理器的各個寄存器中,處理器就可以從該線程上次停止運行的位置繼續(xù)運行了。通過以
39、上的調(diào)試,可以將線程由就緒狀態(tài)進入運行狀態(tài)的步驟總結如下:(1) 將線程從其優(yōu)先級對應的就緒隊列中移除。(2) 將線程的狀態(tài)由 Ready 修改為 Zero。(3) 將線程的狀態(tài)由 Zero 修改為 Running。(4) 將線程的上下文從線程控制塊(TCB)復制到處理器的各個寄存器中,讓線程從上次停止運行的位置繼續(xù)運行。至此,控制臺派遣線程已經(jīng)開始運行了。因為此時沒有比控制臺派遣線程優(yōu)先級更高的線程來搶占處理器,所以控制臺派遣線程可以一直運行,直到將此次由于空格鍵被按下而產(chǎn)生的鍵盤事件處理完畢,然后控制臺派遣線程會由運行狀態(tài)重新進入阻塞狀態(tài),開始等待下一個鍵盤事件到來。2.4,線程由運行狀態(tài)
40、進入阻塞狀態(tài):按照下面的步驟調(diào)試線程狀態(tài)轉換的過程:1. 按 F5 繼續(xù)執(zhí)行, 在 PspWait 函數(shù)中的斷點處中斷。 在快速監(jiān)視對話框中查看 “*PspCurrentThread”表達式的值,觀察當前占用處理器的線程的情況。其中 State 域的值為 2(Running) ,雙向鏈表項 StateListEntry 的 Next 和 Prev 指針的值都為 0, 說明這個線程仍然處于運行狀態(tài); StartAddr域的值為 IopConsoleDispatchThread,說明這個線程就是控制臺派遣線程。2. 按 F10 單步調(diào)試,直到左側的黃色箭頭指向代碼第 248 行。再從快速監(jiān)視對話框
41、中查看“*PspCurrentThread”表達式的值。其中 State 域的值為 3(Waiting) ,雙向鏈表項StateListEntry 的 Next 和 Prev 指針的值都不為 0,說明控制臺派遣線程已經(jīng)處于阻塞狀態(tài)了,并在某個同步對象的等待隊列中。第 248 行代碼可以觸發(fā)線程調(diào)度功能,會中斷執(zhí)行當前已經(jīng)處于阻塞狀態(tài)的控制臺派遣線程,并將處理器上下文保存到該線程的線程控制塊中。通過以上的調(diào)試,可以將線程由運行狀態(tài)進入阻塞狀態(tài)的步驟總結如下:(1) 將線程插入等待隊列的隊尾。(2) 將線程的狀態(tài)由 Running 修改為 Waiting。(3) 將線程中斷執(zhí)行,并將處理器上下文保
42、存到該線程的線程控制塊中。至此,控制臺派遣線程已經(jīng)進入阻塞狀態(tài)了。因為此時 loop 線程是就緒隊列中優(yōu)先級最高的線程,線程調(diào)度功能會選擇讓 loop 線程繼續(xù)執(zhí)行。按照下面的步驟調(diào)試線程狀態(tài)轉換的過程:1. 按 F5 繼續(xù)執(zhí)行,與本實驗 3.2.3 節(jié)中的情況相同,只不過這次變?yōu)?loop 線程由就緒狀態(tài)進入運行狀態(tài)。2. 再按 F5 繼續(xù)執(zhí)行,EOS 不會再被斷點中斷。激活虛擬機窗口,可以看到 loop 線程又開始不停的執(zhí)行死循環(huán)了。3. 可以再次按空格鍵,將以上的調(diào)試步驟重復一遍。這次調(diào)試的速度可以快一些,仔細體會線程狀態(tài)轉換的過程。3,為線程增加掛起狀態(tài): OS 已經(jīng)實現(xiàn)了一個 sus
43、pend 命令,其命令函數(shù)為 ConsoleCmdSuspendThread(在 ke/sysproc.c 文件的第 843 行) 。在這個命令中調(diào)用了 Suspend 原語(在 ps/psspnd.c 文件第 27 行的 PsSuspendThread 函數(shù)中實現(xiàn)) 。Suspend 原語可以將一個處于就緒狀態(tài)的線程掛起。以 loop 線程為例,當使用 suspend 命令將其掛起時,loop 線程的執(zhí)行計數(shù)就會停止增長。按照下面的步驟觀察 loop 線程被掛起的情況:1. 刪除之前添加的所有斷點。2. 按 F5 啟動調(diào)試。3. 待 EOS 啟動完畢,在 EOS 控制臺中輸入命令“l(fā)oop”
44、后按回車。此時可以看到 loop 線程的執(zhí)行計數(shù)在不停增長,說明 loop 線程正在執(zhí)行。記錄下 loop 線程的 ID。4. 按 Ctrl+F2 切換到控制臺 2,輸入命令“suspend 31” (如果 loop 線程的 ID 是 31)后按回車。5. 按 Ctrl+1 切換回控制臺 1,可以看到由于 loop 線程已經(jīng)成功被掛起,其執(zhí)行計數(shù)已經(jīng)停止增長了。此時占用處理器的是 EOS 中的空閑線程。 四,實驗收獲及感悟: 通過本次實驗,我學會了調(diào)試線程在各種狀態(tài)間的轉化過程,熟悉了線程的狀態(tài)和轉換,在實驗中我通過為線程增加掛起狀態(tài),加深了對線程狀態(tài)的理解。5 實驗截圖:實驗5 進程的同步一
45、.實驗目的1.使用EOS的信號量,編程解決生產(chǎn)者消費者問題,理解進程同步的意義。 2.調(diào)試跟蹤EOS信號量的工作過程,理解進程同步的原理。 3.修改EOS的信號量算法,使之支持等待超時喚醒功能(有限等待),加深理解進程同步的原理。 二.實驗內(nèi)容1 準備實驗2 使用EOS的信號量解決生產(chǎn)者消費者問題3 調(diào)試EOS信號量的工作過程3.1 創(chuàng)建信號量3.2 等待、釋放信號量3.2.1 等待信號量(不阻塞)3.2.2 釋放信號量(不喚醒)3.2.3 等待信號量(阻塞)3.2.4 釋放信號量(喚醒)4 修改EOS的信號量算法三.實驗結果1.按照下面的步驟查看生產(chǎn)者消費者同步執(zhí)行的過程:(1)使用pc.c
46、文件中的源代碼,替換之前創(chuàng)建的EOS應用程序項目中EOSApp.c文件內(nèi)的源代碼。 (2)按F7生成修改后的EOS應用程序項目。 (3)按F5啟動調(diào)試。OS Lab會首先彈出一個調(diào)試異常對話框。 (4)在調(diào)試異常對話框中選擇“否”,繼續(xù)執(zhí)行。 (5)立即激活虛擬機窗口查看生產(chǎn)者消費者同步執(zhí)行的過程 (6)待應用程序執(zhí)行完畢后,結束此次調(diào)試。 2. 等待、釋放信號量(1)等待信號量(不阻塞) 生產(chǎn)者和消費者剛開始執(zhí)行時,用來放產(chǎn)品的緩沖區(qū)都是空的,所以生產(chǎn)者在第一次調(diào)用WaitForSingleObject函數(shù)等待Empty信號量時,應該不需要阻塞就可以立即返回。(2)釋放信號量(不喚醒)生產(chǎn)者
47、線程通過等待Empty信號量使空緩沖區(qū)數(shù)量減少了1,通過釋放Full信號量使?jié)M緩沖區(qū)數(shù)量增加了1,這樣就表示生產(chǎn)者線程生產(chǎn)了一個產(chǎn)品并占用了一個緩沖區(qū)。(3)等待信號量(阻塞) 由于開始時生產(chǎn)者線程生產(chǎn)產(chǎn)品的速度較快,而消費者線程消費產(chǎn)品的速度較慢,所以當緩沖池中所有的緩沖區(qū)都被產(chǎn)品占用時,生產(chǎn)者在生產(chǎn)新的產(chǎn)品時就會被阻塞(4)釋放信號量(喚醒) 只有當消費者線程從緩沖池中消費了一個產(chǎn)品,從而產(chǎn)生一個空緩沖區(qū)后,生產(chǎn)者線程才會被喚醒并繼續(xù)生產(chǎn)14號產(chǎn)品。四.實驗總結今天的實驗的內(nèi)容是進程的同步,這也是進程這一概念提出后面臨的一個非常大的問題,因為當進程在競爭臨界資源時,由于進程的異步性,便會給
48、系統(tǒng)造成混亂,所以能不能讓諸多進程之間有效的共享資源和相互合作,就變成了一個很重要的問題。今天的實驗也讓我們直接的觀察到了EOS操作系統(tǒng)如何通過信號量機制解決進程同步問題,并對程序進行修改,這對我們今后的學習有很大的幫助,但對于解決大量同步操作帶來的系統(tǒng)死鎖問題,我還是欠缺實踐和認識。五.實驗截圖實驗7:物理存儲器與進程邏輯空間的管理一,實驗目的:1,通過查看物理存儲器的使用情況,并練習分配和回收物理內(nèi)存,從而掌握物理存儲器的管理方法。2,通過查看進程邏輯地址空間的使用情況,并練習分配和回收虛擬內(nèi)存,從而掌握進程邏輯地址空間的管理方法。二,預備知識:閱讀本書第 6 章。重點閱讀第 6.3 節(jié)和
49、第 6.6 節(jié),了解物理存儲器的管理方式和進程邏輯地址空間的管理方式。三,主要實驗內(nèi)容及步驟:1,準備實驗;2,閱讀控制臺命令“ pm ”相關的源代碼,并查看其執(zhí)行的結果;3,分配物理頁和釋放物理頁: 接下來,在 pm 命令函數(shù)中添加分配物理頁和釋放物理頁的代碼,單步調(diào)試管理物理頁的方法。按照下面的步驟修改 pm 命令的源代碼:1. 使用 OS Lab 打開本實驗文件夾中的 pm.c 文件(將文件拖動到 OS Lab 窗口中釋放即可打開) 。此文件中有一個修改后的 ConsoleCmdPhysicalMemory 函數(shù),主要是在原有代碼的后面增加了分配物理頁和釋放物理頁的代碼。2. 使用 pm
50、.c 文件中 ConsoleCmdPhysicalMemory 函數(shù)的函數(shù)體替換 ke/sysproc.c 文件中ConsoleCmdPhysicalMemory 函數(shù)的函數(shù)體。3. 按 F7 生成修改后的 EOS Kernel 項目。4. 按 F5 啟動調(diào)試。5. 待 EOS 啟動完畢,在 EOS 控制臺中輸入命令“pm”后按回車。按照下面的步驟調(diào)試分配物理頁和釋放物理頁的過程:1. 結束之前的調(diào)試。2. 在 ke/sysproc.c 文件的 ConsoleCmdPhysicalMemory 函數(shù)中,在調(diào)用 MiAllocateAnyPages 函數(shù)的代碼行(第 1103 行)添加一個斷點,
51、在調(diào)用 MiFreePages 函數(shù)的代碼行(第 1115 行)添加一個斷點。3. 按 F5 啟動調(diào)試。4. 待 EOS 啟動完畢,在 EOS 控制臺中輸入命令“pm”后按回車。5. pm 命令開始執(zhí)行后,會在調(diào)用 MiAllocateAnyPages 函數(shù)的代碼行處中斷,按 F11 調(diào)試進入MiAllocateAnyPages 函數(shù)。6. 按 F10 單步調(diào)試 MiAllocateAnyPages 函數(shù)的執(zhí)行過程,嘗試回答下面的問題:(1) 本次分配的物理頁的數(shù)量是多少?分配的物理頁的頁框號是多少?(2) 物理頁是從空閑頁鏈表中分配的?還是從零頁鏈表中分配的?(3) 哪一行語句減少了空閑頁的
52、數(shù)量?哪一行語句將剛剛分配的物理頁由空閑狀態(tài)修改為忙狀態(tài)?(4) 繪制 MiAllocateAnyPages 函數(shù)的流程圖。繼續(xù)調(diào)試釋放物理頁的過程:1. 按 F5 繼續(xù)執(zhí)行,會在調(diào)用 MiFreePages 函數(shù)的代碼行處中斷,按 F11 調(diào)試進入 MiFreePages 函數(shù)。2. 按 F10 單步調(diào)試 MiFreePages 函數(shù)的執(zhí)行過程,嘗試回答下面的問題:(1) 本次釋放的物理頁的數(shù)量是多少?釋放的物理頁的頁框號是多少?釋放的物理頁是之前分配的物理頁嗎?(2) 釋放的物理頁是被放入了空閑頁鏈表中?還是零頁鏈表中?(3) 繪制 MiFreePages 函數(shù)的流程圖。結束此次調(diào)試。 繼
53、續(xù)修改 pm 命令的源代碼, 嘗試在調(diào)用 MiAllocateAnyPages 函數(shù)時分配多個物理頁,然后在調(diào)用 MiFreePages 函數(shù)時將分配的多個物理頁釋放,并練習調(diào)試這兩個函數(shù)在分配多個物理頁和釋放多個物理頁時執(zhí)行的過程4,閱讀控制臺命令“ vm相關的源代碼,并查看其執(zhí)行結果;5,在系統(tǒng)進程中分配虛擬頁和釋放虛擬頁: 接下來, 在 vm 命令函數(shù)中添加分配虛擬頁和釋放虛擬頁的代碼, 單步調(diào)試管理虛擬頁的方法。 首先,按照下面的步驟修改 vm 命令的源代碼:1. 使用 OS Lab 打開本實驗文件夾中的 vm.c 文件(將文件拖動到 OS Lab 窗口中釋放即可打開) 。此文件中有一
54、個修改后的 ConsoleCmdVM 函數(shù),主要是在原有代碼的后面增加了分配虛擬頁和釋放物理頁的代碼。2. 使用 vm.c 文件中 ConsoleCmdVM 函數(shù)的函數(shù)體替換 ke/sysproc.c 文件中 ConsoleCmdVM 函數(shù)的函數(shù)體。3. 按 F7 生成修改后的 EOS Kernel 項目。4. 按 F5 啟動調(diào)試。5. 待 EOS 啟動完畢,在 EOS 控制臺中輸入命令“vm 1”后按回車。命令執(zhí)行的結果會同時轉儲在“輸出”窗口中。嘗試說明分配虛擬頁或者釋放虛擬頁后虛擬地址描述符以及物理存儲器的變化情況。6,在應用程序進程中,分配虛擬頁和釋放虛擬頁;四,實驗收獲及感悟: 通過
55、本次實驗,讓我學會了通過查看物理存儲器的使用情況,并練習分配和回收物理內(nèi)存,從而掌握物理存儲器的管理方法。以及通過查看進程邏輯地址空間的使用情況,并練習分配和回收虛擬內(nèi)存,從而掌握進程邏輯地址空間的管理方法。五:實驗截圖:實驗8:分頁存儲器的管理一,實驗目的:1,學習 i386 處理器的二級頁表硬件機制,理解分頁存儲器管理原理2,查看 EOS 應用程序進程和系統(tǒng)進程的二級頁表映射信息,理解頁目錄和頁表的管理方式。3,編程修改頁目錄和頁表的映射關系,理解分頁地址變換原理。二,預備知識:閱讀本書第 6 章。了解 i386 處理器的二級頁表硬件機制,EOS 操作系統(tǒng)的分頁存儲器管理方式,以及進程地址
56、空間的內(nèi)存分布。三,主要實驗內(nèi)容及步驟:1,準備實驗;2,查看 EOS應用程序進程的頁目錄和頁表;使用 OS Lab 打開本實驗文件夾中的 memory.c 和 getcr3.asm 文件(將文件拖動到 OS Lab 窗口中釋放即可打開) 。仔細閱讀這兩個文件中的源代碼和注釋,main 函數(shù)的流程圖可以參見圖 16-1。按照下面的步驟查看 EOS 應用程序進程的頁目錄和頁表:1. 使用 memory.c 文件中的源代碼替換之前創(chuàng)建的 EOS 應用程序項目中 EOSApp.c 文件中的源代碼。2. 右鍵點擊“項目管理器”窗口中的“源文件”文件夾節(jié)點,在彈出的快捷菜單中選擇“添加”中的“添加新文件”。3. 在彈出的“添加新文件”對話框中選擇“asm 源文件”模板。4. 在“名稱”中輸入文件名稱“func”。5. 點擊“添加”按鈕添加并自動打開文件 fun
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 英語-福建省莆田市2025屆高中畢業(yè)班第二次教學質量檢測試卷(莆田二檢)試題和答案
- 不銹鋼雨篷施工方案
- 碎石填坑施工方案
- 第二單元課題3 制取氧氣-教學設計-2024-2025學年九年級化學人教版上冊
- 2025年茫茫沙漠大班科學標準教案
- 與駕校有合同范例
- 交通標志線合同范例
- 公司工資合同范例
- 強化員工培訓的年度實施計劃
- 生物課本與現(xiàn)實生活的聯(lián)系計劃
- GB/T 45191-2025桑蠶一代雜交種
- 2025年黑龍江省高職單招《語文》備考重點試題庫(含真題)
- 《抖音營銷教程》課件
- 食材配送服務方案投標文件(技術標)
- 貴州省安順市2025屆高三年級第四次監(jiān)測考試2月語文試題及參考答案
- 2025屆山東核電校園招聘正式啟動筆試參考題庫附帶答案詳解
- 2025年度教育培訓機構股權合作協(xié)議范本
- 2025屆江蘇省無錫市江陰實驗中學中考聯(lián)考歷史試題含解析
- 光伏電站設備故障預防措施
- 2024年蘇州職業(yè)大學高職單招語文歷年參考題庫含答案解析
- 2025天津高考英語作文題目及范文
評論
0/150
提交評論