可以将linux看作一个用来管理资源的程序,而其他应用程序跑在其上,linux管理应用程序的内存分配,回收,等等。为了管理,它首先需要给自己分配静态的内存空间:代码段空间,mem_map[]空间等等。然后它把剩余的其他ram用buddy系统进行动态管理。
linux内核的pagetable swapper_pg_dir将虚拟地址0xc0000000~0xc0000000+896m映射到物理地址0x0~0x896m。除去内核代码占用的ram外,其余的物理ram都为空闲。当内核需要时,直接分配了就可以使用,而不需要再对swapper_pg_dir进行修改。而当用户空间需要的时候,内核为其分配page,并要修改应用进程的pagetable从而将刚分配的page映射到相应的应用进程地址空间。内核不需要再次映射,因为swapper_pg_dir已经将896m的地址映射到内核去了。除非内核使用high_mem,这时就要重新映射内核的高128m空间(修改swapper_pg_dir的高128项)。有上可知,只要应用进程分配的page小于896m(在内核地址空间之内),内核都可以直接访问(参见#define __copy_user(to,from,size)其中to为内核地址,使用用户page_dir的768~896项(3g~3g+896m内核空间),from使用用户地址:page_dir的0~767项(0~3g-1用户地址空间))。要是应用进程的page大于896m时,内核就不能直接访问了,需要使用swapper_pg_dir的高128项来映射应用进程的地址空间,这也是high_mem存在的原因。
ram的使用
1. 静态使用:用于linux代码,数据结构等所占用的ram,此类ram不需要管理。
2. 动态使用:由buddy管理。通过buddy申请的页面不使用的时候并不立即释放给buddy,而是利用3的方式缓存起来(1)由slab管理起来(2)由两个双向链表(active_list和inactive_list)管理的页框(3)由icache和dcache缓存起来inode和dentry。这样当系统回收的时候,也是分别通过这三个方面来回收页面,释放到buddy中去的。之所以这样,是由于通过buddy分配或释放给buddy可能需要分裂大块或者合并小块到大的buddy中去,这样比较费时间。因此尽量将分配来的页面缓存起来。(好像linux特别喜欢搞这些缓冲,这样也就给系统带来了异步性。一般来说,异步性效率更好吧:有缓存就相当于有了流水,这样当然可以提高效率)
之所以要这样分,是因为:buddy管理会产生大量的内部碎片,使用slab来减少碎片。一般slab是基于对象的,因此不是以页框为单位,不便于以页为单位进行换入换出。而使用双向链表是将系统中正在使用的页框串联起来,便于scan,以及页框为单位的换入换出(回收)。因此,当系统需要回收页框时,就要从slab和双向链表,inode dentry三方面考虑回收。
对于双向链表中的页框,又可以分为两种使用情况:1. 有后备文件的页框(page buffer,mmap等);2. 无后备文件的页框(应用程序的代码段,数据段,堆栈段etc)。对于2,由于无后备文件,因此需要在磁盘上开辟一个交换文件,用于存放无后备文件的页框,这样以来,1,2都有后备文件了。有了后备文件之后,接下来需要将这些属于不同文件的页框用一个数据结构管理起来:address_space。对于有后备文件的页框,使用特定于每个文件的address_space,对于无后备文件的页框,使用系统中公用的address_space:swapper_space.这样就把1,2统一起来了。
系统要于磁盘打交道,必须先分配一个page buffer:当需要读入文件时,首先要查找address_space看是否已经存在page_buffer,没有的话则分配一个page buffer页框,插入address_space。当写出磁盘时,也要检查address_space中是否存在page buffer,没有的话,分配一个page buffer页框,并插入address_space然后,将要写内容写入该page buffer并返回(该page buffer最终会被页面回收守护线程刷新到磁盘上去)。以上的操作过程同样适用无后备文件的情况(只是它们使用的address_space是swapper_space)。
page buffer是vfs看见(使用的)设施,而cache buffer是块驱动程序使用的设施,一个page buffer包含多个cache buffer(当然块设备也要使用cache buffer)。也就是说,vfs等上层之能“看见”页面,而下层的块设备驱动程序只能看见块。所以当vfs要将一个页写入块设备时候,必须先将页划分成几个buffer,每个buffer用buffer_head描述,一个页中的buffer_head使用单连表相连,只有才能被底层的设备识别。
友达去年获利创10年新高,本钱足够面对竞争
关于目前连接器市场的发展形势分析
能否使用泪珠提高PCB质量和产量?
南京成立国内首个芯片大学,将与华为中芯国际等合作运输人才
金升阳推出6-42VDC超宽压输入、小功率DC/DC电源—CUWF24_J(Y)T-3/6WR3系列
linux内存的使用与page buffer有什么联系?
物联网将怎样可持续发展
Linux最新UBI文件系统介绍
PH-010(A)干燥培养两用箱技术参数的介绍
伺服电机和步进电机的区别和外观区分
PCB制造中,通孔、盲孔和埋孔的区别
安科瑞ARD3M电动机保护器在煤炭行业中的应用
基于总线技术的新一代开放式DCS系统在水泥熟料生产线中的应用
示波器直流和交流耦合
一文解析计算影像学
工业平板电脑在MES生产线管理系统的应用
index函数语法说明及应用实例
ESD/浪涌保护器件使用方法:贴片压敏电阻
千兆电口模块SFP-GE-T有什么用
如何正确使用及保养锂离子电池?