內核態與用戶態【轉載】

?原文:http://blog.csdn.net/skywalkzf/article/details/5185442

內核態與用戶態是操作系統的兩種運行級別,intel cpu提供Ring0-Ring3三種級別的運行模式。Ring0級別最高,Ring3最低。其中特權級0(Ring0)是留給操作系統代碼,設備驅動程序代碼使用的,它們工作于系統核心態;而特權極3(Ring3)則給普通的用戶程序使用,它們工作在用戶態。運行于處理器核心態的代碼不受任何的限制,可以自由地訪問任何有效地址,進行直接端口訪問。而運行于用戶態的代碼則要受到處理器的諸多檢查,它們只能訪問映射其地址空間的頁表項中規定的在用戶態下可訪問頁面的虛擬地址,且只能對任務狀態段(TSS)中I/O許可位圖(I/O Permission Bitmap)中規定的可訪問端口進行直接訪問(此時處理器狀態和控制標志寄存器EFLAGS中的IOPL通常為0,指明當前可以進行直接I/O的最低特權級別是Ring0)。以上的討論只限于保護模式操作系統,象DOS這種模式操作系統則沒有這些概念,其中的所有代碼都可被看作運行在核心態。
  當一個任務(進程)執行系統調用而陷入內核代碼中執行時,我們就稱進程處于內核運行態(或簡稱為內核態)。此時處理器處于特權級最高的(0級) 內核代碼中執行。當進程處于內核態時,執行的內核代碼會使用當前進程的內核棧。每個進程都有自己的內核棧。當進程在執行用戶自己的代碼時,則稱其處于用戶運行態(用戶態)。即此時處理器在特權級最低的(3級)用戶代碼中運行。
  在內核態下CPU可執行任何指令,在用戶態下CPU只能執行非特權指令。當CPU處于內核態,可以隨意進入用戶態;而當CPU處于用戶態時,用戶從用戶態切換到內核態只有在系統調用和中斷兩種情況下發生,一般程序一開始都是運行于用戶態,當程序需要使用系統資源時,就必須通過調用軟中斷進入內核態。
  Linux使用了Ring3級別運行用戶態,Ring0作為內核態,沒有使用Ring1和Ring2。Ring3狀態不能訪問Ring0的地址空間,包括代碼和數據。Linux進程的4GB地址空間,3G-4G部分大家是共享的,是內核態的地址空間,這里存放在整個內核的代碼和所有的內核模塊,以及內核所維護的數據。用戶運行一個程序,該程序所創建的進程開始是運行在用戶態的,如果要執行文件操作,網絡數據發送等操作,必須通過 write,send等系統調用,這些系統調用會調用內核中的代碼來完成操作,這時,必須切換到Ring0,然后進入3GB-4GB中的內核地址空間去執行這些代碼完成操作,完成后,切換回Ring3,回到用戶態。這樣,用戶態的程序就不能隨意操作內核地址空間,具有一定的安全保護作用。
處理器模式從Ring3向Ring0的切換發生在控制權轉移時,有以下兩種情況:訪問調用門的長轉移指令CALL,訪問中斷門或陷阱門的INT指令。具體的轉移細節由于涉及復雜的保護檢查和堆棧切換,不再贅述,請參閱相關資料。現代的操作系統通常使用中斷門來提供系統服務,通過執行一條陷入指令來完成模式切換,在INTEL X86上這條指令是INT,如在WIN9X下是INT30(保護模式回調),在LINUX下是INT80,在WINNT/2000下是INT2E。用戶模式的服務程序(如系統DLL)通過執行一個INTXX來請求系統服務,然后處理器模式將切換到核心態,工作于核心態的相應的系統代碼將服務于此次請求并將結果傳給用戶程序。
?
一,中斷處理過程

硬件中斷:來自時鐘,外設

可編程中斷:programmed interrupt,執行引起軟件中斷的指令。

例外中斷:如頁面錯。

都由系統負責處理。當發生一個中斷時,如果CPU正在比該中斷級低的處理機運行級上運行,它就在解碼下條指令之前,接受該中斷,并提高處理機運行級。內核處理中斷的操作順序如下:

1,對于正在進行的進程,保存其當前寄存器上下文,并創建壓入一個新的上下文層。

2,確定中斷源,識別中斷類型。如是時鐘或磁盤的。

3,查找中斷向量。當系統接受一個中斷時,它從機器中得到一個數,系統把這個作為查表的偏移量。這個表通常成為中斷向量(interrupt vector)。中斷向量的內容包括各種中斷源的中斷處理程序的地址,以及中斷處理程序取得參數的方式。

4,內核調用中斷處理程序。

