作業系統 第五節 系統呼叫的實現
文章目錄
1 系統呼叫的直觀實現
實現一個 whoami 系統呼叫,使用者程式呼叫whoami,一個字串"userName"放在作業系統中,取出來列印
使用者程式和OS都在記憶體中,想要列印"userName"為什麼不直接jmp到OS核心中列印它,而間接的採用whoami系統呼叫實現?
1,OS中存在許多重要的資料,不能隨意的呼叫資料,不能隨意的jmp
2,使用者程式如果可以直接訪問OS,那麼root密碼等其它重要資訊會被暴露甚至被修改
2 核心(使用者)態,核心(使用者)段
硬體設計將核心程式和使用者程式隔離,區分了核心態和使用者態,在記憶體中對應的記憶體段稱為核心段和使用者段
由於CS:IP指示當前執行指令的地址,所以用CS的最低兩位表示:0是核心態,3是使用者態,核心態可以訪問任何資料,使用者態不能訪問核心資料,對於記憶體段和指令跳轉都實現了隔離
為了隔離核心段和使用者段,採用DPL(目標記憶體段的特權級)和CPL(當前記憶體段的特權級),在head.s執行時,會對核心態的程式碼和資料建立gdt表,設定其DPL為0,啟動使用者程式時,設定使用者段的CPL為3,使用者態下執行時CPL均為3
對於標題1中的程式,使用者程式執行在使用者態,指令和資料屬於使用者段,OS處於核心態,OS內的資料與指令處於核心段,此時應用程式想要列印處於OS中的"userName",此時目標記憶體段是OS即核心段,當前記憶體段是應用程式即使用者段,DPL=0,CPL=3,此時應用程式中的指令不能訪問核心段,核心段拒絕了來自低特權級使用者段的想直接訪問核心段的jmp等指令
由於處於使用者態的應用程式無法直接訪問處於核心態的核心段資料,所以提供了系統呼叫來解決問題
3 硬體提供了 “主動進入核心的方法”
對於x86計算機,進入核心的唯一方法是中斷指令 int,這是使用者程式發起的呼叫核心程式碼的唯一方式
系統呼叫表面上是一個函式,但實際上它包含了 int 指令的一段程式,通過中斷來進入核心
系統呼叫的核心:
1,使用者程式中包含了一段包含int指令的程式碼
2,作業系統寫中斷處理,獲取想調程式的編號
3,作業系統根據編號執行相應程式碼
4 系統呼叫的實現
如想要列印字串的系統呼叫過程:
真正完成作業的是write()系統呼叫,printf()函式要先展開為庫函式printf(),由於引數的不匹配,需要轉換成write()庫函式,由系統呼叫write()訪問OS,完成作業,一開始的printf()函式被最終展開成一段包含 int指令的程式碼,然後才能進入核心