课程学习总结报告
Posted liwj57csseblog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了课程学习总结报告相关的知识,希望对你有一定的参考价值。
报告要求:
请您根据本课程所学内容总结梳理出一个精简的Linux系统概念模型,最大程度统摄整顿本课程及相关的知识信息,模型应该是逻辑上可以运转的、自洽的,并举例某一两个具体例子(比如读写文件、分配内存、使用I/O驱动某个硬件等)纳入模型中验证模型。
Linux系统模型
Linux是一种操作系统,它是连接软件和硬件的一种特殊的系统软件:
Linux系统被设计用来管理软硬件资源,与硬件交互以及给用户提供一个良好的执行环境,在学习Linux操作系统之后,可以给它设计这样一个概念模型:
应用程序通过访问操作系统的api,请求系统服务,操作系统进行从用户态切换到内核态,进行系统调用,在进行服务之后,返回用户态,继续操作。
Linux内存分配机制
从以上的模型我们只能对Linux操作系统有一个大概的了解,对他的结构有一个宏观的概念,接下来以Linux内存分配为例,研究一下Linux操作系统的工作原理,并试着将这门课所学到的知识运用进来,使上述模型在逻辑上是能够运转的,自洽的。、
Linux 的虚拟内存管理概念:
1、每个进程都有独立的虚拟地址空间,进程访问的虚拟地址并不是真正的物理地址;
2、虚拟地址可通过每个进程上的页表(在每个进程的内核虚拟地址空间)与物理地址进行映射,获得真正物理地址;
3、如果虚拟地址对应物理地址不在物理内存中,则产生缺页中断,真正分配物理地址,同时更新进程的页表;如果此时物理内存已耗尽,则根据内存替换算法淘汰部分页面至物理磁盘中。
Linux 使用虚拟地址空间,大大增加了进程的寻址空间,由低地址到高地址分别为:
1、只读段:该部分空间只能读,不可写;(包括:代码段、rodata 段(C常量字符串和#define定义的常量) )
2、数据段:保存全局变量、静态变量的空间;
3、堆 :就是平时所说的动态内存, malloc/new 大部分都来源于此。其中堆顶的位置可通过函数 brk 和 sbrk 进行动态调整。
4、文件映射区域 :如动态库、共享内存等映射物理空间的内存,一般是 mmap 函数所分配的虚拟地址空间。
5、栈:用于维护函数调用的上下文空间,一般为 8M ,可通过 ulimit –s 查看。
6、内核虚拟空间:用户代码不可见的内存区域,由内核管理(页表就存放在内核虚拟空间)
当应用进程(如c语言使用malloc)申请内存时,调用系统api,系统从用户态进入内核态,在Linux系统上,程序被载入内存时,内核为用户进程地址空间建立了代码段、数据段和堆栈段,在数据段与堆栈段之间的空闲区域用于动态内存分配。 内核数据结构mm_struct中的成员变量start_code和end_code是进程代码段的起始和终止地址,start_data和 end_data是进程数据段的起始和终止地址,start_stack是进程堆栈段起始地址,start_brk是进程动态内存分配起始地址(堆的起始 地址),还有一个 brk(堆的当前最后地址),就是动态内存分配当前的终止地址。 C语言的动态内存分配基本函数是malloc(),在Linux上的基本实现是通过内核的brk系统调用。brk()是一个非常简单的系统调用,只是简单地改变mm_struct结构的成员变量brk的值。 mmap系统调用实现了更有用的动态内存分配功能,可以将一个磁盘文件的全部或部分内容映射到用户空间中,进程读写文件的操作变成了读写内存的操作。在 linux/mm/mmap.c文件的do_mmap_pgoff()函数,是mmap系统调用实现的核心。do_mmap_pgoff()的代码,只是新建了一个vm_area_struct结构,并把file结构的参数赋值给其成员变量m_file,并没有把文件内容实际装入内存。。
进程分配内存有两种方式,分别由两个系统调用完成:brk和mmap(不考虑共享内存)。
1、brk是将数据段(.data)的最高地址指针_edata往高地址推;
2、mmap是在进程的虚拟地址空间中(堆和栈中间,称为文件映射区域的地方)找一块空闲的虚拟内存
这两种方式分配的都是虚拟内存,没有分配物理内存。在第一次访问已分配的虚拟地址空间的时候,发生缺页中断,操作系统负责分配物理内存,然后建立虚拟内存和物理内存之间的映射关系。当缺页中断发生时,Linux系统进行以下操作:
1、检查要访问的虚拟地址是否合法
2、查找/分配一个物理页
3、填充物理页内容(读取磁盘,或者直接置0,或者啥也不干)
4、建立映射关系(虚拟地址到物理地址)
5、重新执行发生缺页中断的那条指令
只要进程请求内存,内核只要满足要求就会给其分配页面。如果进程不再需要页面,内核就会将其回收。
alloc_page()//该函数用于请求单页
alloc_pages()//该函数用于请求4个页面
__get_free_page()/__get_dma_pages() //返回32为虚拟地址,该地址是分配页面的首地址
__free_page()/__free_pages() //释放页面
每当页面被分配和回收的时候,系统都会遇到外部碎片或内存碎片的问题(即页面散布在内存中,即使可用页面足够多,但是无法分配大块的连续页面)。为了解决这个问题,Linux系统提供了伙伴算法。伙伴系统把内存中空闲块组成链表,将不同大小的空闲内存块组织起来(我猜测是将相同大小的组织在一起),虽然大小不一样,但是都是2的幂次方。当系统中有进程释放没存的时候,伙伴系统就会搜索与所释放块大小相等的可用空闲内存块,如果找到相邻的空闲块,就将其合并成两倍于自身大小的块。这种合并的块称为伙伴。
当内存分配完成,系统从内核态返回用户态。
心得体会
通过这个学期的学习,通过老师们对实际的代码的讲解,我对操作系统的理解大大加深了,大致知晓Linux是如何工作的,使我了解了Linux的很多知识。并且经过几次实际的实验操作,能够跟踪、调试Linux系统的运行机制。但是其内核模块也是相当复杂,不甚晦涩。虽有老师们的悉心讲解,但我感觉自己仅仅是摸到其新手门槛,要学习的知识浩如烟海,我了解到的仅是皮毛而已。因此虽然课程告一段落,但是对于linux的学习,不会止于linux课程的结束。
关于对课程的建议:
建议老师在讲课的时候能够加一些实践操作的环节,让学生能够有模板参照,能够更加深刻的理解Linux,学习起来也更加轻松。再次感谢Linux课程的李春杰老师和孟宁老师。让我对LInux产生浓厚的兴趣。
以上是关于课程学习总结报告的主要内容,如果未能解决你的问题,请参考以下文章