linux内核设计与实现 LINUX内核源代码情景分析

一. linux内核简介1. linux简介1.1 unix的特点

  • unix很简洁,仅提供几百个系统调用,并有非常明确的设计目的
  • unix所有东西都当作文件对待,这种抽象使对数据和设备都通过一套相同的系统调用接口进行
  • 内核用C语言编写,移植能力很强
  • 进程创建迅速,独特的fork调用
  • 提供了简洁但是稳定的进程间通讯原语
1.2 unix和linux
  • linux克隆unix,但不是unix
  • linux借鉴了unix很多的设计,并且实现了 unix的api
  • linux没有直接使用unix的源代码,但完整表达了unix的设计目标并保证编程接口一致
2. 操作系统和内核简介
  • 内核一般包括: 中断服务程序:负责响应中断 调度程序:管理多进程,分配处理器时间 内存管理程序:管理内存空间 系统服务程序:包括网络,进程间通讯
  • 应用程序通过系统调用和内核通讯来运行
  • 应用程序通常调用库函数,库函数通过系统调用让内核带其完成各种任务
  • 内核对硬件设备的管理:硬件想要通讯时,发送异步信号去打断内核,内核通过中断号查找处理程序
  • linux内核开发的特定 不能链接标准c函数库 。c库太大了,会影响大小和效率 。不过大部分常用的c函数在内核中都有实现 没有内存保护机制,要注意非法访问内存地址 不要轻易使用浮点数,要人工保存和恢复浮点寄存器 栈空间很小且固定 。32为机器为8kb,64为16kb 内核很容易产生竞争条件,注意同步和并发 注意可移植性
二. 进程管理1. 基本概念
  • unix系统的两大抽象对象:进程,文件 。
  • 进程是处于执行期的程序,linux通常也把进程叫做任务
  • 进程包括:代码段,数据段,打开的文件,挂起的信号,地址空间,线程等
  • 线程是进程中活动的执行对象
  • 每个线程拥有独立的程序计数器,进程栈和一组进程寄存器
  • 内核调度的对象是线程,而不是进程
  • linux的线程实现非常特别,并不特别区分线程和进程
  • 进程提供两种虚拟机制:虚拟处理器和虚拟内存
  • 同一个进程内的线程可以共享虚拟内存,但是有各自的虚拟处理器
2. 进程描述符及任务队列2.1 基本概念
  • 内核把进程存放在叫做任务队列的双向循环链表中
  • 链表中每一项都是task_struct类型,称为进程描述符,包括一个进程的所有信息 。路径:/include/linux/sched.h
imgSpider 采集中…
2.2 进程描述符如何分配
  • linux通过slab分配其分配task_struct结构,这样能达到对象复用和缓存着色
  • 通过预先分配和重复使用task_struct,避免动态分配和释放带来的性能损耗,这也是为什么创建进程快的原因
  • task_struct放在内核栈的尾端,为了让寄存器少的硬件体系只通过栈指针就能算出位置,避免使用额外寄存器存储
  • slab分配器在内核栈的尾部创建新的struct thread_info,内部的task指向实际的task_struct 。thread_info位置:
【linux内核设计与实现 LINUX内核源代码情景分析】imgSpider 采集中…
2.3 进程描述符存放在哪
  • current宏可以查找当前正在运行进程的进程描述符
  • 这个宏的具体实现根据各自硬件体系结构有所不同
  • x86体系,通过栈尾部的thread_info结构的task指针找到进程描述符
  • 有的体系(IBM的RISC),分配一个专用的寄存器存放task_struct的地址
2.4 进程的状态
  • 进程描述符的state字段描述了进程当前的状态,每个进程都处于五种状态的一种 TASK_RUNNING:运行 。进程是可执行的 。TASK_INTERRUPTIBLE:可中断 。进程被阻塞,等待被唤醒 TASK_UNINTERRUPTIBLE:不可中断 。收到信号不做任何响应 。ps命令查看会显示D TASK_ZOMBIE:僵死 。进程已经结束了,但是父进程还没有调用wait4系统调用 TASK_STOPPED:停止 。进程停止执行
  • 状态变迁图
imgSpider 采集中…
  • 设置当前进程:set_task_state(task,state)或set_current_state
2.5 进程上下文