Linux内核是宏/单内核,分5个模块:进程调度模块、内存管理模块、文件系统模块、进程间通讯模块、网络接口模块。
三种地址概念:
虚拟地址(Virtual Address)、逻辑地址(Logical Address):是程序产生的。虚拟地址由段选择符和段内偏移两部分组成,段内偏移又称逻辑地址。需根据GDT和LDT进行分段变换才能进行下一步地址处理。x86可以索引2^14个段选择符,每个段最长2^32B,最大虚拟地址空间为2^46(64T)B。
线性地址(Linear Address):是虚拟地址到物理地址转化的中间层,是处理器可寻址的内存空间中的地址,由逻辑地址加上对应段基址得到。如未开启分页机制,就等于物理地址。x86中线性地址空间为4GB。
物理地址(Physical Address):是在CPU地址线和其他外部总线上的地址信号。
Linux0.11内核,限制了GDT最大表项为256个,其中2项空闲(NULL/syscall),2项系统使用(Kernel Code/Data),每个进程使用两项(LDT,TTS)。但系统定义了最大进程数是64个,每个进程逻辑地址范围是64M,在线性地址空间中的起始位置是64MB*进程号,全部进程使用的地址空间是64*64MB=4GB。每个进程的代码段和数据段是完全重叠的。其中进程0和进程1比较特殊,分别占用了线性地址0和64M开头的640K地址,进程0还处于内核区。进程2开始就占用128MB开始的64MB空间,依次类推。
Linux0.11内核中,head.s把内核代码段和数据段都初始化为从线性地址0开头的16MB空间,包括内核所有的代码、内核段表(GDT、IDT、TTS)、页目录表和内核二级页表、内核局部数据以及临时栈(将被用于进程0的用户栈)。其中内核使用了4个二级页表和4项页目录,把0-16MB的线性地址映射到物理空间,而且其物理空间等于线性空间。但如果物理内存不满16MB,那么线性地址就不会映射到超过物理大小的内存上去。
进程0:系统中第一个启动的进程,它的代码段和数据段均在内核中,长度为640K,占用线性和物理地址空间中中的0——640K-1的范围。使用的是内核中的页目录和页表(内核页表是用户可读写的),对应的TSS0也是事先设置好的,位于sched.c文件中,长度为104字节。
进程1:(init进程)的代码也在内核代码区中,但当使用fork()来创建它的时候申请了一页内存作为二级页表,并复制了父进程(进程0)的页目录项和页表。它占用了64M——128M-1(实际使用为64M——64M+640K-1的范围)的线性空间,并映射到0——640K-1的物理空间,跟进程0使用的范围一样,长度也是640K。系统还为init进程申请一页内存放置任务数据结构(包括TSS)和init进程的内核态栈。init进程的用户态栈共享了进程0的用户态堆栈。但在init进程执行时,其用户态堆栈对应页表项被设置位只读,这是系统会分配新的页面给其使用。
进程N:使用fork()从init进程产生其他进程时,其过程和从进程0 fork()出init进程基本一致(只有对应的线性空间不同)。然后调用execve()开始加载进程映像的时候,是释放掉从任务1复制的页目录和页表表项以及对应的内存页面,然后重新设置相关页目录和页表。分配给的内存并不是立即生效,而是在需要访问的时候引发缺页异常,系统才会真正的分配物理内存给进程,这被称为Load on demand策略。
用户申请内存:使用库函数malloc()申请内存时,malloc()函数内部会为用户维护一个内存使用表,由库函数自定义策略决定什么时候去系统申请内存,或者释放内存,以及申请和释放的数量。通常来讲如果用户请求分配内存,库函数先看自己库存的内存是否够用,不够用再去向系统申请一块恰当大小的内存(如页的整数倍);用户释放内存的时候库函数也不会立刻将其释放给操作系统,而是缓存起来,等待用户下次的分配请求,直到进程退出,才会把所有内存交还给系统。从系统中申请的内存同样遵守Load on demand策略,只有在用户去实际访问这块内存的时候,系统才会把物理内存映射到指定位置。
分享到:
相关推荐
第5章 中断和异常 192 5.1 基础知识 193 5.1.1 中断和异常的定义 193 5.1.2 中断和异常的分类 193 5.1.3 中断和异常的对比 194 5.2 处理机制 195 5.2.1 IA32架构下的处理机制 195 5.2.2 Linux内核的...
第5章 中断和异常 192 5.1 基础知识 193 5.1.1 中断和异常的定义 193 5.1.2 中断和异常的分类 193 5.1.3 中断和异常的对比 194 5.2 处理机制 195 5.2.1 IA32架构下的处理机制 195 5.2.2 Linux内核的...
第5章 中断和异常 192 5.1 基础知识 193 5.1.1 中断和异常的定义 193 5.1.2 中断和异常的分类 193 5.1.3 中断和异常的对比 194 5.2 处理机制 195 5.2.1 IA32架构下的处理机制 195 5.2.2 Linux内核的...
第5章 中断和异常 192 5.1 基础知识 193 5.1.1 中断和异常的定义 193 5.1.2 中断和异常的分类 193 5.1.3 中断和异常的对比 194 5.2 处理机制 195 5.2.1 IA32架构下的处理机制 195 5.2.2 Linux内核的...
第5章 中断和异常 192 5.1 基础知识 193 5.1.1 中断和异常的定义 193 5.1.2 中断和异常的分类 193 5.1.3 中断和异常的对比 194 5.2 处理机制 195 5.2.1 IA32架构下的处理机制 195 5.2.2 Linux内核的...
第5章 中断和异常 192 5.1 基础知识 193 5.1.1 中断和异常的定义 193 5.1.2 中断和异常的分类 193 5.1.3 中断和异常的对比 194 5.2 处理机制 195 5.2.1 IA32架构下的处理机制 195 5.2.2 Linux内核的...
第5章 中断和异常 192 5.1 基础知识 193 5.1.1 中断和异常的定义 193 5.1.2 中断和异常的分类 193 5.1.3 中断和异常的对比 194 5.2 处理机制 195 5.2.1 IA32架构下的处理机制 195 5.2.2 Linux内核的...
第5章 中断和异常 192 5.1 基础知识 193 5.1.1 中断和异常的定义 193 5.1.2 中断和异常的分类 193 5.1.3 中断和异常的对比 194 5.2 处理机制 195 5.2.1 IA32架构下的处理机制 195 5.2.2 Linux内核的...
- 分析了现代计算机体系结构中的分段机制,以及它是如何影响内核设计的。 - **2.3 Linux中的分段** - 探讨了Linux内核如何实现内存分段,以及它在保护内存区域方面的作用。 - **2.4 硬件分页** - 分页是现代...
第5章 嵌入式Linux开发环境的搭建 5.1 嵌入式开发环境的搭建 5.1.1 嵌入式交叉编译环境的搭建 5.1.2 超级终端和minicom配置及使用 5.1.3 下载映像到开发板 5.1.4 编译嵌入式Linux内核 5.1.5 Linux内核源码目录结构 ...
本书的第二章深入探讨了Linux内核中的内存管理机制,特别是关于内存寻址的细节: ##### 2.1 内存地址 本节介绍了计算机内存的基本概念,包括物理地址和虚拟地址的区别,以及它们在现代操作系统中的作用。 ##### ...
第5章 中断和异常 110 5.1 中断的基本知识 110 5.1.1 中断向量 110 5.1.2 外设可屏蔽中断 111 5.1.3 异常及非屏蔽中断 112 5.1.4 中断描述符表 112 5.1.5 相关汇编指令 113 5.2 中断描述符表的初始化 114 5.2.1 IDT...
#### 第5章:嵌入式Linux开发环境的搭建 - **5.1 嵌入式开发环境的搭建** - **5.1.1 嵌入式交叉编译环境的搭建**:指导如何搭建交叉编译环境。 - **5.1.2 超级终端和Minicom配置及使用**:介绍了如何配置和使用...
#### 第五部分:linux 2.6内核的移植 - 详细描述了Linux内核的移植过程,包括下载内核、修改Makefile、设置flash分区、配置内核等内容。 #### 第六部分:应用程序的移植 - **1 构造目标板的根目录及文件系统** - *...