Chip123 科技應用創新平台

 找回密碼
 申請會員

QQ登錄

只需一步,快速開始

Login

用FB帳號登入

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

Linux 下的 mmap()

[複製鏈接]
跳轉到指定樓層
1#
發表於 2008-8-4 15:17:18 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
以下希望藉由一個實際可以在user mode運作的API, mmap()# X2 L6 {4 t7 K+ V6 m5 x0 R
讓programmer能夠感受到MMU這個硬體在系統中所扮演的角色! [1 l' N( M1 b! |1 L& k" e0 v
3 c9 L- U- q# [' {
寫linux底下driver的人常常會看到這個東西 mmap()$ A. _- W  o) T1 w9 @  b6 M# O
在user mode program裡面假如你用open( "/dev/xxx", ... )
6 H0 G& Y7 _( K; ^$ R去打開一個檔案系統的節點
: j* r5 Y* g8 j0 @就可以用這個file descriptor的handler對他做mmap()的動作# }3 Q. R$ g" t0 Y; f9 d
那這個mmap究竟背後藏了哪些意義?
& n4 L9 v: {' V7 F  D: R又有哪些硬體在工作才能達成?
' D( K  \) }- s; B6 D
0 W( R& v7 _7 E; A# I9 gmmap的字面意義是memory map- w! Q- L) j  {" e$ o* \5 j" v
顧名思義就是『記憶體映對』: s# G9 c. |, {4 O+ \0 u: ?
簡單來看,就是用mmap()幫你做對映2 X9 u$ w4 P& a' Z
對映好了,對著傳回的address作存取
9 w  N% y7 @$ b8 ~  Q4 {4 \. U6 R3 U" K就等於對檔案作存取
) E. _* o% g. D1 I( @7 n) _& k* i$ b3 b# W  \1 B
1. 首先來看mmap()一般是怎麼被使用的 (這邊可以先不用管要傳什麼參數)8 n1 H2 F; i8 Q( Y+ w. j: @
int fd, mapSize, offset, start;. }: Q1 ^8 ~  `
char* ptr;0 c% x  \. }, |2 S% k

, F1 d- a  N1 Z) L3 R+ x# amapSize = 0x1000; /* 希望映對多大的區塊 */
% l2 j& z: J3 ~3 a" H7 f3 Moffset = 0;7 ]8 b9 F) l# ?9 I; T9 `9 U9 X
start = 0;
- v3 |% e# v4 p# ]5 L* |/* 打開檔案 */; L- n: H( W! z0 n' w/ b9 g5 e
fd = open( "/home/tester/a.txt", O_RDWR | O_SYNC );  
; k! I5 r1 U. x& R/* 作mmap動作,取得一個對應好的address */6 D# Z  o$ R% N+ s/ c
ptr = mmap( 0, map_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset );
3 H' N  U9 B: e/ D: Q" w) a* F
7 [5 y* a0 \1 F3 |9 @假如一切順利的話 ptr 就會接到一個address,這個address會對應到a.txt這個檔案所在的起始位置,& l8 g  ?# w8 l$ M
如果這時候我們用 strcpy( ptr, "hello!!" );! M# @7 V2 N0 k2 {& o3 a
. }& W/ b( j" I. b
a.txt裡面就會被寫入"hello!!"的字串, z) j! G  y7 X% R

. I! N2 N2 g  D2 V7 A2. 假如我寫了兩個程式,都是用mmap()到同一個a.txt,程式會不會出問題? 如果不會,那我既然對同一個檔案作mmap(),那我拿到的ptr不是應該是相同的address?
. l1 {- P: r5 w% [# e, y
% U4 r  c1 r7 I/ x9 d2 ]' W答案是:兩個程式可以正常執行,但是這兩個回傳的address不一定相同。
- E/ n6 Y0 ], d% mwhy?  為什麼對同一個檔案寫入,也都做同樣的mmap()動作,甚至傳的參數值都相同。
: [" _, v' q) r1 }為什麼拿到的address可以是不同的? 更奇怪的是,位址不同,還是同樣寫到同一個檔案上頭。
6 T4 e; Q+ s* O( b4 m, ^
  i+ r* z$ q7 v9 m假如這一切都是合理的,那表示雖然這兩個位址不一定相同,其實都是對映同一個地方,表示有某種東西記錄著這個對應關係。而且,兩個program的ptr有時候會一樣,可是有時候又不一樣。唯一個可能是表示兩個process各自保有這些映對的方式。1 e% ]4 m; s  ]) h9 u+ e

- J" }$ n- ^7 q. ]& L1 \3. 假設我只寫一個程式,但是mmap()兩次到同一個檔案上呢? 得到的兩個ptr會一樣嗎?
$ z: A, X8 \* w# ^0 q
8 k0 e- W) S, D# M/ t% |答案是:這個兩ptr還是不一樣的,兩個不同program 跑出來的mmap()結果不同也就算了,同一個program呼叫兩次mmap()跑出來的ptr也不一樣,但又都對映著相同的檔案a.txt。因此我們又可以猜測這一個mmap()是動態的,動態去產生一種應對的方式,將傳回的ptr對應到真正的檔案a.txt去,所以同一個process可以對應好幾次,好幾次都用不同的address去對映到相同的檔案上去。
1 a; V# {. \7 U- W! a3 b' k% I
( ?) _/ B7 p: u1 L8 n綜合上面三種現象,我們合理的懷疑系統裡面存在了一個東西,它讓每一個process可以動態地記錄address的對應關係。並且,每個process各自擁有這個table,而這些對映的關係會動態的反應在這個table當中。/ p6 V$ `$ A, H9 r0 j
6 b+ U% ]: M7 T) \2 H! i( \
回想一下一個系統有誰會做這種工作,不就是MMU所擔任的重要角色嗎?- d9 q  u6 Z+ V9 v( i) n
每個process各自擁有自己的 page table 當他呼叫mmap()的時候,系統就動態地幫她在這個table上寫上紀錄著
& m) A1 G! O' r  N# j- f- A$ l# F
; h( K" N9 t% z4 w, j/ ?& {[processA-pgtable]
# S7 L+ _; S3 k0 a, F1 r0x00008000 ptr1 --> a.txt
- e' K# z! j6 a! a: E* c+ ^0 U0xa0008000 ptr2 --> a.txt
4 @7 j( ?4 @" y( k( S1 c& [5 V. |; y7 S# B5 ]
[processB-pgtable]
" H8 \" h$ r/ w4 ~! u0x00008000 ptr1 --> a.txt
0 k4 \6 O& [$ O( Y0xb0008000 ptr2 --> a.txt# U- z# s* U+ I8 b( n% p8 Y
5 r5 J) J, x$ J: A" T$ e2 V
這樣ptr1, ptr2都可以對應到相同的地方,又因為各個process又有不同table,所以有時候ptr1有可能會相同。
. q, v+ t/ Q" d* ^如此一來,我們終於可以合理的解釋我們觀察mmap()為何對映出來的address會有如此的表現。原來就是MMU被加入,而且OS又被設計成每個process都會各自擁有一個page table來記錄他對記憶體如何解讀。

評分

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

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享分享 頂 踩 分享分享
2#
 樓主| 發表於 2008-8-4 15:20:27 | 只看該作者
略寫下兩個延伸的想像問題" ~2 u3 B" T$ M/ _4 }' t: S
或許有人有興趣可以回答或是深入研究
5 n& b& m1 Z  F, C# i( |9 X' X( M0 Z! J- j! ?9 C6 e$ }2 k" E# F
[延伸想像]
9 Q% m; `. S! b# O& i5 S: j( y我們又可以仔細想想假如每個process都有各自的table" h' J9 l! @& c
那麼從一個process做context switch到另外一個process的時候
( B$ k- o, p' }( ~6 j# Q& `代表所用的table是不同的9 c  y4 u% J% R. N8 H
wow!!!可想而知系統是很忙碌的,1秒鐘context switch 10次就要替mmu切換10次page table的mmap方式4 K! ]' C) P' c: m1 T- q
不然process用錯page table可能就會指到錯誤的位址
0 o- J0 d, H2 Q那OS到底怎麼切換這些page table?
0 w9 D+ I+ r/ A2 i2 W# l7 mkernel和user program的page table有什麼不同??
  n# {; P+ E2 c2 C* `
) {$ F$ X# O# c8 |% W6 Y[延伸想像]( H3 }+ g. C# l- v1 O' ^
假如我們可以修改page table的權利,是不是就可以寫出一個可以偷取別的process data的東西?因為我可以偷偷的map過去他的address space讀取它的資料??    有辦法嗎? 還是根本沒機會?
您需要登錄後才可以回帖 登錄 | 申請會員

本版積分規則

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

GMT+8, 2024-9-21 07:30 PM , Processed in 0.161010 second(s), 19 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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