內(nèi)存
每個(gè)內(nèi)存單元有一個(gè)地址內(nèi)存地址是從0開始編號(hào)的整數(shù),CPU通過地址找到相應(yīng)的內(nèi)存單元,取其中的指令或者讀寫其中的數(shù)據(jù)。一個(gè)地址所對(duì)應(yīng)的內(nèi)存單元只能存一個(gè)字節(jié),像int、float等多字節(jié)的數(shù)據(jù)類型保存在內(nèi)存中要占用連續(xù)的多個(gè)地址,它們的地址是它所占內(nèi)存單元的起始地址。
CPU
CPU最核心的功能單元包括:
Register (寄存器)
寄存器是CPU內(nèi)部的高速存儲(chǔ)器,像內(nèi)存一樣可以存取數(shù)據(jù),但比訪問內(nèi)存快得多。
一些寄存器可以用在各種運(yùn)算和讀寫內(nèi)存的指令中,比如eax寄存器,這稱為通用寄存器(General-purpose Register)。
一些寄存器只能用于某種特定的用途,比如eip用作程序計(jì)數(shù)器,這稱為特殊寄存器(Special-purpose Register)。
PC (Program Counter,程序計(jì)數(shù)器)
程序計(jì)數(shù)器是一種特殊寄存器,保存著CPU取下一條指令的地址,CPU按程序計(jì)數(shù)器保存的地址去內(nèi)存中取指令然后解釋執(zhí)行,這時(shí)程序計(jì)數(shù)器保存的地址會(huì)自動(dòng)加上該指令的長(zhǎng)度,指向內(nèi)存中的下一條指令。
Instruction Decoder (指令譯碼器)
CPU取上來的指令由若干個(gè)字節(jié)組成,這些字節(jié)中有些位表示內(nèi)存地址,有些位表示寄存器編號(hào),有些位表示這種指令做什么操作,是加減乘除還是讀寫內(nèi)存,指令譯碼器負(fù)責(zé)解釋這條指令的含義,然后調(diào)動(dòng)相應(yīng)的執(zhí)行單元去執(zhí)行它。
ALU (Arithmetic and Logic Unit,算術(shù)邏輯單元)
如果譯碼器將一條指令解釋為運(yùn)算指令,就調(diào)動(dòng)算術(shù)邏輯單元去做運(yùn)算,比如加減乘除、位運(yùn)算、邏輯運(yùn)算。指令中會(huì)指示運(yùn)算結(jié)果保存到哪里,可能保存到寄存器中,也可能保存到內(nèi)存中。
Bus (地址和數(shù)據(jù)總線)。
CPU和內(nèi)存之間用地址總線、數(shù)據(jù)總線和控制線連接起來,每條線上有1和0兩種狀態(tài)。
從CPU訪問內(nèi)存
如果在執(zhí)行指令過程中需要訪問內(nèi)存,比如從內(nèi)存讀一個(gè)數(shù)到寄存器,執(zhí)行過程可以想像成這樣:
1.CPU內(nèi)部將寄存器對(duì)接到數(shù)據(jù)總線上,使寄存器的每一位對(duì)接到一條數(shù)據(jù)線,等待接收數(shù)據(jù)。
2.CPU通過控制線發(fā)一個(gè)讀請(qǐng)求,并且將內(nèi)存地址通過地址線發(fā)給內(nèi)存。
3.內(nèi)存收到地址和讀請(qǐng)求之后,將相應(yīng)的內(nèi)存單元對(duì)接到數(shù)據(jù)總線的另一端,這樣,內(nèi)存單元每一位的1或0狀態(tài)通過一條數(shù)據(jù)線到達(dá)CPU寄存器中相應(yīng)的位,就完成了數(shù)據(jù)傳送。
上圖中畫了32條地址線和32條數(shù)據(jù)線,CPU寄存器也是32位,可以說這種體系結(jié)構(gòu)是32位的,比如x86就是這樣的體系結(jié)構(gòu),目前主流的處理器是32位或64位的。地址線、數(shù)據(jù)線和CPU寄存器的位數(shù)通常是一致的,從上圖可以看出數(shù)據(jù)線和CPU寄存器的位數(shù)應(yīng)該一致,另外有些寄存器(比如程序計(jì)數(shù)器)需要保存一個(gè)內(nèi)存地址,因而地址線和CPU寄存器的位數(shù)也應(yīng)該一致。32位計(jì)算機(jī)有32條地址線,地址空間(Address Space)從0x00000000到0xffffffff,共4GB,而64位計(jì)算機(jī)有更大的地址空間。
這里的的地址線、數(shù)據(jù)線是指CPU的內(nèi)總線,是直接和CPU的執(zhí)行單元相連的,內(nèi)總線經(jīng)過MMU和總線接口的轉(zhuǎn)換之后引出到芯片引腳才是外總線,外地址線和外數(shù)據(jù)線的位數(shù)都有可能和內(nèi)總線不同,例如32位處理器的外地址總線可尋址的空間可以大于4GB。
CPU從內(nèi)存中取值
1.eip寄存器指向地址0x80483a2,CPU從這里開始取一條5個(gè)字節(jié)的指令,然后eip寄存器指向下一條指令的起始地址0x80483a7。
2.CPU對(duì)這5個(gè)字節(jié)譯碼,得知這條指令要求從地址0x804a01c開始取4個(gè)字節(jié)保存到eax寄存器。
3.執(zhí)行指令,讀內(nèi)存,取上來的數(shù)是3,保存到eax寄存器。注意,地址0x804a01c~0x804a01f里存儲(chǔ)的四個(gè)字節(jié)不能按地址從低到高的順序看成0x03000000,而要按地址從高到低的順序看成0x00000003。也就是說,對(duì)于多字節(jié)的整數(shù)類型,低地址保存的是整數(shù)的低位,這稱為小端(Little Endian)字節(jié)序(Byte Order)。x86平臺(tái)是小端字節(jié)序的,而另外一些平臺(tái)規(guī)定低地址保存整數(shù)的高位,稱為大端(Big Endian)字節(jié)序。
4.CPU從eip寄存器指向的地址取一條3個(gè)字節(jié)的指令,然后eip寄存器指向下一條指令的起始地址0x80483aa。
5.CPU對(duì)這3個(gè)字節(jié)譯碼,得知這條指令要求把eax寄存器的值加1,結(jié)果仍保存到eax寄存器。
6.執(zhí)行指令,現(xiàn)在eax寄存器中的數(shù)是4。
7.CPU從eip寄存器指向的地址取一條5個(gè)字節(jié)的指令,然后eip寄存器指向下一條指令的起始地址0x80483af。
8.CPU對(duì)這5個(gè)字節(jié)譯碼,得知這條指令要求把eax寄存器的值保存到從地址0x804a018開始的4個(gè)字節(jié)。
9.執(zhí)行指令,把4這個(gè)值保存到從地址0x804a018開始的4個(gè)字節(jié)(按小端字節(jié)序保存)。
設(shè)備
CPU訪問設(shè)備的兩種方式:
Memory-mapped I/O (內(nèi)存映射I/O)
圖中①②訪問這種設(shè)備就像訪問內(nèi)存一樣(略有不同,如下表),按地址讀寫即可。比如ARM。
Port I/O (端口I/O)
圖中③需要用一種專用的in/out指令訪問。比如x86。
第三種方式:設(shè)備總線
由于計(jì)算機(jī)的設(shè)備五花八門,于是出現(xiàn)了各種適應(yīng)不同要求的設(shè)備總線,設(shè)備總線的控制器也是一種設(shè)備。CPU通過內(nèi)存映射I/O或端口I/O訪問相應(yīng)的總線控制器,通過總線控制器再去訪問掛在總線上的設(shè)備。
比如PCI、AGP、USB、1394、SATA等等,這些設(shè)備是掛在設(shè)備總線上的。
上圖中標(biāo)有“設(shè)備”的框都可能是實(shí)際的設(shè)備,也可能是設(shè)備總線的控制器。
Interrupt中斷機(jī)制
每個(gè)設(shè)備都有一條中斷線,通過中斷控制器連接到CPU,當(dāng)設(shè)備需要主動(dòng)通知CPU時(shí)就引發(fā)一個(gè)中斷信號(hào),CPU正在執(zhí)行的指令將被打斷,程序計(jì)數(shù)器會(huì)指向某個(gè)固定的地址(這個(gè)地址由體系結(jié)構(gòu)定義),于是CPU從這個(gè)地址開始取指令(或者說跳轉(zhuǎn)到這個(gè)地址),執(zhí)行中斷服務(wù)程序(ISR,Interrupt Service Routine),完成中斷處理之后再返回先前被打斷的地方執(zhí)行后續(xù)指令。
比如某種體系結(jié)構(gòu)規(guī)定發(fā)生中斷時(shí)跳轉(zhuǎn)到地址0x00000010執(zhí)行,那么就要事先把一段ISR程序加載到這個(gè)地址,ISR程序是內(nèi)核代碼的一部分,在這段代碼中首先判斷是哪個(gè)設(shè)備引發(fā)了中斷,然后調(diào)用該設(shè)備的中斷處理函數(shù)做進(jìn)一步處理。
設(shè)備寄存器
設(shè)備中可供讀寫訪問的單元通常稱為設(shè)備寄存器(注意和CPU寄存器不是一回事)。
操作設(shè)備的過程就是讀寫這些設(shè)備寄存器的過程,比如向串口發(fā)送寄存器里寫數(shù)據(jù),串口設(shè)備就會(huì)把數(shù)據(jù)發(fā)送出去,讀串口接收寄存器的值,就可以讀取串口設(shè)備接收到的數(shù)據(jù)。
硬盤
在x86平臺(tái)上,硬盤是掛在IDE、SATA或SCSI總線上的設(shè)備,保存在硬盤上的程序是不能被CPU直接取指令執(zhí)行的,操作系統(tǒng)在執(zhí)行程序時(shí)會(huì)把它從硬盤拷貝到內(nèi)存,這樣CPU才能取指令執(zhí)行。
操作系統(tǒng)
Operating System(操作系統(tǒng))本身也是一段保存在磁盤上的程序,計(jì)算機(jī)在啟動(dòng)時(shí)執(zhí)行一段固定的啟動(dòng)代碼(稱為Bootloader)首先把操作系統(tǒng)從磁盤加載到內(nèi)存,然后執(zhí)行操作系統(tǒng)中的代碼把用戶需要的其它程序加載到內(nèi)存。
操作系統(tǒng)最核心的功能是管理進(jìn)程調(diào)度、管理內(nèi)存的分配使用和管理各種設(shè)備,做這些工作的程序稱為Kernel(內(nèi)核),在我的系統(tǒng)上內(nèi)核程序是/boot/vmlinuz-2.6.28-13-generic文件,它在計(jì)算機(jī)啟動(dòng)時(shí)加載到內(nèi)存并常駐內(nèi)存。
廣義上操作系統(tǒng)的概念還包括一些必不可少的用戶程序,比如Shell是每個(gè)Linux系統(tǒng)必不可少的,而Office辦公套件則是可有可無的,所以前者也屬于廣義上操作系統(tǒng)的范疇,而后者屬于應(yīng)用軟件。
設(shè)備驅(qū)動(dòng)程序
由于各種設(shè)備的操作方法各不相同,每種設(shè)備都需要專門的Device Driver(設(shè)備驅(qū)動(dòng)程序),一個(gè)操作系統(tǒng)為了支持廣泛的設(shè)備就需要有大量的設(shè)備驅(qū)動(dòng)程序,事實(shí)上Linux內(nèi)核源代碼中絕大部分是設(shè)備驅(qū)動(dòng)程序。設(shè)備驅(qū)動(dòng)程序通常是內(nèi)核里的一組函數(shù),通過讀寫設(shè)備寄存器實(shí)現(xiàn)對(duì)設(shè)備的初始化、讀、寫等操作,有些設(shè)備還要提供一個(gè)中斷處理函數(shù)供ISR調(diào)用。
MMU
現(xiàn)代操作系統(tǒng)普遍采用Virtual Memory Management(虛擬內(nèi)存管理)機(jī)制,這需要處理器中的MMU(Memory Management Unit,內(nèi)存管理單元)提供支持。
PA物理地址
如果處理器沒有MMU,或者有MMU但沒有啟用,CPU執(zhí)行單元發(fā)出的內(nèi)存地址將直接傳到芯片引腳上,被內(nèi)存芯片(以下稱為物理內(nèi)存,以便與虛擬內(nèi)存區(qū)分)接收,這稱為PA(Physical Address,物理地址)。
VA虛擬地址
如果處理器啟用了MMU,CPU執(zhí)行單元發(fā)出的內(nèi)存地址將被MMU截獲,從CPU到MMU的地址稱為VA(Virtual Address,虛擬地址),而MMU將這個(gè)地址翻譯成另一個(gè)地址發(fā)到CPU芯片的外部地址引腳上,也就是將VA映射成PA
如果是32位處理器,則內(nèi)地址總線是32位的,與CPU執(zhí)行單元相連(右圖只是示意性地畫了4條地址線),而經(jīng)過MMU轉(zhuǎn)換之后的外地址總線則不一定是32位的。也就是說,虛擬地址空間和物理地址空間是獨(dú)立的,32位處理器的虛擬地址空間是4GB,而物理地址空間既可以大于也可以小于4GB。
MMU將VA映射到PA是以Page(頁)為單位的,32位處理器的頁尺寸通常是4KB。例如,MMU可以通過一個(gè)映射項(xiàng)將VA的一頁0xb70010000xb7001fff映射到PA的一頁0x20000x2fff,如果CPU執(zhí)行單元要訪問虛擬地址0xb7001008,則實(shí)際訪問到的物理地址是0x2008。物理內(nèi)存中的頁稱為Page Frame(物理頁面或者頁幀)。
虛擬內(nèi)存的哪個(gè)頁面映射到物理內(nèi)存的哪個(gè)頁幀是通過Page Table(頁表)來描述的,頁表保存在物理內(nèi)存中,MMU會(huì)查找頁表來確定一個(gè)VA應(yīng)該映射到什么PA。
操作系統(tǒng)和MMU是這樣配合的:
1.操作系統(tǒng)在初始化或分配、釋放內(nèi)存時(shí)會(huì)執(zhí)行一些指令在物理內(nèi)存中填寫頁表,然后用指令設(shè)置MMU,告訴MMU頁表在物理內(nèi)存中的什么位置。
2.設(shè)置好之后,CPU每次執(zhí)行訪問內(nèi)存的指令都會(huì)自動(dòng)引發(fā)MMU做查表和地址轉(zhuǎn)換操作,地址轉(zhuǎn)換操作由硬件自動(dòng)完成,不需要用指令控制MMU去做。
我們?cè)诔绦蛑惺褂玫淖兞亢秃瘮?shù)都有各自的地址,程序被編譯后,這些地址就成了指令中的地址,指令中的地址被CPU解釋執(zhí)行,就成了CPU執(zhí)行單元發(fā)出的內(nèi)存地址,所以在啟用MMU的情況下,程序中使用的地址都是虛擬地址,都會(huì)引發(fā)MMU做查表和地址轉(zhuǎn)換操作。
MMU除了做地址轉(zhuǎn)換之外,還提供內(nèi)存保護(hù)機(jī)制。 各種體系結(jié)構(gòu)都有User Mode(用戶模式)和Privileged Mode(特權(quán)模式)之分,操作系統(tǒng)可以在頁表中設(shè)置每個(gè)內(nèi)存頁面的訪問權(quán)限,有些頁面不允許訪問,有些頁面只有在CPU處于特權(quán)模式時(shí)才允許訪問,有些頁面在用戶模式和特權(quán)模式都可以訪問,訪問權(quán)限又分為可讀、可寫和可執(zhí)行三種。這樣設(shè)定好之后,當(dāng)CPU要訪問一個(gè)VA時(shí),MMU會(huì)檢查CPU當(dāng)前處于用戶模式還是特權(quán)模式,訪問內(nèi)存的目的是讀數(shù)據(jù)、寫數(shù)據(jù)還是取指令,如果和操作系統(tǒng)設(shè)定的頁面權(quán)限相符,就允許訪問,把它轉(zhuǎn)換成PA,否則不允許訪問,產(chǎn)生一個(gè)Exception(異常)。
異常的處理過程和中斷類似,不同的是中斷由外部設(shè)備產(chǎn)生而異常由CPU內(nèi)部產(chǎn)生,中斷產(chǎn)生的原因和CPU當(dāng)前執(zhí)行的指令無關(guān),而異常的產(chǎn)生就是由于CPU當(dāng)前執(zhí)行的指令出了問題,例如訪問內(nèi)存的指令被MMU檢查出權(quán)限錯(cuò)誤,除法指令的除數(shù)為0等都會(huì)產(chǎn)生異常。
通常操作系統(tǒng)把虛擬地址空間劃分為用戶空間和內(nèi)核空間,例如x86平臺(tái)的Linux系統(tǒng)虛擬地址空間是0x000000000xffffffff,前3GB(0x000000000xbfffffff)是用戶空間,后1GB(0xc0000000~0xffffffff)是內(nèi)核空間。用戶程序加載到用戶空間,在用戶模式下執(zhí)行,不能訪問內(nèi)核中的數(shù)據(jù),也不能跳轉(zhuǎn)到內(nèi)核代碼中執(zhí)行。這樣可以保護(hù)內(nèi)核,如果一個(gè)進(jìn)程訪問了非法地址,頂多這一個(gè)進(jìn)程崩潰,而不會(huì)影響到內(nèi)核和整個(gè)系統(tǒng)的穩(wěn)定性。CPU在產(chǎn)生中斷或異常時(shí)不僅會(huì)跳轉(zhuǎn)到中斷或異常服務(wù)程序,還會(huì)自動(dòng)切換模式,從用戶模式切換到特權(quán)模式,因此從中斷或異常服務(wù)程序可以跳轉(zhuǎn)到內(nèi)核代碼中執(zhí)行。事實(shí)上,整個(gè)內(nèi)核就是由各種中斷和異常處理程序組成的。總結(jié)一下:在正常情況下處理器在用戶模式執(zhí)行用戶程序,在中斷或異常情況下處理器切換到特權(quán)模式執(zhí)行內(nèi)核程序,處理完中斷或異常之后再返回用戶模式繼續(xù)執(zhí)行用戶程序。
Segmentation fault (段錯(cuò)誤)的產(chǎn)生過程:
1.用戶程序要訪問的一個(gè)VA,經(jīng)MMU檢查無權(quán)訪問。
2.MMU產(chǎn)生一個(gè)異常,CPU從用戶模式切換到特權(quán)模式,跳轉(zhuǎn)到內(nèi)核代碼中執(zhí)行異常服務(wù)程序。
3.內(nèi)核把這個(gè)異常解釋為段錯(cuò)誤,把引發(fā)異常的進(jìn)程終止掉。
存儲(chǔ)器
Memory Hierarchy
-
處理器
+關(guān)注
關(guān)注
68文章
19740瀏覽量
232898 -
寄存器
+關(guān)注
關(guān)注
31文章
5401瀏覽量
122794 -
計(jì)算機(jī)
+關(guān)注
關(guān)注
19文章
7607瀏覽量
89840 -
ISR
+關(guān)注
關(guān)注
0文章
38瀏覽量
14647 -
中斷控制器
+關(guān)注
關(guān)注
0文章
60瀏覽量
9604
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論