分享
 
 
 

读核日记 ( 七 )

王朝other·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

作者: sunmoon

内存治理是一个操作系统必不可少.并且.非常重要的一环.Linux的成功.和它优秀的内存治理联系

非常密切.因为一个系统的高效性欲稳定性往往决定于它的内存治理机制.我项很多人吃过dos下

640k 的苦吧.

前面我们介绍了386保护模式.从今天起我们将在此基础上,分析linux的虚拟存储治理,对每个程序

员来说.他们都希望有无穷大的快速的内存,然而,现阶段是不可能的,况且,无穷大与快速本身就可

能矛盾

为了解决无穷大.linux 引入了虚拟存储系统,为了解决快速,linux 引入了cache ,交换机制等等,

以使的存储系统,在容量上接近硬盘,速度上接近cache.(当然,我认为这是存储系统的实际目的).

Linux 的内存治理采取的是分页机制.它的设计目的是分时多任务.linux 可同时处理256个任务

(这应该与某个变量来定义,一时想不起来).同时它采用了两级饱和机制来分别内核进程与用户进程.

在386 保护模式的0-4G 的线性虚拟地址中,3-4G 是留给内核进程的.而0-3G分给用户进程.内核在

内核空间的寻址不同于用户进程在用户空间的寻址.因为内核是在启动时装入内存的.说以它可以

直接吧地址映射到3G 以上.用户若想访问内核就不许通过swapper_pg_div 中的指针来得到页表.

相反,用户进程,在用户空间的寻址是通过所用户页目录中的指针得到用户的页表.并通过页表的指

针直接指向相应的物理内存.

Linux虚拟内存的实现,需要几种不同的机制来实现:

地址映射机制

内存的分配与回收

请页机制

交换机制

内存共享机制

在具体的读源码之前.我们先根据我们以前学过的操作系统知识.和C语言等知识.来考虑一下,这几

个机制如何实现.现自己设计一下.在看别人是怎样实现的.找到自己想不到.或者对效率空间有损

的地方.这样才有进步.我不止一次的说.操作系统的某一部分,就起实现来说,非常简单.它的难点

是如何将大量的功能集成出一个kernerl.

地址映射机制,说白了,就是在虚拟内存与物理内存上的一个桥梁.它要做的事情可能就是通过几个

不同的表.把虚拟地址转换成物理地址,把物理地址转化虚拟地址.

我们以前说过.因为有系统与用户之分,它必须也要有不同的数据结构.为了解决速度等问题.它会

有一个硬件的缓冲区

对于它的数据结构.我们可以先想一下.如虚拟地址的信息,虚拟地址在那个区域等等

至于请页机制,更好理解.因为linux是页式存储的.因此必然会存在空白页和使用页.既然是页.就

必然会存在页溢出.页无效(是不是在win98 下经常出现类似错误,当然linux的内存治理不可能和

windows一样,可基本道理相同).因此.在每一个页出错.或者该页存不下多余的数据时.就要要求内

核分配新的页面

同时.当时用fork() 产生一个新的进程时.也需要分配新的叶面.这一部分大概讲的就是进程如何

向内和描述自己需要怎么样的和多少页

在我们学习是我们学了,很多内存分配方式,如首次拟和.最佳拟和,最差拟和等等.但

是我们可以想象.linux 大概不会用他们.那就一定是伙伴系统了.因此我们可以对于伙伴系统的分

配,回收的基本算法.回想一下.这样在读者一部分源码时,回有意象不到的收获.

至于交换机制.我们也可以现想一想.内存中总与很多使用者的页.假如这些也已经把所有的页都用

完了.再分配时必须把其中的某些页释放.释放那些页,需要考虑.如最近不用页.近期少用页,等等

都可以在考虑之中.

这个算法,大概就是计算内存中使用的页,什么时候可以换处.说白了就是为所有的使用页计算一

个”权”,而这个”权”就决定了他什么时候被释放以换如它的内容.需要想的是对于经常使用的页.可

以把它放入cahe.(尽管这一部分对程序员是透明的,但我们应该理解他的原理).

