Chip123 科技應用創新平台

 找回密碼
 申請會員

QQ登錄

只需一步,快速開始

Login

用FB帳號登入

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

Linux 下的 mmap()

[複製鏈接]
跳轉到指定樓層
1#
發表於 2008-8-4 15:17:18 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
以下希望藉由一個實際可以在user mode運作的API, mmap()% C: z5 A, X+ b
讓programmer能夠感受到MMU這個硬體在系統中所扮演的角色
" t& B& t8 D. Y( ]0 @4 t+ F' s9 w7 Z' t  u. H- F: z1 S3 ^
寫linux底下driver的人常常會看到這個東西 mmap()" M" q* [2 X/ i0 W( m/ p
在user mode program裡面假如你用open( "/dev/xxx", ... )6 z' h+ `: i$ z, i, ~
去打開一個檔案系統的節點
5 j4 G% {$ D, `% u5 }. d7 p就可以用這個file descriptor的handler對他做mmap()的動作  L$ q( e4 R$ b9 O5 I+ Y
那這個mmap究竟背後藏了哪些意義?
: ?5 \0 x9 m! b; Q又有哪些硬體在工作才能達成?
0 P5 P0 u! }3 N2 Y+ u2 V7 D6 ?7 q% Y2 H8 E/ i6 t; l4 P  [+ a
mmap的字面意義是memory map' N2 J) p4 A! y" T7 Y! s4 v) g
顧名思義就是『記憶體映對』
4 P# d3 N) L$ ~; s簡單來看,就是用mmap()幫你做對映
! y9 \- ?# _# Q: ]; M3 w; o對映好了,對著傳回的address作存取" {! Q, X% \$ {/ k5 Q
就等於對檔案作存取
2 N4 I7 N3 V6 u6 }; p4 x3 u$ [2 |: q7 k3 K; A9 w" B3 F/ d) n: G
1. 首先來看mmap()一般是怎麼被使用的 (這邊可以先不用管要傳什麼參數)0 V/ x4 w( [" W$ d3 r
int fd, mapSize, offset, start;) E- P5 x( a6 q( K; A
char* ptr;
$ h' u; t0 v. j( }8 V3 H" Z" L" U  j( P: p1 ?
mapSize = 0x1000; /* 希望映對多大的區塊 */& k3 w9 Z# F# R" S5 F
offset = 0;9 ?' z( Y, e" }; n9 J* h$ B
start = 0;
; w# g. W; d+ y  ^/* 打開檔案 */, @  j5 A" P; {: J+ L9 n; W# f2 g
fd = open( "/home/tester/a.txt", O_RDWR | O_SYNC );  : k; h: N7 @" \
/* 作mmap動作,取得一個對應好的address */
" x$ O& m( K$ N- kptr = mmap( 0, map_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset );
+ }/ G( R2 T6 B% ~# m7 r+ j, ~1 w; Z3 ]* G9 T. h6 @
假如一切順利的話 ptr 就會接到一個address,這個address會對應到a.txt這個檔案所在的起始位置,
/ {) O! Y; H! Y如果這時候我們用 strcpy( ptr, "hello!!" );
& F" m3 V3 C# E/ C( P. I  K+ s
0 w4 b% G- L( Q; Ba.txt裡面就會被寫入"hello!!"的字串+ B( |8 ~( q: P" W& U8 u! T0 ~
5 u& s3 M/ g5 S, n- r* |  N
2. 假如我寫了兩個程式,都是用mmap()到同一個a.txt,程式會不會出問題? 如果不會,那我既然對同一個檔案作mmap(),那我拿到的ptr不是應該是相同的address?
. ~0 B1 K3 u" Z- [2 e! H, O0 n+ R6 @
答案是:兩個程式可以正常執行,但是這兩個回傳的address不一定相同。7 G2 H& f) Z4 ?' i
why?  為什麼對同一個檔案寫入,也都做同樣的mmap()動作,甚至傳的參數值都相同。
' G. a; @8 r/ e6 B: z+ E為什麼拿到的address可以是不同的? 更奇怪的是,位址不同,還是同樣寫到同一個檔案上頭。
' G3 F  n6 r% A! V) m" s
/ [  f2 h" `3 V+ b4 P; H假如這一切都是合理的,那表示雖然這兩個位址不一定相同,其實都是對映同一個地方,表示有某種東西記錄著這個對應關係。而且,兩個program的ptr有時候會一樣,可是有時候又不一樣。唯一個可能是表示兩個process各自保有這些映對的方式。
, z+ H! f' ?# c3 s, T, ^+ ^( B  B2 z6 J8 @- f
3. 假設我只寫一個程式,但是mmap()兩次到同一個檔案上呢? 得到的兩個ptr會一樣嗎?/ I6 ~% z% k& s6 C

) x# N) O* X4 E! e0 ^. B7 f2 q答案是:這個兩ptr還是不一樣的,兩個不同program 跑出來的mmap()結果不同也就算了,同一個program呼叫兩次mmap()跑出來的ptr也不一樣,但又都對映著相同的檔案a.txt。因此我們又可以猜測這一個mmap()是動態的,動態去產生一種應對的方式,將傳回的ptr對應到真正的檔案a.txt去,所以同一個process可以對應好幾次,好幾次都用不同的address去對映到相同的檔案上去。6 M0 k) d+ J- l7 I

* V$ C' k6 Q# ]$ t: j綜合上面三種現象,我們合理的懷疑系統裡面存在了一個東西,它讓每一個process可以動態地記錄address的對應關係。並且,每個process各自擁有這個table,而這些對映的關係會動態的反應在這個table當中。/ m( _3 |1 Z1 b- l) p
  W$ O8 p& [, I9 [- ^- M$ c
回想一下一個系統有誰會做這種工作,不就是MMU所擔任的重要角色嗎?. D" M2 r0 z2 c6 Q* r$ O! q
每個process各自擁有自己的 page table 當他呼叫mmap()的時候,系統就動態地幫她在這個table上寫上紀錄著  t( E" n, P. t: ]
4 ~6 Y. F$ }! U% w2 ]1 ~
[processA-pgtable]
/ ^+ w8 h- T, @3 v; ?! V0x00008000 ptr1 --> a.txt
5 ]  w- s- R: D# {0 X, F& I0xa0008000 ptr2 --> a.txt
* [  z* `/ a3 b" g7 {  m! T* h6 W+ `+ G3 _; m
[processB-pgtable]% J1 @4 j+ p/ W* N7 V: V
0x00008000 ptr1 --> a.txt
, H# g2 L9 n- K) t' c) z' l0xb0008000 ptr2 --> a.txt( @& t- a7 Q% r2 G$ F! i
; c$ k- X- i  J# }" f
這樣ptr1, ptr2都可以對應到相同的地方,又因為各個process又有不同table,所以有時候ptr1有可能會相同。
9 R9 X, y' Z7 M0 }7 O如此一來,我們終於可以合理的解釋我們觀察mmap()為何對映出來的address會有如此的表現。原來就是MMU被加入,而且OS又被設計成每個process都會各自擁有一個page table來記錄他對記憶體如何解讀。

評分

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

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享分享 頂 踩 分享分享
2#
 樓主| 發表於 2008-8-4 15:20:27 | 只看該作者
略寫下兩個延伸的想像問題
( ^4 C$ M0 l! M1 f. x或許有人有興趣可以回答或是深入研究. j2 y7 [( p6 O4 O+ d. F
9 g' n6 x- x3 e/ A% L+ }* Z$ ]
[延伸想像]8 a2 o4 I) Y, _% P+ m8 v# v
我們又可以仔細想想假如每個process都有各自的table
# K) R5 v: ]  G7 T! `! {那麼從一個process做context switch到另外一個process的時候  `; ?  o% F1 X8 v: |
代表所用的table是不同的
6 D, z- b) a) w3 ~# I0 z8 J+ {8 c1 c# [wow!!!可想而知系統是很忙碌的,1秒鐘context switch 10次就要替mmu切換10次page table的mmap方式) {: H# t, H9 k
不然process用錯page table可能就會指到錯誤的位址, Q5 s4 W0 B$ t: w$ Y' c+ D& |
那OS到底怎麼切換這些page table?
" b- W- a! ]7 u8 |1 Qkernel和user program的page table有什麼不同??, u$ Q3 C# y0 u; }+ t) s3 h: |
/ N" b5 `5 V5 w3 G! \
[延伸想像]8 y- a) v( o$ |: f
假如我們可以修改page table的權利,是不是就可以寫出一個可以偷取別的process data的東西?因為我可以偷偷的map過去他的address space讀取它的資料??    有辦法嗎? 還是根本沒機會?
您需要登錄後才可以回帖 登錄 | 申請會員

本版積分規則

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

GMT+8, 2025-1-22 07:03 PM , Processed in 0.156000 second(s), 19 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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