|
2#
樓主 |
發表於 2008-7-31 13:43:33
|
只看該作者
接著我們看virtual address和physical address的誕生,這邊相當抽象,需要一些想像。- \: Z- Y6 ?2 a/ L
0 M0 O" Y a( |& E
隨著時代進步,越來越多user program產生,user mode的program目前雖然已經不會因為隨意的存取記憶體,造成OS掛點,可是還是有可能去改到別人的記憶體,因為每個程式共同擁有並使用同一個記憶體和所謂的記憶體空間。4 \$ c0 T. F( s" c- l1 E- Y
1 b/ W/ M5 w; ` n3 D
例如:程式A放在0~128 KBytes,程式B放在512~768KBytes,程式A寫錯位置到B程式的地方,變成程式B毀損,B程式就掛掉了。, p9 I; t# P9 i8 ~% G9 \" b/ m9 e. G
! b8 j4 H. y, x4 T# U u( r: T" d; l: l上述的記憶體使用情況,不僅給programmer帶來困擾,而且變成記憶體必須被事先決定好誰只能用哪邊?只能使用多大?這樣不但得事先規劃,對於記憶體的使用也不是很高,因此MMU的硬體便被提出來。 L1 F+ Y9 L! [% j
; T5 \5 w6 B8 M, M
簡單來看,MMU記錄著某個虛擬位置所對應到的實體記憶體的位置。
9 p: `0 P" z& h3 s) w d _) b+ |! n) ^$ @
作業系統利用這個特性,為每一個user program先做了一個假的記憶體,每個程式都以為他有很大很大的記憶體空間,其實當程式呼叫malloc的時候,才會去設置MMU將這個user program的假記憶體空間和真實記憶體做個連結。這邊很難解釋清楚,其實每個程式都有一個假的記憶體空間的紀錄表格,當OS做context switch到某個program的時候,MMU也會跟著切到這個table上,以便用到正確的紀錄表格。
; i% N0 R, h& `/ z% ^- B1 l# F
* ?! H8 {+ v9 W# Z0 P+ o5 I例如:
1 @: k' `& o: E$ [0 d1 f+ k" d
. a m; ?3 D' [. s, ~ q. O1 {$ B程式A的表格記錄了他配置0~4K,而這4K對應到真實記憶體的128K~132K的區段。
4 M, [3 q3 e: O" Q程式B的表格記錄了他配置0~4K,而這4K對應到真實記憶體的132K~136K的區段。
( x n) s* z0 q8 e3 y( e
# I; L# f2 u# [ e3 e, F3 g雖然兩個程式自己都以為他是用到0~4K,可是其實真實記憶體所配到的位置不同,作業系統在切換的時候,會同步將虛擬記憶體的紀錄表格做切換,以便使用到正確的對應表。以上是一種例子,各種OS可能採取的設計方式不同,但是概念大多是一樣的,我們可以看得出來,對每個程式來說,它可以有擁有許多假的連續記憶體空間,對程式撰寫,還有記憶體使用率來說,很有效果。
1 Y, Y) }- I) x1 n$ L4 g9 |( t
到此,CPU多了MMU,現在大多包含MPU的功能。5 d* s2 e8 e& w/ h3 Y3 M0 O6 W
2 V' _/ A) E- D: L
muti-mode CPU + MMU + arbiter bus + memory + DMA
- d7 J8 m: w$ N0 `$ F
5 H- c o4 ] k, z$ Q0 z因此OS在kernel mode的時候,如果MMU是打開的,這時候還是使用virtual address。: {2 u! z, c" ?2 [' j
! _7 F! b$ u. g; Y
要讓mmu正常工作,必須要設定,要讓他知道你對位址的規劃是如何。8 ]; a; _( A0 X0 a* U; U8 |9 z4 r
7 w/ P; W1 |! d0 \1 ?例如:RAM被硬體人員安排到0xFF00 0000的位址,可是你希望RAM被當成從0x0開始,你就可以設定MMU將 0xFF00 0000 對應到 0x0,這樣一來你讀取0x0就會自動轉到0xFF00 0000那邊去。
. ` f9 k* p( m& n: N
# t4 N! M$ @6 ?- o" C/ a, w8 ~+ s0x0000 0000 --< mapping >-- 0xFF00 0000% t* H. Y% a8 K; i5 X
& `/ x2 N; ^/ I
作業系統一開始就會初始化這些位址轉換對應的資訊,把它放在所謂的page table裡面,然後把table位址交給MMU,MMU就會依照table的資訊工作。
- [% d% C/ O! [* Y c2 z3 a
3 t# s g) o8 h/ E; `假如你今天有兩張table,兩張table設定不一樣,MMU只要在這兩張table之間切換,那記憶體對應的方式也會跟著換。
' e/ O0 @- ~2 q W( Z( Y9 u9 \' t' x3 z! M' R
這是一個很重要的想法。假如,我每一個process都有自己的 page table,切換process的時候,table也跟著切換,這樣我可以控制每一個process去存取記憶體的方式。假如我是讓所有的process 都共用一個 table,這樣這個table的設定值,就會影響到所有的process。
9 a# S5 v$ p: [) ~4 ]
0 {: [, s9 E) E# j6 e0 Q共用一個table表示每個process用同一個位址去讀寫,透過MMU轉換到的位址是相同的,會讀寫到同一塊。不共用的話,表示processA和processB即使拿同一個位址0x8000 0000去讀寫,可能最後對應到的位址是不同的。
: h! s- q- l$ }* ]0 B2 I
0 u* _0 `" Z) [3 F但是這樣的差別就是有什麼好處??6 z! P8 O0 I5 ]
. ? y) W9 t; F9 ~3 U因為感覺上複雜化了整個系統,本來我可以很直覺的拿processA傳給我的位址,去讀取它為我準備的資料,現在我可能會因為我使用的 table 不同,就不能在其他process直接使用。感覺很麻煩,要是大家都在同一個 table 工作,不是很簡單嗎?位址空間都是一樣的。
3 `: n! w9 r1 W
& E1 @8 U0 [: H. e; Jwhy?!
! H; Y" {- Z! p1 |$ Y
$ T) q, z1 R9 H字數又超過啦~ |
|