linux 内核采用页式存储管理.虚拟地址空间划分成固定大小的"页面",由MMU在运行时将虚拟地址映射成某个物理内存页面中的地址.页式内存管理比段式内存管理有很多好处,但是由于Intel是先使用段式管理的,然后才发明了页式管理,为了兼容,i386 CPU 一律对程序中使用的地址先进行段式映射,然后才能进行页式映射,既然CPU的硬件结构是这样,linux内核也只好服从intel的选择.通过一个例子看看linux内核是怎样在i386 CPU 上进行地址映射的. 假设我们写了这么一个程序:…
http://blog.sina.com.cn/s/blog_6b94d5680101vfqv.html Linux内核源代码情景分析---第五章 文件系统  5.1 概述 构成一个操作系统最重要的就是 进程管理 与 文件系统: 有些操作系统有进程管理而没有文件系统,有些操作系统有文件系统而没有进程管理(MSDOS):两者都没有那就不是操作系统了: 狭义的文件:指磁盘文件,进入指可以是有序地存储在任何介质中(包括内存)的一组信息. 广义的文件:(unix把外部设备也当成文件)凡是可以产生或消耗信…
父进程fork子进程: child = fork() fork经过系统调用.来到了sys_fork.具体过程请參考Linux内核源码情景分析-系统调用. asmlinkage int sys_fork(struct pt_regs regs) { return do_fork(SIGCHLD, regs.esp, &regs, 0); } int do_fork(unsigned long clone_flags, unsigned long stack_start, //stack_start…
386 CPU中的页式存管的基本思路是:通过页面目录和页面表分两个层次实现从线性地址到物理地址的映射.这种映射模式在大多数情况下可以节省页面表所占用的空间.因为大多数进程不会用到整个虚存空间,在虚存空间中通常都留有很大的"空洞".采用两层的方式,只要一个目录项所对应的的那部分空间是个空洞,就可以把该目录项设置为空,从而剩下了与之对应的页面表.当地址的宽度是32时,两层映射机制比较有效也比较合理,但是,当地址的宽度大于32位时就不够有效了. 因此,linux 内核的映射机制设计成3层,在…
linux 内核的主体是以GNU的C语言编写的,GNU为此提供了编译工具gcc.GNU对C语言本身作了不少扩充. 1) gcc 从 C++ 语言中吸收了"inline"和"const".inline 函数的使用与#define 宏定义相似,但更有相对的独立性,也更安全,因为"inline"函数会进行参数的类型检查.使用inline 函数也有利于程序调试.如果编译时不加优化,则这些inline函数就是普通的.独立的函数,更便于调试.调试好了以后,再…
上一节中,我们浏览了一次因越界访问而造成映射失败从而引起进程流产的过程,不过有时候,越界访问时正常的.现在我们就来看看当用户堆栈过小,但是因越界访问而"因祸得福"得以伸展的情景. 假设在进程运行的过程中,已经用尽了为本进程分配的堆栈空间,此时CPU 中的堆栈指针%esp已经指向堆栈区间的起始地址,如下图 假设现在需要调用某个子程序,因此CPU 需将返回地址压入堆栈,也就是要将返回地址写入虚存空间中地址为(%esp-4)的地方,可以在我们这个情景中地址(%esp-4)落入了空洞中,这是尚…
一.中断初始化 1.中断向量表IDT初始化 void __init init_IRQ(void) { int i; #ifndef CONFIG_X86_VISWS_APIC init_ISA_irqs(); #else init_VISWS_APIC_irqs(); #endif /* * Cover the whole vector space, no vector can escape * us. (some of these will be overridden and become *…
页式存储管理机制通过页面目录和页面表将每个线性地址转换成物理地址,当遇到下面几种情况就会使CPU产生一次缺页中断,从而执行预定的页面异常处理程序: ① 相应的页面目录或页表项为空,也就是该线性地址与物理地址的关系还没建立或者已经撤销 ② 相应的物理页面不在内存中 ③ 指令规定的访问方式与页面的权限不符 我们假设一个情景,当我们的用户程序将一个打开的文件通过mmap()映射到内存,然后又通过munmap()撤销映射.在撤销一个映射区间时,常常会在虚存地址空间中留下一个空洞,而相应的地址则不应继续使…
页面目录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; }…
1. 用汇编语言编写部分核心代码的原因: ① 操作系统内核中的底层程序直接与硬件打交道,需要用到一些专用的指令,而这些指令在C语言中并无对应的语言成分: ② CPU中的一些特殊指令也没有对应的C语言成分,如关中断.开中断等等: ③ 内核中的某些函数在运行时会非常频繁的被调用,因此效率就显得很重要,用汇编语言写的程序效率通常要比高级语言编写的高: ④ 在某些特殊场合,一段程序的空间效率也会显得很重要: 2. linux 采用了AT&T的386汇编语言格式,而没有用Intel的,它们之间的差别主要有…