5,中斷處理程序執行那個返回,恢復(彈出)前一上下文層。

二,軟中斷

軟中斷通知進程發生了異步事件。

系統有個進程表,每個進程在進程表中有有個進程表項,每個進程表項有個軟中斷信號字段,紀錄發向一個進程的所有未處理的軟中斷信號。

當一個進程即將從核心態返回到用戶態時,或它要進入或離開一個適當的低調度優先級時,內核要檢查它是否收到了一個軟中斷信號。

內核僅當一個進程從核心態返回到用戶態時才處理軟中斷信號。

三,系統調用

我們在C程序中調用系統調用好像是個一般的函數調用,當實際上調用系統調用會引起用戶態到核心態的狀態變化,這是怎么做到的呢?

原來,C編譯程序采用一個預定義的函數庫(C之程序庫),其中的函數具有系統調用的名字,從而解決了在用戶程序中請求系統調用的問題。這些庫函數一般都執行一條指令,該指令將進程的運行方式變為核心態,然后,使內核開始為系統調用執行代碼。我們稱這個指令為操作系統陷入(operating system trap)。

系統調用的接口是一個中斷處理程序的特例。

在處理操作系統陷入時,

1,內核根據系統調用號查系統調用入口表,找到相應的內核子程序的地址。

2,內核還要確定該系統調用所要求的參數個數。

3,從用戶地址空間拷貝參數到U區(Unix V)。

4,保存當前上下文,執行系統調用代碼。

核心態:當CPU正在運行內核代碼時(內核代碼是共享的)。

用戶態:當CPU正在運行用戶代碼時。

用戶模式:不可以訪問內核空間(>=0x80000000)

內核模式:可以訪問任何有效虛擬地址,包括內核空間。一個線程可以訪問其他任何線程地址空間。

轉載于:https://www.cnblogs.com/candycloud/p/3959774.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/376678.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/376678.shtml
英文地址,請注明出處:http://en.pswp.cn/news/376678.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

解決ListView異步加載數據之后不能點擊的問題

在ListView的onScroll事件中執行異步加載數據,然后使用notifyDataSetChange()函數更新適配器,之后發現listView不能點擊了,這問題苦惱了我半天。最后在一篇博文中發現調用listView的requestFocusFromTouch()函數終于解決了這問題。 Java代碼…

從WebRtc學習RTCP協議

文章目錄RTCP支持的消息類型RTCP協議頭WebRTC的反饋報文RTPFB支持的報文類型:PSFB支持的報文類型:參考RTCP是RTP的控制協議.那么RTCP能對RTP做哪些控制呢?其中最為大家熟知的就是 丟包控制。發送端發送數據后,接收端如果發現有RTP…

白話經典算法系列之中的一個 冒泡排序的三種實現

冒泡排序是很easy理解和實現,,以從小到大排序舉例: 設數組長度為N。 1.比較相鄰的前后二個數據,假設前面數據大于后面的數據,就將二個數據交換。 2.這樣對數組的第0個數據到N-1個數據進行一次遍…

如何用java代碼讓android Market顯示指定的程序以便用戶下載?

Uri uri Uri.parse("market://search?q名稱");Intent i new Intent("Intent.ACTION_VIEW", uri);startActivity(i);//根據應用程序ID應用程序的包名Uri urii Uri.parse("market://details?idcom.xiaoqiu.test");Intent ii new Intent(&quo…

無鎖隊列設計思路以及簡要代碼

