地址的映射机制
r0 }! s7 ?0 z/ H1 D/ m
地址的映射机制,主要完成主存.辅存.和虚存之间的关联.包括
磁盘文件到虚存的映射和虚存与
内存的映射关系.为了虚拟存储和进程调度相一致.linux采用可一系列的
数据结构,和一个
硬件缓存(TLB)来实现地址映射机制.
. a( R, \. \8 Y
mm_strut用来
描述进程的缓存.
# z* U- h) E1 U6 [% n
structmm_struct
" \0 V! n4 l3 M+ E6 e j- W/ _% b. w
{
3 i d9 W+ c2 [- N: J1 Z& U5 U[color=#FFFFFF']
" z9 g& I8 p: j _) J" D
6 H, c, V3 g: L* _
structvm_area_struct*mmap;/*listofVMAs*/
/ I9 t' s Q9 v5 d2 u) l
[color=#FFFFFF']
( C( x- }, o: X, K
' T2 l% R+ @# V R6 m. ^9 W
structvm_area_struct*mmap_avl;/*treeofVMAs*/
" x5 @' x5 \3 \* }' `
structvm_area_struct*mmap_cache;/*lastfind_vmaresult*/
w/ a! C+ Z& f" c) e% ]
pgd_t*pgd;
* v9 {( q$ c2 T: u+ ^0 o; T% W8 ]
atomic_tcount;
* K( u! D' D/ w& f' x% D
intmap_count;/*numberofVMAs*/
. a2 D# z! ]% p$ ?% w% Gstructsemaphoremmap_sem;
) Y0 L+ \/ T, K# U/ ?0 \spinlock_tpage_table_lock;
8 r0 |" y2 t+ T- i4 R
unsignedlongcontext;
3 F3 V) ]: x) N1 T! q3 x: C- A1 ?
[color=#FFFFFF']
! W3 ?/ N( x% g* W# U, M
7 V% H ]; F( B) h9 E
unsignedlongstart_code,end_code,start_data,end_data;
; b3 U- \; E2 L3 ]unsignedlongstart_brk,brk,start_stack;
: r9 |% V2 y, ], Z! x
unsignedlongarg_start,arg_end,env_start,env_end;
7 u% o7 s! _1 p+ h" s' u% v+ V! }
unsignedlongrss,total_vm,locked_vm;
1 `7 H: b% R% N+ s& u2 xunsignedlongdef_flags;
( t' z$ Z, T, H$ tunsignedlongcpu_vm_mask;
; N8 E4 Z8 g1 s, I; X! ?- h
[color=#FFFFFF']
! b& k/ {3 ~6 g$ b/ A# A- U
9 k0 d6 e+ j7 y+ cunsignedlongswap_cnt;/*numberofpagestoswaponnextpass*/
, V% s' Z9 `7 ~0 c7 }: J) q
unsignedlongswap_address;
. G! u# ^" }7 L4 e+ a+ x& e9 k/*
( Y/ D& w: {$ K9 d& m9 J
[color=#FFFFFF']
3 G9 v* Q+ \' l r) |6 p5 O+ l9 P9 `# D2 v
*Thisisanarchitecture-specificpointer:theportable
6 l' g5 |% Q' p/ R' P: Q! s*partof
Linuxdoesnotknowaboutanysegments.
0 l( k$ I( |5 S: \- Y( c*/
. ?$ m* K/ Z: R9 a$ W" y
void*segments;
( O( A% r6 o/ ]) U' \
};
" j- o3 x: o1 H. U0 {他描述了一个进程的页目录,有关进程的上下文
信息.以及数据.代码.堆栈的启示结束地址.还有虚拟存储取得数目.以及调度存储用的链表指针.他的参差比较高
5 F% {) T; i: r3 n% b% v4 X
[color=#FFFFFF']
" x. r/ G6 `5 N1 a6 J' l7 O7 `
' b+ s+ w) L+ u5 L2 P: n. ]较高层次的vm_area-struct是描述进程的虚拟地址区域.他形成一个算相链表.按虚地址下降排列.这样当内核需要在一个给定进程页上执行给定操作时.客从双向列表中找到该项.在世想有关页的处理.如.页错误.页换出等等
+ \- u: r; ^6 r" d0 ^9 Z! G
他的具体结构如下:
* _- M5 s- N: {; ^0 O& x/ cstructvm_area_struct{
( k! z, }' v% v- Y5 s& f* t' Bstructmm_struct*vm_mm;/*VMareaparameters*/
: b6 Y+ V, ]# ?% Y7 b
unsignedlongvm_start;
* _1 H! F7 M9 r4 h) N6 l
unsignedlongvm_end;
( W5 b5 u7 W6 @, h3 n) i
/ _8 G- b+ R# I3 R% Q' W/*linkedlistofVMareaspertask,sortedbyaddress*/
+ s3 |! @& k" P+ ^2 ~, S
[color=#FFFFFF']
+ u9 O! _8 ~; W
( K2 k2 S; W3 }0 T0 I
structvm_area_struct*vm_next;
9 y* w6 d" A) k! S7 O
# a5 N% n1 \( b+ M; v7 M/ _
[color=#FFFFFF']
! L& ^$ n2 `% i ?
) K' Q S! S- s" Z2 Q- m7 Mpgprot_tvm_page_prot;
, T8 [( w6 ^& D% [2 l9 ?+ Bunsignedshortvm_flags;
' {& l' h+ R: {- s9 ]2 \% ~. _
! ] O! Y) P' k. \% _: S! C/*AVLtreeofVMareaspertask,sortedbyaddress*/
- q [2 s, {- h0 a0 w# |
shortvm_avl_height;
, m$ p0 V) Z# I, x9 s/ x' r
structvm_area_struct*vm_avl_left;
; f$ o h- X; R[color=#FFFFFF']
: t- t6 R0 z5 q
1 A+ A3 O2 T' i1 u: _3 ?
structvm_area_struct*vm_avl_right;
3 @6 ]/ Y5 g9 r$ A* e5 n4 s
[color=#FFFFFF']
7 d# ]; u$ ~ l) z
+ J2 }) _* @" y
1 e3 x, G Z# }& k% v# p[color=#FFFFFF']
6 I, @* }: R5 B6 m8 H" j- ?- E
# Z- N( {, o* T7 G8 R z: f5 e( x
/*Forareaswithinode,thelistinode-%26gt;i_mmap,forshmareas,
8 o: A1 c9 C' q$ P L$ j! x' U
*thelistofattaches,otherwiseunused.
6 ^+ ?( p* O& k*/
. ?# \* T- q' q, q
structvm_area_struct*vm_next_share;
7 ?0 H: x" H/ N% ]
structvm_area_struct**vm_pprev_share;
, G8 V8 v7 o' i- D; o8 p
: M- c2 B6 u1 f2 Cstructvm_operations_struct*vm_ops;
: F A* I2 Q4 n[color=#FFFFFF']
5 Y) [9 n( l- o& J' Y8 E* v, L
$ \4 Y( c! d3 h4 q; e9 O4 D/ o$ O
unsignedlongvm_offset;
) A; ?! A! U$ m; m; E$ e
[color=#FFFFFF']
$ V* X/ ? I0 J. c6 B% O2 }5 L
7 ?6 Z, l) O- x, q! F
structfile*vm_file;
4 y' o( g8 X# v- K' ^unsignedlongvm_pte;/*sharedmem*/
* K0 P; o( `: a% b( e
[color=#FFFFFF']
; `7 p. b0 V; P
9 c2 o' V2 g! L7 |1 R};
% m" L `+ u) q1 [8 C[color=#FFFFFF']
* L# K7 m. e R0 d6 A4 {
9 x, l `/ Z, b4 z' @7 `1 T4 W9 \而page结构则是对
物理页进行描述的一个数据结构,他不是一个真正的物理页.而只不过是描述了一个物理页的内容和框架.作了
逻辑页的一个标志;.他的标志域定义了这个页在进行的操作.链域则定义了一个双项链表.时的页框.可以很容易的查找到.为实际物理内存的使用直到方便
: g' K- M% q2 f' ]" s" i3 w
[color=#FFFFFF']
! [) }8 ]6 K7 T4 i
* s% U: p$ i0 S) L( e f1 V8 q他的具体结构如下
% q3 O+ n$ y! X
typedefstructpage{
, W! w" y7 {) ]3 k7 m$ V/*thesemustbefirst(freeareahandling)*/
' r7 \4 v1 V+ |. nstructpage*next;
0 z0 ?7 T- E2 [: u- _3 istructpage*prev;
& G& l# V1 i6 F6 Nstructinode*inode;
) \8 s+ \+ U: N* ]1 q# E! T( j" gunsignedlongoffset;
, X) W3 B. }2 J7 |# X" ~structpage*next_hash;
/ u. G3 N7 P4 Z9 N5 Vatomic_tcount;
* y, M+ M8 S9 D5 q; ~& funsignedlongflags;/*atomicflags,somepossiblyupdatedasynchronously*/
6 w( n/ b* {" ~$ q7 {* C
wait_queue_head_twait;
9 k* M. }% J- _0 z; L I, \$ |/ ?
structpage**pprev_hash;
) k! r) f: c* x8 K, Q4 `3 Wstructbuffer_head*buffers;
: \$ T& L ]0 L- n1 y3 @[color=#FFFFFF']
, g( h! ~9 O1 h, R! W( t& g
9 w8 ]& g$ Y! |6 ^( M: V8 qintowner;/*temporarydebuggingcheck*/
+ j8 M7 o" L/ J6 E
}mem_map_t;
$ ]# m9 `! o. x. A
所有的page结构将都被转入一个叫做mem_map的数组中.
9 G2 ?# W2 [( W' u. U8 N( @
当一个进程运行时,他的代码段和数据段将都会被调入内存.如果它使用了
共享库.共享客的内容也将贝雕如内存.进程运行时.
系统首先分配一个vm_area_struct给进程.并将这各进程连结到虚拟内存的连标中去.这是根据进程的可执行影像中的信息.吧数据段和客执行代码非配内存.新分配的内存必须和进程已有的内存连结起来才能应用.这样聚会出现页
故障.系统利用了请页机制来避免对物理内存的过分使用.但进程访问的虚存不在当前的物理内存时,这时系统会将需要的页调入内存.同时修改进程的页表.用来标志虚拟页是否在物理内存中.
: [( L- K+ D; z! o
因此,系统用了较复杂的数据结构来跟踪进程的虚拟地址.在task_struct中包含一个指向mm_struct结构的指针.进程的mm_struct中则包含了进程可执行影像的页目录指针pgd.还包含了指向vm_area_struct的几个指针,每个vm_area_struct包含一个进程的虚拟地址区域.
: K; \4 S, x- Z% i2 C2 v+ z7 d; k一个进程有多个vm_area_stuct结构.linux要经常对进程分配..或调整vm_area_struct.这样对vm_area_stuct的查找效率.对系统很有影像.所以在这里将所有的vm_area_struct形成了一个查找效率较高的平衡二叉树结构.
! x: E7 U! J- \/ ?. _ M我个人认为,在整个linux内核中这个地方.数据结构是最复杂的.如果把这一部分肯下来以后,整个内核便开始清晰了