摘要: 页式存储管理机制通过页面目录和页面表将每个线性地址转换成物理地址,当遇到下面几种情况就会使CPU产生一次缺页中断,从而执行预定的页面异常处理程序: ① 相应的页面目录或页表项为空,也就是该线性地址与物理地址的关系还没建立或者已经撤销 ② 相应的物理页面不在内存中 ③ 指令规定的访问方式与页面的权限不符 我们假设一个情景,当我们的用户程序将一个打开的文件通过mmap()映射到内存,然后又通过munmap()撤销映射。在撤销一个映射区间时,常常会在虚存地址空间中留下一个空洞,而相应的地址则不应继续使用了,但是,程序中可能会有错误继续访问这个已经撤销的区域,这时候,一次因越界访问一个无效... 阅读全文
posted @ 2013-10-18 15:22 linux_rookie 阅读(1177) 评论(0) 推荐(0) 编辑
摘要: 1、问:什么是系统调用?用户应用程序访问并使用内核所提供的各种服务的途径即是系统调用,也称系统调用接口层。2、问:为什么需要系统调用? ①系统调用作为内核和应用程序之间的中间层,扮演了一个桥梁角色,系统调用把应用程序的请求传达给内核,待内核处理完之后再将结果返回给应用程序② 系统调用可以为用户空间提供访问硬件资源的统一接口,以至于应用程序不必关心具体的硬件访问操作③ 系统调用可以对系统进行保护,保证系统的稳定和安全3、系统调用、API、POSIX、C库、系统命令、内核函数的区别?①在通常情况下,应用程序是通过操作系统提供的应用编程接口(API)而不是直接通过系统调用来编程②在UNIX世界里,最 阅读全文
posted @ 2013-10-18 13:51 linux_rookie 阅读(1201) 评论(0) 推荐(0) 编辑
摘要: 页面目录PGD、中间目录PMD和页面表PT分别是由表项pgd_t、pmd_t和pte_t构成的数组,而这些表项都是数据结构 1 /* 2 * These are used to make use of C type-checking.. 3 */ 4 #if CONFIG_X86_PAE 5 typedef struct { unsigned long pte_low, pte_high; } pte_t; 6 typedef struct { unsigned long long pmd; } pmd_t; 7 typedef struct { unsigned long long pg.. 阅读全文
posted @ 2013-10-18 11:17 linux_rookie 阅读(2544) 评论(0) 推荐(0) 编辑
摘要: linux 内核采用页式存储管理。虚拟地址空间划分成固定大小的“页面”,由MMU在运行时将虚拟地址映射成某个物理内存页面中的地址。页式内存管理比段式内存管理有很多好处,但是由于Intel是先使用段式管理的,然后才发明了页式管理,为了兼容,i386 CPU 一律对程序中使用的地址先进行段式映射,然后才能进行页式映射,既然CPU的硬件结构是这样,linux内核也只好服从intel的选择。通过一个例子看看linux内核是怎样在i386 CPU 上进行地址映射的。假设我们写了这么一个程序: 1 #include 2 3 greeting() 4 { 5 printf("hello, wo.. 阅读全文
posted @ 2013-10-18 11:05 linux_rookie 阅读(1631) 评论(0) 推荐(0) 编辑
摘要: 1. 用汇编语言编写部分核心代码的原因:① 操作系统内核中的底层程序直接与硬件打交道,需要用到一些专用的指令,而这些指令在C语言中并无对应的语言成分;② CPU中的一些特殊指令也没有对应的C语言成分,如关中断、开中断等等;③内核中的某些函数在运行时会非常频繁的被调用,因此效率就显得很重要,用汇编语言写的程序效率通常要比高级语言编写的高;④在某些特殊场合,一段程序的空间效率也会显得很重要;2. linux 采用了AT&T的386汇编语言格式,而没有用Intel的,它们之间的差别主要有:①在Intel格式中大多使用大写字母,而在AT&T格式中都使用小写字母;②在AT&T格式 阅读全文
posted @ 2013-10-18 11:04 linux_rookie 阅读(1447) 评论(0) 推荐(0) 编辑
摘要: 386 CPU中的页式存管的基本思路是:通过页面目录和页面表分两个层次实现从线性地址到物理地址的映射。这种映射模式在大多数情况下可以节省页面表所占用的空间。因为大多数进程不会用到整个虚存空间,在虚存空间中通常都留有很大的“空洞”。采用两层的方式,只要一个目录项所对应的的那部分空间是个空洞,就可以把该目录项设置为空,从而剩下了与之对应的页面表。当地址的宽度是32时,两层映射机制比较有效也比较合理,但是,当地址的宽度大于32位时就不够有效了。因此,linux 内核的映射机制设计成3层,在页面目录和页面表中间增设了一层“中间目录”,在代码中,页面目录称为PGD,中间目录称为PMD,而页面表则称为PT 阅读全文
posted @ 2013-10-18 11:02 linux_rookie 阅读(511) 评论(0) 推荐(0) 编辑
摘要: linux 内核的主体是以GNU的C语言编写的,GNU为此提供了编译工具gcc。GNU对C语言本身作了不少扩充。1) gcc 从 C++ 语言中吸收了“inline”和“const”。inline 函数的使用与#define 宏定义相似,但更有相对的独立性,也更安全,因为“inline”函数会进行参数的类型检查。使用inline 函数也有利于程序调试。如果编译时不加优化,则这些inline函数就是普通的、独立的函数,更便于调试。调试好了以后,再采用优化重新编辑一次,这些inline函数就像宏操作一样融入了引用处的代码中,有利于提高运行效率,由于inline函数的大量使用,相当一部分代码从.c文 阅读全文
posted @ 2013-10-18 10:59 linux_rookie 阅读(597) 评论(0) 推荐(0) 编辑
摘要: 可以看出,在页面目录中共有210= 1024个目录项,每个目录项指向一个页面表,而在每个页面表中又共有1024个页面描述项。由图看出来,从线性地址到物理地址的映射过程为:1)从CR3取得页面目录的基地址;2)以线性地址中的dir位段为下标,在目录中取得相应页面表的基地址;3)以线性地址中的page位段为下标,在所得到的的页面表中取得相应的页面描述项;4)将页面描述项中给出的页面基地址与线性地址中的offset位段相加得到物理地址;目录项结构为:目录项的直观表示如下图:页表项的结构基本上于此相同,但没有“页面大小”位ps,所以第8位保留不用,但第7位(在目录项中保留不用)则为D标志,表示该页面已 阅读全文
posted @ 2013-10-18 10:56 linux_rookie 阅读(265) 评论(0) 推荐(0) 编辑
摘要: 当我们说一个CPU是“16位”或“32”位时,指的是处理器中“算数逻辑单元”(ALU)的宽度。数据总线通常与ALU具有相同的宽度。当Intel决定在16位CPU 8086中采用1M字节的内存空间,地址总线的宽度也就确定了,那就是20位。问题就来了:既然是ALU是16位,也就是说直接加以运算的指针长度是16位,即这个指针所能代表的地址最多有216,不能达到20位地址总线所能寻址的最大空间,于是Intel在8086 CPU中设置了4个“段寄存器”:CS、DS、SS和ES,分别用于可执行代码、数据、堆栈和其他。每个段寄存器都是16位的,对应于地址总线中的高16位。每条“访内”指令中的“内部地址”都是 阅读全文
posted @ 2013-10-18 10:53 linux_rookie 阅读(559) 评论(0) 推荐(0) 编辑