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等來完成。