Chip123 科技應用創新平台

 找回密碼
 申請會員

QQ登錄

只需一步,快速開始

Login

用FB帳號登入

搜索
1 2 3 4
查看: 3962|回復: 1
打印 上一主題 下一主題

Linux 下的 mmap()

[複製鏈接]
跳轉到指定樓層
1#
發表於 2008-8-4 15:17:18 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
以下希望藉由一個實際可以在user mode運作的API, mmap(); F& ~* X. W7 @% z7 |5 p- w6 Z2 @/ D7 j
讓programmer能夠感受到MMU這個硬體在系統中所扮演的角色. e* T9 {) D8 @% u) g2 B- {
4 Q: @/ ^! F! a3 |+ w# c! }6 v5 p
寫linux底下driver的人常常會看到這個東西 mmap()
4 \6 M5 W, y- E- d, I在user mode program裡面假如你用open( "/dev/xxx", ... )4 n6 H6 z  B8 h/ R9 j
去打開一個檔案系統的節點
0 B  t4 H3 k7 E就可以用這個file descriptor的handler對他做mmap()的動作& ]* `2 I: G  ?/ m
那這個mmap究竟背後藏了哪些意義?
8 p- \4 s8 ]( k( l# z1 I又有哪些硬體在工作才能達成?. ?6 q: Y! C% P  A
; I5 Z3 Z5 ?0 `) x4 @
mmap的字面意義是memory map
5 n: [+ D, \3 G. s2 K8 h顧名思義就是『記憶體映對』
* S- u0 ^- B/ z) g7 F簡單來看,就是用mmap()幫你做對映) e: l! }$ j& \# b# k0 {0 Y
對映好了,對著傳回的address作存取( X6 ?8 E- P) a4 M
就等於對檔案作存取
( X7 _- O$ U; D
0 b. Q. U5 }, z( k1 E# N( ?1. 首先來看mmap()一般是怎麼被使用的 (這邊可以先不用管要傳什麼參數)
3 c2 {* g- I; ?  f& s% hint fd, mapSize, offset, start;
8 C% Q) f2 i: xchar* ptr;
6 W/ x! u2 r6 ~" Z% C" Z; }
0 G' S/ V. L* t* r9 L: C+ vmapSize = 0x1000; /* 希望映對多大的區塊 */! R( w7 M. d4 M
offset = 0;
/ C( }. \8 n$ Ystart = 0;
' u5 e# A6 I/ f! G/* 打開檔案 */
$ ~9 \5 J, b. d" R6 Tfd = open( "/home/tester/a.txt", O_RDWR | O_SYNC );  
; e& J% g3 X# k5 q- P/ h2 t/* 作mmap動作,取得一個對應好的address */+ @) x( z% m4 h2 S  S3 E: l& q1 Z
ptr = mmap( 0, map_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset );+ D4 d  W. u# S