文章目錄非并發的一寫一讀環形隊列多讀多寫環形隊列非并發的一寫一讀環形隊列 讀指針: 1、先判斷是否有數據 2、讀取數據 3、操作指針 寫指針: 1、先判斷空間是否足夠 2、寫入數據 3、操作指針 所以代碼也十分簡單: bool putqueue(void* pDa…

vs 2012,vs 2013問題系列

系統環境: 64位 win7 1,問題: 之前能連接tfs進行源碼管理,期間有改過本地電腦的時間,再后來使用vs 2012連接tfs卻失敗了。錯誤碼:TF31002。排除了網絡問題,用戶權限問題,tfs服務器問…

Linux查看系統信息的一些命令

轉:http://www.cnblogs.com/chenwenbiao/archive/2011/07/18/2109983.html 系統 # uname -a # 查看內核/操作系統/CPU信息 # head -n 1 /etc/issue # 查看操作系統版本 # cat /proc/cpuinfo # 查看CPU信息 # hostname # 查看計…

CPU Cache對于并發編程的影響

文章目錄引子CPU Cache對于并發的影響讀寫順序對性能的影響字節對齊對Cache的影響小結引子 下面給出兩個極其相似的代碼&#xff0c;運行出的時間卻是有很大差別&#xff1a; 代碼一 #include <stdio.h> #include <pthread.h> #include <stdint.h> #includ…

textarea 在瀏覽器中固定大小和禁止拖動

http://blog.sina.com.cn/s/blog_641d569301011naz.html HTML 標簽 textarea 在大部分瀏覽器中只要指定行&#xff08;rows&#xff09;和列&#xff08;cols&#xff09;屬性&#xff0c;就可以規定 textarea 的尺寸&#xff0c;大小就不會改變&#xff0c;不過更好的辦法是使…

hibernate操作時報錯

報錯&#xff1a;[ERROR] AbstractBatcher Exception executing batch: org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1原因&#xff1a;視具體情況而定&#xff0c;我這邊是代碼被修改過…

bugfix:MySQL內存使用率無限增長以及kill手法

問題&#xff1a;昨天mysql 宕機了一次&#xff0c;重啟&#xff0c;然后繼續運行業務代碼的時候發現問題&#xff0c;mysql內存占用率上升較快&#xff0c;于是搜了搜&#xff0c;遇到一個&#xff1a; http://blog.itpub.net/29510932/viewspace-2129312/ 根據思路&#xff0…

軟工之初識

我們之前已經在完全不懂軟件工程的情況下&#xff0c;已經做完了兩個小系統&#xff0c;雖然能夠運行&#xff0c;但其中有很多的問題&#xff0c;學習軟工就是讓我們在工程學原理的指導之下去開發和設計軟件。 軟件工程同大多數書講的都是一樣的&#xff0c;首先對軟件工程有一…

perf +火焰圖使用

以mysqld進程為例&#xff1a; [rootVM-90-225-centos ~]# ps -ef | grep mysqld root 9808 9621 0 19:30 pts/7 00:00:00 grep --colorauto mysqld root 16104 1 0 17:30 pts/0 00:00:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --datadir/usr/loc…

Mysql 遇到的編碼問題。

今天幫小朋友做一個項目&#xff0c;碰到一個挺搞的問題。在幫她安裝mysql的時候一直是next&#xff0c;沒有去注意一些細節&#xff0c;不曉得有沒有漏掉設置編碼那一部分。。 結果在用sql文件導入數據庫MySQL -h localhost -u root -p xxx < e:\xxx.sql 執行的時候錯誤提…

在一個字符串中找到第一個只出現一次的字符

題目&#xff1a;在一個字符串中找到第一個只出現一次的字符&#xff0c;如輸入abaccdeff&#xff0c;則輸出b&#xff1b;具體實現如下&#xff1a;#include <iostream> #include <string> using namespace std; void FindChar(const string &strBuf) {int nA…

py腳本:獲取進程信息

這里以mysqld進程為例子 # pip install psutil import psutil import time import re, sys# x:進程name y:非進程name # 由于這里監控的是mysqld&#xff0c;如果不加限制的話會先識別mysqld_safe&#xff0c;所以要加上mysql_safe的判別 def processinfo(x, y):p_list psut…

sysctl -P 報錯解決辦法

sysctl -P 報錯解決辦法問題癥狀修改 linux 內核文件 #vi /etc/sysctl.conf后執行sysctl -P 報錯error: "net.bridge.bridge-nf-call-ip6tables" is an unknown keyerror: "net.bridge.bridge-nf-call-iptables" is an unknown keyerror: "net.bridg…

-bash: belts.awk: command not found

執行awk命令時&#xff0c;沒有問題。可是執行awk腳本時&#xff0c;出現這個問題&#xff1a;-bash: belts.awk: command not found。 既然之前直接執行awk命令沒有問題&#xff0c;說明awk已經裝了&#xff0c;本身是沒有問題的。那就說明路徑不對&#xff0c;執行echo $PATH…

nagios快速安裝

1、安裝軟件包&#xff08;準備軟件包&#xff09; yum install httpd gcc glibc glibc-common gd gd-devel 2、建立一個賬戶 創建一個名為nagios的帳號并給定登錄口令 /usr/sbin/useradd nagios passwd nagios 創建一個用戶組名為nagcmd用于從Web接口執行外部命令。將nagios用…

零拷貝機制在文件傳輸中的使用手法

文章目錄文件傳輸&#xff08;讀取與發送&#xff09;中的拷貝與上下文切換零拷貝技術sendfilesendfile SG-DMAmmap writespliceDirect I/O經典應用文件傳輸&#xff08;讀取與發送&#xff09;中的拷貝與上下文切換 如果服務端要提供文件傳輸的功能&#xff0c;最簡單的方式…