来自:Jan5 > 馆藏分类
配色: 字号:
linux用户空间与内核空间
2014-01-03 | 阅:  转:  |  分享 
  
第七讲内核空间和用户空间

从以上几讲我们知道,Linux简化了分段机制,使得虚拟地址与线性地址总是一致,

因此,Linux的虚拟地址空间也为0~4G。Linux内核将这4G字节的空间分为两部分。将最

高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF),供内核使用,称为“内核空间

”。而将较低的3G字节(从虚拟地址0x00000000到0xBFFFFFFF),供各个进程使用,称

为“用户空间)。因为每个进程可以通过系统调用进入内核,因此,Linux内核由系统内

的所有进程共享。于是,从具体进程的角度来看,每个进程可以拥有4G字节的虚拟空间。

图6.3给出了进程虚拟空间示意图。

图6.3Linux进程的虚拟空间

Linux使用两级保护机制:0级供内核使用,3级供用户程序使用。从图中可以看出,

每个进程有各自的私有用户空间(0~3G),这个空间对系统中的其他进程是不可见的。

最高的1GB字节虚拟内核空间则为所有进程以及内核所共享。

1.虚拟内核空间到物理空间的映射

内核空间中存放的是内核代码和数据,而进程的用户空间中存放的是用户程序的代码

和数据。不管是内核空间还是用户空间,它们都处于虚拟空间中。读,系统,

内核的代码和数据不是入到物理内存它们为也处于虚拟内存中这和

程序有,我们通过具体这一。

虚拟内核空间(1GB)

进程1

的用户

空间

(3GB)

进程2

的用户

空间

(3GB)

进程n

的用户

空间

(3GB)

内核空间据了每个虚拟空间中的最高1GB字节,映射到物理内存总是从

最低地址(0x00000000)。图6.4所示,对内核空间来,其地址映射是?简¢的

线性映射,0xC0000000是物理地址与线性地址£间的?¥?,§Linux代码中currency1''

PAGE_OFFSET。

虚地址空间物理地址空间

图6.4内核的虚拟地址空间到物理地址空间的映射

我们来看一“§include/asm/i386/page.h中对内核空间中地址映射的及??:

/

Thishandlesthememorymap..Wecouldmakethisaconfig

0

3G

4G

0

X

option,buttoomanypeoplescrewitup,andtoofewneed

it.



A__PAGE_OFFSETof0xC0000000meansthatthekernelhas

avirtualaddressspaceofonegigabyte,whichlimitsthe

amountofphysicalmemoryyoucanusetoabout950MB.



IfyouwantmorephysicalmemorythanthisthenseetheCONFIG_HIGHMEM4G

andCONFIG_HIGHMEM64Goptionsinthekernelconfiguration.

/

#define__PAGE_OFFSET(0xC0000000)

??

#definePAGE_OFFSET((unsignedlong)__PAGE_OFFSET)

#define__pa(x)((unsignedlong)(x)-PAGE_OFFSET)

#define__va(x)((void)((unsignedlong)(x)+PAGE_OFFSET))

fi代码的fl中,–?的物理内存?于950MB,·§内核??

CONFIG_HIGHMEM4G和CONFIG_HIGHMEM64G??,这”?…我们‰不?。–物理内存

于950MB,则对于内核空间而`,给?一个虚地址x,其物理地址为“x-

PAGE_OFFSET”,给?一个物理地址x,其虚地址为“x+PAGE_OFFSET”。

这′??,ˉ__pa()??˙一个内核空间的虚地址映射到物理地址,而¨不

用于用户空间,用户空间的地址映射???得。

2.内核映?

§“的?ˇ中,我们˙内核的代码和数据currency1内核映?(kernelimage)。—系统

,Linux内核映?§物理地址0x00100000的地,1MB的间

(第1M它用)。而,§,个内核映?§虚拟内核空间中,因此,

程序§内核映?,§所有的?地址上?一个¥?PAGE_OFFSET,这a,

内核映?§内核空间的地址为0xC0100000。

,进程的?PGD(?于内核数据?o)处于内核空间中。§进程,

?将存CR3??进程的?PGD,而?的地址§内核空间中是

虚地址,CR3所?的是物理地址,这?用__pa()进地址。§

mm_context.h中有这一??:

asmvolatile(“movl%0,%%cr3”::”r”(__pa(next->pgd));

这是一?入?代码,其?是将“一个进程的?地址next_pgd,通

过__pa()物理地址,存放§个存中,用mov将其写入CR3存中。

经过这??的处理,CR3?进程next的?表PGD了。

献花(0)
+1
(本文系Jan5首藏)