操作系统存储器管理课程设计报告.docx
《操作系统存储器管理课程设计报告.docx》由会员分享,可在线阅读,更多相关《操作系统存储器管理课程设计报告.docx(21页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、流程图任务执行路径进程地址间的治理模型页表治理内存虚拟空间3. 相关代码设计linux/memory.c 程序代码#include / 信号头文件。定义信号符号常量,信号构造以及信号操作函数原型。#include / 系统头文件。定义了设置或修改描述符/中断门等的嵌入式汇编宏。#include / 调度程序头文件,定义了任务构造 task_struct、初始任务 0 的数据,/ 还有一些有关描述符参数设置和猎取的嵌入式汇编函数宏语句。#include / head 头文件,定义了段描述符的简洁构造,和几个选择符常量。#include / 内核头文件。含有一些内核常用函数的原形定义。volati
2、le void do_exit(long code);/ 进程退出处理函数,在 kernel/exit.c。/ 显示内存已用完出错信息,并退出。static inline volatile void oom(void)printk(“out of memorynr“);do_exit(SIGSEGV);/do_exit 应当使用退出代码, 这里用了信号值SIGSEGV(11)/ 一样值的出错码含义是“资源临时不行用”,正好同义。/ 刷页变换高速缓冲宏函数。/ 为了提高地址转换的效率,CPU 将最近使用的页表数据存放在芯片中高速缓冲中。在修改正页表/ 信息之后,就需要刷该缓冲区。这里使用重加载页
3、名目基址存放器cr3 的方法来进展刷。/ 下面 eax = 0,是页名目的基址。#define invalidate asm(“movl %eax,%cr3“:“a“ (0)/* these are not to be changed without changing head.s etc */* 下面定义假设需要改动,则需要与 head.s 等文件中的相关信息一起转变 */ linux 0.11 内核默认支持的最大内存容量是 16M,可以修改这些定义以适合更多的内存。#define LOW_MEM 0x100000/ 内存低端1MB。#define PAGING_MEMORY (15*102
4、4*1024)/ 分页内存 15MB。主内存区最多15M。#define PAGING_S (PAGING_MEMORY12)/ 分页后的物理内存页数。#define MAP_NR(addr) (addr)-LOW_MEM)12)/ 指定内存地址映射为页号。#define USED 100/ 页面被占用标志/ CODE_SPACE(addr) (addr)+0xfff)&0xfff) start_code + current-end_code。)/ 该宏用于推断给定地址是否位于当前进程的代码段中。#define CODE_SPACE(addr) (addr)+4095)&4095) start
5、_code + current-end_code)static long HIGH_MEMORY = 0;/ 全局变量,存放实际物理内存最高端地址。/ 复制 1 页内存4K 字节。#define copy_(from,to) asm(“cld ; rep ; movsl“:“S“ (from),“D“ (to),“c“ (1024):“cx“,“di“,“si“)/ 内存映射字节图,每个页面对应的字节用于标志页面当前被引用占用次数。static unsigned char mem_map PAGING_S = 0,;* Get physical address of first (actual
6、ly last :-) free , and mark it* used. If no free s left, return 0.* 猎取首个(实际上是最终 1 个:-)空闲页面,并标记为已使用。假设没有空闲页面,* 就返回 0。/ 取空闲页面。假设已经没有可用内存了,则返回 0。/输 入 : %1(ax=0)-0; %2(LOW_MEM); %3(cx=PAGINGS) ;%4(edi=mem_map+PAGING_S-1)。/ 输出:返回%0(ax=页面起始地址)。/ 上面%4 存放器实际指向 mem_map内存字节图的最终一个字节。本函数从字节图末端开头向前扫描/ 全部页面标志页面总数
7、为 PAGING_S,假设有页面空闲其内存映像字节为 0则返回页面地址。/ 留意!本函数只是指出在主内存区的一页空闲页面,但并没有映射到某个进程的线性地址去。后面/ 的 put_函数就是用来作映射的。unsigned long get_free_(void)register unsigned longres asm(“ax“); asm(“std ; repne ; scasbnt“/ 方向位置位,将 al(0)与对应每个页面的(di)内容比较, “jne 1fnt“/ 假设没有等于 0 的字节,则跳转完毕返回 0。movb $1,1(%edi)nt/ 将对应页面的内存映像位置 1。sall
8、$12,%ecxnt“/ 页面数*4K = 相对页面起始地址。“addl %2,%ecxnt“/ 再加上低端内存地址,即获得页面实际物理起始地址。“movl %ecx,%edxnt“/ 将页面实际起始地址edx 存放器。“movl $1024,%ecxnt“/ 存放器 ecx 置计数值 1024。leal 4092(%edx),%edint“/ 将 4092+edx 的位置edi(该页面的末端)。rep ; stoslnt“/ 将 edi 所指内存清零反方向,也马上该页面清零。“movl %edx,%eaxn“/ 将页面起始地址eax返回值。“1:“:“=a“ (res): “ (0),“i“
9、 (LOW_MEM),“c“ (PAGING_S), “D“ (mem_map+PAGING_S-1):“di“,“cx“,“dx“);return res;/ 返回空闲页面地址假设无空闲也则返回 0。* Free a of memory at physical address ”addr”. Used by* ”free_tables”* 释放物理地址”addr”开头的一页内存。用于函数”free_tables”。/ 释放物理地址 addr 开头的一页面内存。/ 1MB 以下的内存空间用于内核程序和缓冲,不作为安排页面的内存空间。void free_(unsigned long addr)i
10、f (addr = HIGH_MEMORY)/ 假设物理地址 addr 内存最高端,则显示出错信息。panic(“trying to free nonexistent “);addr -= LOW_MEM;/ 物理地址减去低端内存位置,再除以 4KB,得页面号。addr = 12;if (mem_mapaddr-) return; / 假设对应内存页面映射字节不等于 0,则减 1 返回。死机。mem_mapaddr=0;/ 否则置对应页面映射字节为 0,并显示出错信息,panic(“trying to free free “);* This function frees a continuos
11、 block of tables, as needed* by ”exit”. As does copy_tables, this handles only 4Mb blocks.* 下面函数释放页表连续的内存块,”exit”需要该函数。与 copy_tables* 类似,该函数仅处理 4Mb 的内存块。/ 依据指定的线性地址和限长页表个数,释放对应内存页表所指定的内存块并置表项空闲。/ 页名目位于物理地址 0 开头处,共 1024 项,占 4K 字节。每个名目项指定一个页表。/ 每个页表项对应一页物理内存4K。/ 参数:from - 起始基地址;size - 释放的长度。int free_t
12、ables(unsigned long from,unsigned long size)unsigned long *pg_table; unsigned long * dir, nr;if (from & 0x3fffff)/ 要释放内存块的地址需以 4M 为边界。panic(“free_tables called with wrong alignment“);if (!from)/ 出错,试图释放内核和缓冲所占空间。panic(“Trying to free up swapper memory space“);/ 计算所占页名目项数(4M 的进位整数倍),也即所占页表数。size = (s
13、ize + 0x3fffff) 22;/ 下面一句计算起始名目项。对应的名目项号=from22,因每项占 4 字节,并且由于页名目是从/ 物理地址 0 开头,因此实际的名目项指针=名目项号20)。与上 0xffc 确保/ 名目项指针范围有效。dir = (unsigned long *) (from20) & 0xffc); /* _pg_dir = 0 */for ( ; size-0 ; dir+) / size 现在是需要被释放内存的名目项数。if (!(1 & *dir)/ 假设该名目项无效(P 位 0),则连续。continue;/ 名目项的位 0(P 位)表示对应页表是否存在。pg
14、_table = (unsigned long *) (0xfffff000 & *dir);/ 取名目项中页表地址。for (nr=0 ; nr20) & 0xffc); /* _pg_dir = 0 */ to_dir = (unsigned long *) (to20) & 0xffc);/ 计算要复制的内存块占用的页表数也即名目项数。size = (unsigned) (size+0x3fffff) 22;/ 下面开头对每个占用的页表依次进展复制操作。for( ; size-0 ; from_dir+,to_dir+) / 假设目的名目项指定的页表已经存在(P=1),则出错,死机。if
15、 (1 & *to_dir)panic(“copy_tables: already exist“);/ 假设此源名目项未被使用,则不用复制对应页表,跳过。if (!(1 & *from_dir)continue;/ 取当前源名目项中页表的地址from_table。from_table = (unsigned long *) (0xfffff000 & *from_dir);/ 为目的页表取一页空闲内存,假设返回是 0 则说明没有申请到空闲内存页面。返回值=-1,退出。if (!(to_table = (unsigned long *) get_free_) return -1;/* Out o
16、f memory, see freeing */ 设置目的名目项信息。7 是标志信息,表示(Usr, R/W, Present)。*to_dir = (unsigned long) to_table) | 7;/ 针对当前处理的页表,设置需复制的页面数。nr = (from0)?0xA0:1024;/ 对于当前页表,开头复制指定数目 nr 个内存页面。for ( ; nr- 0 ; from_table+,to_table+) this_=*from_table;/取 源 页 表 项 内 容 。if (!(1 & this_)/ 假设当前源页面没有使用,则不用复制。continue;/ 复位页
17、表项中 R/W 标志(置 0)。(假设 U/S 位是 0,则 R/W 就没有作用。假设 U/S 是 1, 而 R/W 是 0,/ 那么运行在用户层的代码就只能读页面。假设 U/S 和 R/W 都置位,则就有写的权限。) this_ &= 2;*to_table = this_; / 将该页表项复制到目的页表中。/ 假设该页表项所指页面的地址在 1M 以上,则需要设置内存页面映射数组 mem_map, 于是计算/ 页面号,并以它为索引在页面映射数组相应项中增加引用次数。if (this_ LOW_MEM) / 下面这句的含义是令源页表项所指内存页也为只读。由于现在开头有两个进程共用内存区了。/
18、假设其中一个内存需要进展写操作,则可以通过页特别的写保护处理,为执行写操作的进程安排/ 一页的空闲页面,也即进展写时复制的操作。*from_table = this_; / 令源页表项也只读。this_ -= LOW_MEM; this_ = 12;mem_mapthis_+;invalidate;/ 刷页变换高速缓冲。return 0;* This function puts a in memory at the wanted address.* It returns the physical address of the gotten, 0 if* out of memory (eithe
19、r when trying to access -table or* .)* 下面函数将一内存页面放置在指定地址处。它返回页面的物理地址,假设* 内存不够(在访问页表或页面时),则返回 0。/ 把一物理内存页面映射到指定的线性地址处。/ 主要工作是在页名目和页表中设置指定页面的信息。假设成功则返回页面地址。unsigned long put_(unsigned long ,unsigned long address)unsigned long tmp, *_table;/* NOTE ! This uses the fact that _pg_dir=0 */* 留意!这里使用了页名目基址_p
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 存储器 管理 课程设计 报告
限制150内