操作系統的一些基本概念

1,幾種進程間的通信方式

管道( pipe ):管道是一種半雙工的通信方式,數據只能單向流動,而且只能在具有親緣關係的進程間使用。進程的親緣關係通常是指父子進程關係。
# 有名管道 (named pipe) : 有名管道也是半雙工的通信方式,但是它允許無親緣關係進程間的通信。
# 信號量( semophore ) : 信號量是一個計數器,可以用來控制多個進程對共享資源的訪問。它常作爲一種鎖機制,防止某進程正在訪問共享資源時,其他進程也訪問該資源。因此,主要作爲進程間以及同一進程內不同線程之間的同步手段。
消息隊列( message queue ) : 消息隊列是由消息的鏈表,存放在內核中並由消息隊列標識符標識。消息隊列克服了信號傳遞信息少、管道只能承載無格式字節流以及緩衝區大小受限等缺點
# 信號 ( sinal ) : 信號是一種比較複雜的通信方式,用於通知接收進程某個事件已經發生。
共享內存( shared memory ) :共享內存就是映射一段能被其他進程所訪問的內存,這段共享內存由一個進程創建,但多個進程都可以訪問。共享內存是最快的 IPC 方式,它是針對其他進程間通信方式運行效率低而專門設計的。它往往與其他通信機制,如信號兩,配合使用,來實現進程間的同步和通信。
# 套接字( socket ) : 套解口也是一種進程間通信機制,與其他通信機制不同的是,它可用於不同及其間的進程通信。




2,進程同步與互斥

圖比較多,參看操作系統原理



3,內核態與用戶態

當一個任務(進程)執行系統調用而執行內核代碼時,稱進程處於內核內核態此時處理器處於特權級最高的(0級)內核代碼中執行當進程處於內核態時,執行的內核代碼會使用當前進程的內核棧,每個進程都有自己的內核棧。當進程執行用戶代碼時,稱其處於用戶態此時處理器在特權級最低的(3級)用戶代碼中運行。

當正在執行用戶程序而突然被中斷程序中斷時,此時用戶程序也可以象徵性地稱爲處於進程的內核,因爲中斷處理程序將使用當前進程的內核棧。這與處於內核態的進程的狀態有些類似。內核態與用戶態是操作系統的兩種運行級別,intel cpu沒有必然的聯繫,intel cpu提供Ring0-Ring3三種級別的運行模式,Ring0級別最高,Ring3最低。

Linux使用了Ring3級別運行用戶態,Ring0作爲內核態,沒有使用Ring1Ring2Ring3狀態不能訪問Ring0的地址空間,包括代碼和數據。Linux進程的4GB地址空間,3G-4G部分大家是共享的,是內核態的地址空間,這裏存放在整個內核的代碼和所有的內核模塊,以及內核所維護的數據。用戶運行一個程序,該程序所創建的進程開始是運行在用戶態的,如果要執行文件操作,網絡數據發送等操作,必須通過writesend等系統調用,這些系統調用會調用內核中的代碼來完成操作,這時,必須切換到Ring0,然後進入3GB-4GB中的內核地址空間去執行這些代碼完成操作,完成後,切換回Ring3,回到用戶態。這樣,用戶態的程序就不能隨意操作內核地址空間,具有一定的安全保護作用。

保護模式,通過內存頁表操作等機制,保證進程間的地址空間不會互相沖突,一個進程的操作不會修改另一個進程的地址空間中的數據在內核態下,CPU可執行任何指令,在用戶態下CPU只能執行非特權指令。當CPU處於內核態,可以隨意進入用戶態;而當CPU處於用戶態,只能通過中斷的方式進入內核態。一般程序一開始都是運行於用戶態,當程序需要使用系統資源時,就必須通過調用軟中斷進入內核態.

使用nm查看用戶態程序的符號表內容

使用System.map(內核符號表)查看內核符號表內容

1) 測試程序中打印用戶態函數地址,並調用系統調用(在內核中打印系統調用函數地址),用"用戶態符號表""內核態符號表"示例說明內核態和用戶態地址空間的差異

  2) 說明內核態地址映射ioremap();用戶態地址映射mmap()



4,系統調用

在系統中真正被所有進程都使用的內核通信方式是系統調用。例如當進程請求內核服務時,就使用的是系統調用。一般情況下,進程是不能夠存取系統內核的。它不 能存取內核使用的內存段,也不能調用內核函數,CPU的硬件結構保證了這一點。只有系統調用是一個例外。進程使用寄存器中適當的值跳轉到內核中事先定義好 的代碼中執行,(當然,這些代碼是隻讀的)。在Intel結構的計算機中,這是由中斷0x80實現的。

    進程可以跳轉到的內核中的位置叫做system_call。在此位置的過程檢查系統調用號,它將告訴內核進程請求的服務是什麼。然後,它再查找系統調用表sys_call_table,找到希望調用的內核函數的地址,並調用此函數,最後返回。

    所以,如果希望改變一個系統調用的函數,需要做的是編寫一個自己的函數,然後改變sys_call_table中的指針指向該函數,最後再使用cleanup_module將系統調用表恢復到原來的狀態

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章