/ Q, Z; y! G8 \7 b; N( `6 e/ J假如一切順利的話 ptr 就會接到一個address,這個address會對應到a.txt這個檔案所在的起始位置,
& g/ U# c* f5 U9 l7 H& A如果這時候我們用 strcpy( ptr, "hello!!" );
0 I5 R1 ^% j& _; Q
' X! Z3 v+ f6 S: w  ta.txt裡面就會被寫入"hello!!"的字串
' E+ x. l. y2 M" n
$ v. C3 b3 @0 X" L. s2 Z7 b2. 假如我寫了兩個程式,都是用mmap()到同一個a.txt,程式會不會出問題? 如果不會,那我既然對同一個檔案作mmap(),那我拿到的ptr不是應該是相同的address?
. F5 E1 I9 R/ Q* `6 q- _- f  P7 ^+ I( C: l
答案是:兩個程式可以正常執行,但是這兩個回傳的address不一定相同。
3 j1 s0 B+ a/ O% _6 I7 E3 {why?  為什麼對同一個檔案寫入,也都做同樣的mmap()動作,甚至傳的參數值都相同。
5 ~. r! q' K; a4 E) N$ H/ {為什麼拿到的address可以是不同的? 更奇怪的是,位址不同,還是同樣寫到同一個檔案上頭。; D) ]! L' F( W- `

  c- F3 K. N9 s# m假如這一切都是合理的,那表示雖然這兩個位址不一定相同,其實都是對映同一個地方,表示有某種東西記錄著這個對應關係。而且,兩個program的ptr有時候會一樣,可是有時候又不一樣。唯一個可能是表示兩個process各自保有這些映對的方式。
" _% R" u: Y6 I# v# K
2 o2 z1 b; \6 p4 Z$ Z: S3. 假設我只寫一個程式,但是mmap()兩次到同一個檔案上呢? 得到的兩個ptr會一樣嗎?  O5 u/ W9 }) \( b: }: g
0 I! T0 ]$ C0 i' E  d
答案是:這個兩ptr還是不一樣的,兩個不同program 跑出來的mmap()結果不同也就算了,同一個program呼叫兩次mmap()跑出來的ptr也不一樣,但又都對映著相同的檔案a.txt。因此我們又可以猜測這一個mmap()是動態的,動態去產生一種應對的方式,將傳回的ptr對應到真正的檔案a.txt去,所以同一個process可以對應好幾次,好幾次都用不同的address去對映到相同的檔案上去。
% }( O" U3 t5 y  ^" M) N3 p, _4 T( m6 {; z. h- I
綜合上面三種現象,我們合理的懷疑系統裡面存在了一個東西,它讓每一個process可以動態地記錄address的對應關係。並且,每個process各自擁有這個table,而這些對映的關係會動態的反應在這個table當中。3 b& L# Y( o% E$ m
- }2 b+ D( s/ p; r0 U( i. z
回想一下一個系統有誰會做這種工作,不就是MMU所擔任的重要角色嗎?
# X! N$ i' }  @0 A- f( i* }; T每個process各自擁有自己的 page table 當他呼叫mmap()的時候,系統就動態地幫她在這個table上寫上紀錄著
8 |1 Q9 t* W: n- u  H! v+ I- w- W# D% a# D: S0 p
[processA-pgtable]6 W; A4 B/ e& V8 ^- o5 M
0x00008000 ptr1 --> a.txt6 n0 R- l. L. Y. M/ L# \
0xa0008000 ptr2 --> a.txt% J- X4 P4 X/ J! D
6 ^" m) z) {. y  s; A
[processB-pgtable]# O" `; Y3 h: i& F# M
0x00008000 ptr1 --> a.txt
6 s7 N8 T$ d" T1 T: b9 j- R0xb0008000 ptr2 --> a.txt) }) e5 }1 F# M* }$ K

$ k' L5 g+ y; n1 E這樣ptr1, ptr2都可以對應到相同的地方,又因為各個process又有不同table,所以有時候ptr1有可能會相同。
$ O5 u6 E! Z+ q% ?如此一來,我們終於可以合理的解釋我們觀察mmap()為何對映出來的address會有如此的表現。原來就是MMU被加入,而且OS又被設計成每個process都會各自擁有一個page table來記錄他對記憶體如何解讀。

評分

參與人數 1Chipcoin +5 收起 理由
jacky002 + 5 以資鼓勵,再接再厲!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享分享 頂 踩 分享分享
2#
 樓主| 發表於 2008-8-4 15:20:27 | 只看該作者
略寫下兩個延伸的想像問題
/ f- F* r  J/ x0 X或許有人有興趣可以回答或是深入研究8 ]! z. \- m4 X: G, y

$ e5 u1 e! ?/ h2 f2 T[延伸想像]+ p) D' Y9 C  b
我們又可以仔細想想假如每個process都有各自的table
9 j  I0 Z8 Y: m( D  Z那麼從一個process做context switch到另外一個process的時候
. `/ H! o3 `+ s& L/ L" g( ^代表所用的table是不同的
8 E1 h( q9 O7 `+ `- m9 V* ewow!!!可想而知系統是很忙碌的,1秒鐘context switch 10次就要替mmu切換10次page table的mmap方式
" y9 O  l& k# ]1 q+ U9 ], v* J8 l不然process用錯page table可能就會指到錯誤的位址/ O. n/ |5 {( y! v6 X' W
那OS到底怎麼切換這些page table?
: t9 H, B+ }2 g; ^+ N4 fkernel和user program的page table有什麼不同??
5 b- [+ g0 a7 }% I! C) @& d: f9 N3 S2 C. L& A5 w% ~
[延伸想像], Q) p' s! }/ z
假如我們可以修改page table的權利,是不是就可以寫出一個可以偷取別的process data的東西?因為我可以偷偷的map過去他的address space讀取它的資料??    有辦法嗎? 還是根本沒機會?
您需要登錄後才可以回帖 登錄 | 申請會員

本版積分規則

首頁|手機版|Chip123 科技應用創新平台 |新契機國際商機整合股份有限公司

GMT+8, 2025-1-23 01:10 AM , Processed in 0.156001 second(s), 19 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回復 返回頂部 返回列表