最后的一部分共享内存,我想和我门初学linux编程时,进程通讯里面的共享内存没有区别.大概也

就是在它的数据结构中加入可以答应不同进程访问的tag 就行了.

以上,只是我们对linux的内存治理机制的猜测,需要我们做的工作就是具体的读源码.更正不正确

的猜想.同时学习别人的实际思路.

地址的映射机制

地址的映射机制,主要完成主存.辅存.和虚存之间的关联.包括磁盘文件到虚存的映射和虚存与内

存的映射关系.为了虚拟存储和进程调度相一致.linux 采用可一系列的数据结构,和一个硬件缓存

(TLB)来实现地址映射机制.

mm_strut 用来描述进程的缓存.

strUCt mm_struct

{

struct vm_area_struct * mmap;

/* list of VMAs */

struct vm_area_struct * mmap_avl; /* tree of VMAs */

struct vm_area_struct * mmap_cache; /* last find_vma result */

pgd_t * pgd;

atomic_t count;

int map_count; /* number of VMAs */

struct semaphore mmap_sem;

spinlock_t page_table_lock;

unsigned long context;

unsigned long start_code, end_code, start_data, end_data;

unsigned long start_brk, brk, start_stack;

unsigned long arg_start, arg_end, env_start, env_end;

unsigned long rss, total_vm, locked_vm;

unsigned long def_flags;

unsigned long cpu_vm_mask;

unsigned long swap_cnt; /* number of pages to swap on next pass */

unsigned long swap_address;

/*

* This is an architecture-specific pointer: the portable

* part of Linux does not know about any segments.

*/

void * segments;

};

他描述了一个进程的页目录,有关进程的上下文信息.以及数据.代码.堆栈的启示结束地址.还有虚

拟存储取得数目.以及调度存储用的链表指针.他的参差比较高

较高层次的vm_area-struct 是描述进程的虚拟地址区域.他形成一个算相链表.按虚地址下降排列

.这样当内核需要在一个给定进程页上执行给定操作时.客从双向列表中找到该项.在世想有关页的

处理.如.页错误.页换出等等

他的具体结构如下:

struct vm_area_struct {

struct mm_struct * vm_mm; /* VM area parameters */

unsigned long vm_start;

unsigned long vm_end;

/* linked list of VM areas per task, sorted by address */

struct vm_area_struct *vm_next;

pgprot_t vm_page_prot;

unsigned short vm_flags;

/* AVL tree of VM areas per task, sorted by address */

short vm_avl_height;

struct vm_area_struct * vm_avl_left;

struct vm_area_struct * vm_avl_right;

/* For areas with inode, the list inode-i_mmap, for shm areas,

* the list of attaches, otherwise unused.

*/

struct vm_area_struct *vm_next_share;

struct vm_area_struct **vm_pprev_share;

struct vm_operations_struct * vm_ops;

unsigned long vm_offset;

struct file * vm_file;

unsigned long vm_pte; /* shared mem */

};

而page 结构 则是对物理页进行描述的一个数据结构,他不是一个真正的物理页.而只不过是描述

了一个物理页的内容和框架.作了逻辑页的一个标志;.他的标志域定义了这个页在进行的操作.链

域则定义了一个双项链表.时的页框.可以很轻易的查找到.为实际物理内存的使用直到方便

他的具体结构如下

typedef struct page {

/* these must be first (free area handling) */

struct page *next;

struct page *prev;

struct inode *inode;

unsigned long offset;

struct page *next_hash;

atomic_t count;

unsigned long flags; /* atomic flags, some possibly updated asynchronously */

wait_queue_head_t wait;

struct page **pprev_hash;

struct buffer_head * buffers;

int owner; /* temporary debugging check */

} mem_map_t;

所有的page 结构将都被转入一个叫做mem_map 的数组中.

当一个进程运行时,他的代码段和数据段将都会被调入内存.假如它使用了共享库.共享客的内容也

将贝雕如内存.进程运行时.系统首先分配一

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有