「您只要在mymain.c基礎上繼續寫程序描述pcb和程序鍊錶管理等**,在myinterrupt.c的基礎上完成程序切換**,乙個可執行的小os kernel就完成了。」
孟老師在課程公告中對mykernel做了簡明的講解:
「理解和執行mykernel,它是提供初始化好的cpu從my_start_kernel開始執行,並提供了時鐘中斷機制週期性執行my_time_handler中斷處理程式,執行完後中斷返回總是可以回到my_start_kernel中斷的位置繼續執行。當然中斷儲存現場恢復現場的細節都處理好了,mykernel就是乙個邏輯上的硬體平台,具體怎麼做到的一般不必深究。」
這裡主要分析一下mymain.c和myinterupt.c中的相關**是如何在kernel啟動中發揮作用的。
首先,我們從pcb.h談起:
該標頭檔案中定義了乙個兩個結構體,第乙個是struct thread,它用來儲存執行緒的ip和sp。另外乙個是pcb(程序控制塊),這是作業系統中乙個很重要的資料結構,所有關於程序的資訊都儲存在pcb中,這裡**中簡化了pcb的結構,只給出了一些最基本的資訊,如pid(程序號),程序狀態,程式入口位址,核心堆疊,執行緒資訊等。
有了pcb這個資料結構,我們就可以用它來建立程序或者在進行程序間切換時儲存資訊。
我們再來看mymain.c檔案,mykernel核心是從my_start_kernel函式開始執行的,所以我們在該函式中首先建立程序,建立程序的方法就是填充pcb的資訊。
我們可以從**中看出,這裡講pcb實現成了乙個環形佇列,每次建立新的程序時,都將該程序插入到佇列的最後乙個位置,然後將該程序指向第乙個程序。
建立好程序之後,該函式中最重要的一段**出現了,該部分利用嵌入式彙編來啟動0號程序。
**首先將pcb中的sp資訊放入esp暫存器,然後將ebp壓棧(因為此時程序堆疊為空棧,所以壓入esp相當於ebp),第三第四句我們將eip壓棧然後ret(即pop eip),下一條指令就會跳轉到0號程序的第一條指令開始執行,在這裡就是my_process()。
my_process幹了一件很簡單的事情,就是迴圈等待並print程序id,然後觀察變數my_need_sched是否為1,如果是則主動進入排程函式my_schedule開始執行。
my_schedule函式在myinterupt.c中,在分析該函式之前,我們先看一下該檔案中的另乙個函式,my_timer_handler。
mykernel提供了時鐘中斷機制,週期性執行my_time_handler中斷處理程式,該函式定時觀察my_need_sched是否不等於1,如果是則將其置為1,使myprocess執行my_schedule()。
這時我們分析一下my_schedule,該函式在pcb環形佇列中選擇下乙個程序進行執行,但對於處於不同狀態的程序,排程方式略有不同,如果即將上cpu的程序之前已經執行過(即state為0),我們儲存當前程序的資訊,然後把下乙個程序的資訊寫入到暫存器中,執行ret使下乙個程序開始執行。
之前沒有在執行態的(state不為0),我們先將其設定為執行態,我們這裡需要初始化其ebp,因為該程序的堆疊是空棧esp=ebp。
至此,我們的mini kernel的執行分析完畢。
mykernel的執行與初步分析
黃二玉 linux核心分析 mooc課程 預備知識 內嵌彙編 內嵌彙編語法 asm 彙編語句模板 輸出部分 輸入部分 破壞描述部分 同時 asm 也可以由 asm 來代替,asm 是 asm 的別名。在 asm 後面有時也會加上 volatile 表示編譯器不要優化 後面的指令保留原樣,volati...
從OpenTsdb來分析rowkey設計
討論此問題前,先理解乙個問題。關於hbase熱點問題 當處理由連續事件得到的資料時,即時間上連續的資料。這些資料可能來自於某個感測器網路 交易或者乙個監控系統。它們顯著的特點就是rowkey中含有事件發生時間。帶來的乙個問題便是hbase對於row的不均衡分布,它們被儲存在乙個唯一的rowkey區間...
從JMM資料原子操作來分析volatile
併發程式設計的三個性質 原子性,可見性,有序性 兩線程同時對i做i 執行緒1往記憶體寫經過匯流排時被執行緒2感知到了,執行緒2做i 的操作已經做完了,然而因為感知到i變了,做i無效化重新讀,所以執行緒2做的那次i 的操作執行了但是沒起作用 在討論原子性操作時,我們經常會聽到乙個說法 任意單個vola...