《Linux 操作系统chap8.ppt》由会员分享,可在线阅读,更多相关《Linux 操作系统chap8.ppt(52页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、LINUX存储管理/设备管理地址空间地址空间(address space)是一段表示内存位置的地址范围。地址空间有两种:n物理地址空间n逻辑地址空间,也被称为虚拟地址空间在逻辑地址和物理地址之间相互转换的工作是由内核和硬件内存管理单元(MMUmemory management unit)共同完成的。MMU是被集成进现代的CPU里的,它们都是同一块CPU芯片内的一个部分。内核告诉MMU如何为每个进程把某逻辑页面映射到某特定物理页面,而MMU在进程提出内存请求时完成实际的转换工作。Linux操作系统采用请求式分页虚拟存储管理方法。系统为每个进程提供了4GB的虚拟内存空间。各个进程的虚拟内存彼此独立
2、。虚拟内存的抽象模型n内存管理系统是操作系统中最为重要的部分,因为系统的物理内存总是少于系统所需要的内存数量。虚拟内存就是为了克服这个矛盾而采用的策略。系统的虚拟内存通过在各个进程之间共享内存而使系统看起来有多于实际内存的内存容量。虚拟内存可以提供以下的功能:广阔的地址空间。进程的保护。内存映射。公平的物理内存分配。共享虚拟内存(动态库、IPC)。虚拟地址到物理地址映射的抽象模型虚拟地址到物理地址映射的抽象模型 进程虚存空间的管理 n进程运行时能访问的存储空间只是它的虚拟内存空间。对当前该进程而言只有属于它的虚拟内存是可见的。n在进程的虚拟内存包含着进程本身的程序代码和数据。n进程在运行中还必
3、须得到操作系统的支持。进程的虚拟内存中还包含着操作系统内核。nLinux把进程的虚拟内存分成两部分,内核区和用户区。n操作系统内核的代码和数据等被映射到内核区。n进程的可执行映像(代码和数据)映射到虚拟内存的用户区。n进程虚拟内存的内核区的访问权限设置为0级,用户区为3级。n内核访问虚存的权限为0级,而进程的访问权限为3级nLinux的存储管理主要是管理进程虚拟内存的用户区。n进程虚拟内存的用户区分成代码段、数据段、堆栈以及进程运行的环境变量、参数传递区域等虚拟内存的抽象模型n当处理器执行一个程序时,它从内存中读取指令并解码执行。当执行这条指令时,处理器将还会需要在内存的某一个位置读取或存储数
4、据。在一个虚拟内存系统中,所有程序涉及到的内存地址均为虚拟内存地址而不是机器的物理地址。处理器根据操作系统保存的一些信息将虚拟内存地址转换为物理地址。n为了让这种转换更为容易进行,虚拟内存和物理内存都分为大小固定的块,叫做页面。每一个页面有一个唯一的页面号,叫做PFN(page frame number)在这种分页方式下,一个虚拟内存地址由两部分组成:一部分是位移地址,另一部分是PFN。每当处理器遇到一个虚拟内存地址时,它都将会分离出位移地址和PFN地址。然后再将PFN地址翻译成物理地址,以便正确地读取其中的位移地址。处理器利用页面表来完成上述的工作。LINUX的虚拟地址划分每一个用户进程都可
5、以访问4GB的线性虚拟内存空间。从0到3GB的虚拟内存地址是用户空间,用户进程可以直接对其进行访问。从3GB到4GB的虚拟内存地址为核心态空间,存放仅供核心态访问的代码和数据,用户态进程不可访问。所有进程从3GB到4GB的虚拟空间都是一样的,有同样的页目录项,同样的页表,对应到同样的物理内存段。LINUX以此方式让内核态进程共享代码段和数据段。内 核 态 虚 拟 空 间 从 3GB到3GB+4M的一段(也就是进程页目录第768项所管辖的范围),被映射到物理空间0到4M段。因此,进程处于核心态时,只要通过访问虚拟空间3GB到3GB+4M段,偏移地址0到4M,即访问了物理空间0到4M段。Linux
6、的三级分页结构 n页表是从线性地址向物理地址转换中不可缺少的数据结构,而且它使用的频率较高。页表必须存放在物理存储器中。n 虚存空间有4GB,按4KB页面划分页表可以有1M页。n若采用一级页表机制,页表有1M个表项,每个表项4字节,这个页面就要占用4MB的内存空间。n由于系统中每个进程都有自己的页表,如果每个页表占用4MB,对于多个进程而言就要占去大量的物理内存,这是不现实的。n在目前用户的进程不可能需要使用4GB这么庞大的虚存空间,若使用1M个表项的一级页表,势必造成物理内存极大的浪费。为此,Linux采用了三级页表结构,以利于节省物理内存。n三级分页管理把虚拟地址分成四个位段:页目录、页中
7、间目录、页表、页内偏移地址。n系统设置三级页表系列:n 页目录PGD(PaGe Directory)、n 页中间目录PMD(Page Middle Directory)n 页表PTE(Page TablE)。Linux的三级分页结构n三级分页结构是Linux提供的与硬件无关的分页管理方式。n当Linux运行在某种机器上时,需要利用该种机器硬件的存储管理机制来实现分页存储。nLinux内核中对不同的机器配备了不同的分页结构的转换方法。n对x86,提供了把三级分页管理转换成两级分页机制的方法。n其中一个重要的方面就是把PGD与MGD合二为一,使所有关于PMD的操作变为对PGD的操作Linux的三级
8、分页结构虚拟地址转换 PGD PMD PTE Page Frame 页目录索引,页面中间目录、页表索引和偏移量虚拟内存和物理内存都分为大小固定的块,叫做页面。每一个页面有一个唯一的页面号,叫做PFN(page frame number)。X86下的地址转换X86下的地址转换总之,存储器只有一个页目录,有1024个页目录项,每个页目录项又含有1024个页面 项,因 此,存 储 器 一 共 可 以 分 成102410241M个页面。由于每个页面为4K字节,所以,存储器的大小正好(最多)为4GB。n转转 换换 后后 备备 缓缓 存存(Translation Lookaside Buffers:TLB
9、s)n如果简单的执行从逻辑地址到物理地址的转换过程,在跟踪指针链时将会需要几个内存引用。RAM虽然不像磁盘那么慢,但是仍然比CPU要慢的多,这样就容易形成性能的瓶颈。为了减少这种开销,最近被执行过的地址转换结果将被存储在MMU的转换后备缓存(translation lookaside buffers:TLBs)内。虚拟地址转换X86高速缓存Linux的存储管理思想系统调用内存映射模块(mmap)内存管理模块(core)结构特定模块MMU交换控制模块 (swap)负责把磁盘文件或交换空间文件的逻辑地址映射到虚拟地址,以及把虚拟地址映射到物理地址负责控制内存内容的换入和换出。采用交换机制,从主存中
10、淘汰最近没被访问的逻辑页,保存近来访问过的逻辑页负责核心内存管理功能,如页的分配、回收和请求调页处理等功能,这些功能将别的内核子系统(如文件系统)所使用负责给各种硬件平台提供通用接口,主要完成主存初始化工作及对页面故障的处理。这个模块是实现虚拟内存的物理基础物理空间管理n物理空间的组织n空闲物理内存管理空闲内存的组织分配回收物理空间的组织(include/linux/fs.h,struct page)物理内存以页帧(page frame)为单位,页帧的长度固定,等于页长,对INTEL CPU缺省为4K字节。LINUX对物理内存的管理通过mem_map表描述(mm/memory.c)。mem_m
11、ap在系统初始化时由free_area_init()函数创建(mm/page_alloc.c)。它 本 身 是 关 于 struct page mem_map_t(linux/mm.h)的数组,每项mem_map_t对应一个关于核心态、用户态代码和数据等的页帧。物理内存空间管理划分后形成了大小不等的存储块,称为页面块,简称页块。包含1个页面的页块称为1页块,包含2个页面的称为2页块,依此类推。每种页块按前后顺序两两结合成一对Buddy“伙伴”系统按照Buddy关系把具有相同大小的空闲页面块组成页块组,即1页块组、2页块组32页块组。每个页块组用一个双向循环链表进行管理,共有个链表,分别为1、2
12、、4、8、16、32页块链表。分别挂到free_area 数组上。物理内存空间管理位图数组 标记内存页面使用情况,第0组每一位表示单个页面使用情况,1表示使用,0表示空闲,第2组每一位表示比邻的两个页面的使用情况,依次类推。默认为10个数组。当一对Buddy的两个页面块中有一个是空闲的,而另一个全部或部分被占用时,该位置1。两个页面块都是空闲,或都被全部或部分占用时,对应位置0。分配算法 LINUX采用buddy算法分配空闲块,块长可以是2i个(0=i NR_MEM_LISTS)页帧。当分配长度是2i页帧的块时,从free_area数组的第i条链表开始搜索,找不到再搜索第i+1条链表,以此类推
13、。若找到的空闲块长正好等于需求的块长,则直接将它从free_area删除,返回首地址。若找到的空闲块长大于需求的块长,则将空闲块一分为二,前半部分插入free_area中前一条链表,取后半部分。若还大,则继续对半分,留一半取一半,直至相等。bitmap表也相应调整。每分配一个2i页帧长的块,都要将bitmap表从第i组到第NR_MEM_LISTS组的对应的bit置1。空闲内存的组织空闲内存的组织空闲内存的组织释放算法 回收空闲块时,change_bit()函数根据bitmap表的对应组,判断回收块的前后邻居是否也为空。若空则合并,即修改bitmap表中对应位,从free_area的空闲链表中取
14、下该相邻块。此判断是个递归过程,直至找不到空闲邻居为止。将最后合并的最大块插入free_area的相应链表中。其他物理内存空间管理slabSlab算法采用buddy算法,解决了外碎片问题,这种方法适合大块内存请求,不适合小内存区请求。如:几十个或者几百个字节。Linux2.0采用传统内存分区算法,按几何分布提供内存区大小,内存区以2的幂次方为单位。虽然减少了内碎片,但没有显著提高系统效率。其他物理内存空间管理slabLinux2.4采用了slab分配器算法 该算法比传统的分配器算法有更好性能和内存利用率,最早在solaris2.4上使用其他物理内存空间管理slabSlab分配器思想小对象的申请
15、和释放通过slab分配器来管理。slab分配器有一组高速缓存,每个高速缓存保存同一种对象类型,如i节点缓存、PCB缓存等。内核从它们各自的缓存种分配和释放对象。每种对象的缓存区由一连串slab构成,每个slab由一个或者多个连续的物理页面组成。这些页面种包含了已分配的缓存对象,也包含了空闲对象。其他物理内存空间管理slabcacheSlabPCB缓存Slabi节点缓存PCB缓存i节点缓存其他物理内存空间管理slab优点:充分利用了空间,减少了内部碎片 管理局部化,尽可能减少了与buddy分配器打交道,提高了效率。交换机制两种交换空间:一种用整个块设备,如硬盘的一个分区,称作交换设备,效率较高(
16、页插槽);另一种用文件系统中固定长度的文件,称作交换文件,效率较低。LINUX允许并行管理MAX_SWAPFILES个交换空间(MAX_SWAPFILES的缺省值为8)。交换机制页面交换守护进程kswapd()是一个无限循环的线程,完成页面交换工作,保证系统内有足够内存。Linux将页面分为活跃状态、非活跃”脏“状态、非活跃”干净“状态。需要时,将非活跃”脏“状态页面内容写入到外存交换空间,并将该页面从”脏“队列移动到”干净“队列。回收页面总是从非活跃”干净“链表队列中进行缓冲机制目的 改善处理机和外围设备之间速度不匹配的矛盾,提高系统性能。Linux采用了多种与主存相关的高速缓存。缓冲区高速
17、缓存 页面高速缓存 交换高速缓存 硬件高速缓存缓冲机制缓冲区高速缓存大小固定,是针对块设备的I/O开辟的。缓存区高速缓存以块设备标识符和块号作为索引,快速查找数据块,若数据块已在缓存中,则不必从物理设备中读取,从而加快了读取数据速度。缓冲区高速缓存大小可变化,当没有空闲的缓冲区而又必须分配新缓冲区时,内核就按需分配缓冲区,当主存空间不足时,可以释放缓冲区。缓冲机制页面高速缓存是为了加快对磁盘文件访问而设立的。当页面从磁盘被读入主存时,被存入页面高速缓存。如文件系统的一些系统调用,如read()、write()等,都是通过页面高速缓存完成的。缓冲机制交换缓存为了避免页面交换时,直接对磁盘交换空间
18、操作,从而提高了系统性能。linux需要将一个页面从内存中换出时,首先查询交换缓存,如果缓存中的文件没有被修改过,则直接丢弃而不用回写外存交换文件。这样大大节省了许多不必要的磁盘操作。硬件缓存 联想寄存器虚拟空间管理内存管理的常用命令nfreenvmstatn cat/proc/meminfonpsntopLinux 设备管理Linux 设备管理模块的安装和卸载设备管理模块的安装和卸载n模块:可以作为独立程序来编译的函数和数据结构的集合。它可以动态的增加内核的功能。n装载:静态装载:在内核启动时动态装载:在内核运行时注:当前装载的模块可以在/proc/modeles读出。模块一旦被装入系统,就
19、在内核地址空间中管态下执行。模块中的每个新函数都必须在模块装入内核中时进行注册。模块卸载时,函数必须注销。设备管理n系统中的所有硬件设备看起来都和一般的文件一样,它们可以使用处理文件的标准系统调用来打开、关闭和读写。n系统中的每一个设备都由一个设备文件来代表,设备文件名由主设备号和从设备号组成。例如,主IDE硬盘的设备文件是/dev/hda。一个设备驱动程序控制的所有设备有一个相同的主设备号,通过不同的从设备号来区分设备和它们的控制器。例如,主IDE硬盘的每一个分区都有一个不同的从设备号,这样主IDE硬盘的第二个分区的设备文件是/dev/hda2。Linux系统使用主设备号和系统中的一些表来将
20、系统调用中使用的设备文件映射到设备驱动程序中。Linux 系统支持三种类型的硬件设备n字符设备:字符设备是直接读取的,不必使用缓冲区。n块设备:块设备每次只能读取一定大小的块的倍数,通常一块是512或者1024字节。块设备通过缓冲区读写,并且可以随机地读写。块设备可以通过它们的设备文件存取,但通常是通过文件系统存取。只有块设备支持挂接的文件系统。n网络设备:网络设备是通过BSD套接字接口存取的。设备管理设备管理n对设备的识别使用设备类型、主设备号、次设备号n设备类型:字符设备还是块设备。n按照设备使用的驱动程序不同而赋予设备不同的主设备号。主设备号是与驱动程序一一对应的,n同时还使用次设备号来
21、区分一种设备中的各个具体设备。次设备号用来区分使用同一个驱动程序的个体设备。设备文件 nLinux设备管理的基本特点是把物理设备看成文件,采用处理文件的接口和系统调用来管理控制设备。从抽象的观点出发,Linux的设备又称为设备文件。n设备文件也有文件名,设备文件名一般由两部分组成n第一部分23个字符,表示设备的种类,如串口设备是cu,并口设备是lp,IDE普通硬盘是hd,SCIS硬盘是sd,软盘是fp等。n第二部分通常是字母或数字,用于区分同种设备中的单个设备,如hda、hdb、hdc分别表示第一块、第二块、第三块IED硬盘。而hda1、hda2表示第一块硬盘中的第一、第二个磁盘分区。n设备文
22、件一般置于/dev目录下,如/dev/hda2、/dev/lp0等。nLinux使用虚拟文件系统VFS做为统一的操作接口来处理文件和设备。n与普通的目录和文件一样,每个设备也使用一个VFSinode来描述,其中包含着该种设备的主、次设备号。n对设备的操作也是通过对文件操作的file_operations结构体来调用驱动程序的设备服务子程序。常用module命令n与modules有关的命令有:lsmode:列出已经被内核调入的模块 insmode:将某个module插入到内核中 rmmod:将某个module从内核中卸载 depmod:生成依赖文件,告诉将来的 insmod 要从哪儿调入 mod
23、ules。这个依赖 文件就在/lib/modules/你的kernel版本/modules.dep。Kerneld:负责自动的将模块调入内核和把模块从内核中卸载。n命令位置/sbin 一个内核模块的例子 n#include /所有模块都需要的头文件n#include /init&exit相关宏nMODULE_LICENSE(GPL);nstatic int _init hello_init(void)nnprintk(Hello module initn);nreturn 0;nnstatic void _exit hello_exit(void)nnprintk(Hello module e
24、xitn);nnmodule_init(hello_init);nmodule_exit(hello_exit);一个内核模块的例子n一个Linux内核模块需包含模块初始化和模块卸载函数,前者在 insmod的时候运行,后者在rmmod的时候运行。n初始化与卸载函数必须在宏module_init和module_exit使用前定义,否则会出现编译错误。n程序中的MODULE_LICENSE(GPL)用于声明模块的许可证。一个内核模块的例子n如果要把上述程序编译为一个运行时加载和删除的模块,可以编写makefile文件如下:nCC=/usr/local/arm/2.95.3/bin/arm-lin
25、ux-gcc nKERNELDIR=/home/work/linux-2.4nCFLAGS=-D_KERNEL_-DMODULE-I$(KERNELDIR)/include-O-Wall nhello.o:$(CC)$(CFLAGS)-c$nclean:n rm-rf*.o一个内核模块的例子n下列命令将可加载hello模块:ninsmod./hello.o n下列命令完成相反过程:nrmmod hello 注意n在Linux内核模式下,我们不能使用用户态的malloc()和free()函数申请和释放内存。进行内核编程时,最常用的内存申请和释放函数为在include/linux/kernel.h文件中声明的kmalloc()和kfree()n在内核编程中,我们不能使用用户态C库函数中的printf()函数输出信息,而只能使用 printk()。n但是,内核中printk()函数的设计目的并不是为了和用户交流,它实际上是内核的一种日志机制,用来记录下日志信息或者给出警告提示。每个printk都会有个优先级,内核一共有8个优先级,它们都有对应的宏定义。如果未指定优先级,内核会选择默认的优先级
限制150内