Linux 0.12内核与现代内核在内存管理上的区别

0.12内核的内存管理比较简单粗暴,内核只用了一个页目录,只能映射4G的线性空间,所以每个进程的虚拟空间(逻辑空间)只能给到64M,最多64个进程;每个进程都有对应的任务号nr,当一个进程需要分配进程空间时,只需要nr乘以64M就可以得出该进程空间的线性起始地址。然后该进程的代码段、数据段描述符里面的基址字段会被设定为(nr x 64M),同时可以为进程分配页目录项和页目录表用以承载映射关系。

之后如果进程要访问自己空间内的某个地址时就会首先用基地址与程序内32位偏移地址(逻辑地址)合成出线性地址,这个合成出来的线性地址一定在(段基址)~(段基址+段限长)之间,也就是(nr x 64M ~ nr x 64M+64M)之间。然后用这个线性地址遵循:“页目录项-页表-页表表项”这样的顺序找到对应的页表表项,也就找到了物理地址,就可以真正的存取数据了。

但是在现代内核里,内存管理有很多不同。
首先,线性地址空间不会改变,32位CPU可寻址4G线性空间。这个是唯一的。
但是每个进程都有自己各自独立的4G虚拟空间,那么这是如何做到的呢?其实是每个进程给它一个自己的页目录,这样每个进程就能拥有4G的虚拟空间(逻辑空间)了。

注意:0.12内核两个进程各自合成出的线性地址一定不相同,因为每个进程占据线性空间的不同区域。但是现代内核里,A、B两个进程可能合成出相同的线性地址,因为每个进程都有4G的虚拟空间,也就是说虚拟空间和线性空间对等了。但是由于两个进程的页目录和页表都不同,所以这两个进程会把各自合成出的数值相等的线性地址,映射到不同的物理地址。也就是两者线性空间到物理空间的映射是不同的。换句话说在现代内核里,虚拟空间(逻辑空间)和线性空间几乎成了一个概念,以下不作区分。

举个例子,即使A和B进程同时访问各自线性空间的0x0804800地址处,分段分页地址变换机制也会把0x0804800这个线性地址映射到不同的物理地址上去。而这个过程,进程自己是看不到的,A和B都认为自己成功访问了0x0804800这个地址,但是实际上,他们访问的是各自线性空间里“数值相等的”线性地址,最终这两个“数值上相等”的线性地址将映射到不同的的物理内存地址处。这就实现了进程隔离。
每个进程都具备4G的线性空间(虚拟空间),进程的线性空间之间相互隔离,互不干涉,每个进程都在自己的世界里干活。

上面说的都是从操作系统原理的角度说的,放到具体的Linux操作系统上会有点不同。因为Linux内核里面规定,虽然每个进程各自拥有4G的线性空间,但是他们并不能随意使用这全部的4个G。0-3G是用户空间,的确是可以自由使用的,但是3G-4G之间内核空间,不能被随意使用。所以,上面的理论可以完善为,每个进程都有一个大小为4G的线性空间,这4G的线性空间分为两部分:

大小为3G的用户空间,各进程在“特权级3级”下可以自由独立使用,各进程的这块空间是完全独立的互不影响的,是指向物理内存不同位置的。

大小为1G的内核空间,各进程在“特权级0级”下才可以使用这块空间,各进程的这块空间不是独立的,是指向同一物理内存位置的。也就是说是所有进程共享的。

时间: 2024-08-07 03:35:44

Linux 0.12内核与现代内核在内存管理上的区别的相关文章

Linux 0.12 内核管理存储器

