1. 程式人生 > >linux之使用者空間和核心空間

linux之使用者空間和核心空間

linux驅動程式一般工作在核心空間,但也可以工作在使用者空間。下面我們將詳細解析,什麼是核心空間,什麼是使用者空間,以及如何判斷他們。
Linux簡化了分段機制,使得虛擬地址與線性地址總是一致,因此,Linux的虛擬地址空間也為0~4G。Linux核心將這4G位元組的空間分為兩部分。將最高的1G位元組(從虛擬地址0xC0000000到0xFFFFFFFF),供核心使用,稱為“核心空間”。而將較低的3G位元組(從虛擬地址 0x00000000到0xBFFFFFFF),供各個程序使用,稱為“使用者空間)。因為每個程序可以通過系統呼叫進入核心,因此,Linux核心由系統內的所有程序共享。於是,從具體程序的角度來看,每個程序可以擁有4G位元組的虛擬空間。

    Linux使用兩級保護機制:0級供核心使用,3級供使用者程式使用。從圖中可以看出(這裡無法表示圖),每個程序有各自的私有使用者空間(0~3G),這個空間對系統中的其他程序是不可見的。最高的1GB位元組虛擬核心空間則為所有程序以及核心所共享。

  核心空間中存放的是核心程式碼和資料,而程序的使用者空間中存放的是使用者程式的程式碼和資料。不管是核心空間還是使用者空間,它們都處於虛擬空間中。 
雖然核心空間佔據了每個虛擬空間中的最高1GB位元組,但對映到實體記憶體卻總是從最低地址(0x00000000)開始。對核心空間來說,其地址對映是很簡單的線性對映,0xC0000000就是實體地址與線性地址之間的位移量,在Linux程式碼中就叫做PAGE_OFFSET。


核心空間和使用者空間之間如何進行通訊? 
核心空間和使用者空間一般通過系統呼叫進行通訊。 


如何判斷一個驅動是使用者模式驅動還是核心模式驅動?  判斷的標準是什麼? 

使用者空間模式的驅動一般通過系統呼叫來完成對硬體的訪問,如通過系統呼叫將驅動的io空間對映到使用者空間等。因此,主要的判斷依據就是系統呼叫。 
核心空間和使用者空間上不同太多了,說不完,比如使用者態的連結串列和核心連結串列不一樣;使用者態用printf,核心態用printk;使用者態每個應用程式空間是虛擬的,相對獨立的,核心態中卻不是獨立的,所以程式設計要非常小心。等等。

還有使用者態和核心態程式通訊的方法很多,不單單是系統呼叫,實際上系統呼叫是個不好的選擇,因為需要系統呼叫號,這個需要統一分配。 
可以通過ioctl、sysfs、proc等來完成。

 

 

核心態和使用者態

 

當一個任務(程序)執行系統呼叫而陷入核心程式碼中執行時,我們就稱程序處於核心執行態(或簡稱為核心態)。此時處理器處於特權級最高的(0級)核心程式碼中執行。當程序處於核心態時,執行的核心程式碼會使用當前程序的核心棧。每個程序都有自己的核心棧。當程序在執行使用者自己的程式碼時,則稱其處於使用者執行態(使用者態)。即此時處理器在特權級最低的(3級)使用者程式碼中執行。當正在執行使用者程式而突然被中斷程式中斷時,此時使用者程式也可以象徵性地稱為處於程序的核心態。因為中斷處理程式將使用當前程序的核心棧。這與處於核心態的程序的狀態有些類似。



程序上下文和中斷上下文

 

處理器總處於以下狀態中的一種:

1、核心態,運行於程序上下文,核心代表程序運行於核心空間;

2、核心態,運行於中斷上下文,核心代表硬體運行於核心空間;

3、使用者態,運行於使用者空間。

使用者空間的應用程式,通過系統呼叫,進入核心空間。這個時候使用者空間的程序要傳遞很多變數、引數的值給核心,核心態執行的時候也要儲存使用者程序的一些暫存器值、變數等。所謂的“程序上下文”,可以看作是使用者程序傳遞給核心的這些引數以及核心要儲存的那一整套的變數和暫存器值和當時的環境等。

硬體通過觸發訊號,導致核心呼叫中斷處理程式,進入核心空間。這個過程中,硬體的一些變數和引數也要傳遞給核心,核心通過這些引數進行中斷處理。所謂的“中斷上下文”,其實也可以看作就是硬體傳遞過來的這些引數和核心需要儲存的一些其他環境(主要是當前被打斷執行的程序環境)。