其分段,用分段的机制把进程间的虚拟地址分隔开. 每一个进程都有一张段表LDT.整个系统有一张GDT表.且整个系统仅仅有一个总页表. 其地址翻译过程为: 程序中给出的32位地址(实际上被看做段内偏移地址),再依据代码段寄存器CS中的16位段选择子,可在GDT或LDT中查找对应的段描写叙述符.从段描写叙述符中提取段的基地址,与程序给出的32位地址相加.得到结果为线性地址. 依据此线性地址查找系统页文件夹表,再查二级或是多级页表,终于得到物理地址. 此方式系统仅仅有一个4G的线性地址空间由各进程共享(

《linux 内核完全剖析》编译linux 0.12 内核 Ubuntu 64bits 环境

我×...终于好了,大概3 4个小时吧...各种毛刺问题.终究还是闯过来了.... [email protected]:~/Downloads/linux-0.00-050613/linux-0.00$ make ld -s -x -M head.o  -o system > System.map dd bs=32 if=boot of=Image skip=1 16+0 records in 16+0 records out 512 bytes (512 B) copied, 0.000605

Linux 0.12和Linux 0.11内核学习——Google邮件列表

亲,你在学习Linux 0.12或0.11内核吗?快来加入我们吧,就缺你了!!! 为什么选用邮件列表呢?因为赵炯博士那个论坛交流不是很方便,经常发了贴没人回,人气相比十年前论坛刚成立时弱了不少.很多人,很多元老级别的人物,消失了...再也没有出现过. 而QQ群很繁杂,比如你肯定会因为一些兴趣爱好加入一些QQ群,但是也就刚加进去或者自己有什么要问的时候说几句,之后就屏蔽了,因为每天都有人在聊天,什么内容都有,想退群却又怕以后有用,不退吧又很烦,只能屏蔽了潜水. 而邮件列表,你可以订阅主题,实时追踪

十天学Linux内核之第三天---内存管理方式

昨天分析的进程的代码让自己还在头昏目眩,脑子中这几天都是关于Linux内核的,对于自己出现的一些问题我会继续改正,希望和大家好好分享,共同进步.今天将会讲诉Linux如何追踪和管理用户空间进程的可用内存和内核的可用内存,还会讲到内核对内存分类的方式以及如何决定分配和释放内存,内存管理是应用程序通过软硬件协助来访问内存的一种方式,这里我们主要是介绍操作系统正常运行对内存的管理.插个话题,刚才和姐姐聊天,她快结婚了,说起了自己的初恋,可能是一句很搞笑的话,防火防盗防初恋,,嘎嘎,这个好像是的吧,尽管

Linux 0.12的编译与链接

昨天花了很长时间去编译链接linux 0.12版的kernel,发现在64位ubuntu下,这位兄台的文章写得最全最好,几乎涵盖了我遇到的所有问题,在此记录一下. 编译linux 0.12 链接linux 0.12

《linux 内核全然剖析》编译linux 0.12 内核 Ubuntu 64bits 环境

我×.. . 最终好了,大概3 4个小时吧...各种毛刺问题.终究还是闯过来了.. .. [email protected]:~/Downloads/linux-0.00-050613/linux-0.00$ make ld -s -x -M head.o  -o system > System.map dd bs=32 if=boot of=Image skip=1 16+0 records in 16+0 records out 512 bytes (512 B) copied, 0.000

Linux 0.12 sched.c代码理解

最近看看linux0.12,对自己理解内核有很大帮助,但是有些东西也确实需要时间去认真分析,今天看看了sched.c的代码,和大家分享一下.先上代码 /* * linux/kernel/sched.c * * (C) 1991 Linus Torvalds */ /* * 'sched.c' is the main kernel file. It contains scheduling primitives * (sleep_on, wakeup, schedule etc) as well a

第一次作业 基于Linux 0.12的进程模型分析

作业内容 挑选一个开源的操作系统,深入源码分析其进程模型,具体包含如下内容: 操作系统是怎么组织进程的 进程状态如何转换(给出进程状态转换图) 进程是如何调度的 谈谈自己对该操作系统进程模型的看法 1.操作系统是怎么组织进程的 1.1什么是进程 程序是一个可执行的文件,而进程是一个执行中的程序实例.Linux操作系统上利用分时技术,可同时运行多个进程.利用分时技术,在Linux操作系统上同时可以运行多个进程.分时技术的基本原理是把CPU的运行时间划分成一个个规定长度的时间片,让每个进程在一个时间

《Linux内核设计与实现》内存管理札记

1.页 芯作为物理页存储器管理的基本单元,MMU(内存管理单元)中的页表,从虚拟内存的角度来看,页就是最小单位. 内核用struct page结构来标识系统中的每个物理页.它的定义例如以下: flag域用来存放页的状态(是不是脏的.是不是被锁定在内存中等等)._count表示这一页被引用了多少次.当次数为0时,表示此页没有被引用,于是在新的分配中就能够使用它.virtual域是页的虚拟地址. 2.获得页 内核提供了一种请求内核的底层机制,并提供了对它进行訪问的几个接口. 全部这些接口都以页为单位