第一章 预备知识

1.1 linux内核简介

linux发展路线图

在这里插入图片描述

linux目录结构

在这里插入图片描述
在这里插入图片描述

GPL许可证

GPL条款规定GNU软件以及GNU软件的基础上加以修改而成的软件,在发布、转让、出售时必须要申明该软件出自GNU,并且必须要保证让接收者能够共享源代码,能从源代码重构可执行代码。

1.2 Intel X86系列的寻址方式

当一条访问内存指令发出一个内存地址时,CPU就可以这样来归纳出实际上应该放上数据总线的地址:

  1. 根据指令的性质来确定应该使用哪一个寄存器,例如转移指令中的地址在代码段,而取数指令中的地址在数据段。这一点与实地址模式相同。
  2. 根据段寄存器的内容,找到相应的“地址段描述结构”
  3. 从地址段描述结构中得到基地址
  4. 将指令中发出的地址作为位移,与段描述符结构中规定的段长度相比,看看是否越界
  5. 根据指令的性质和段描述符中的访问权限来确定是否越权
  6. 将指令中发出的地址作为位移,与基地址相加而得到实际的“物理地址”
    在这里插入图片描述

1.3 i386的页式内存管理机制

从线性地址到物理地址的映射过程为:

  1. 从CR3取得页面目录的基地址
  2. 以线性地址中的dir位段为下标,在目录中取得相应页面表的基地址
  3. 以线性地址中的page位段为下标,在所得到的页面表中取得相应的页面描述项
  4. 将页面描述项中给出的页面基地址与线性地址中的offset位段想加得到物理地址
    在这里插入图片描述

1.4 linux内核源代码中的C语言代码

  1. gcc在C++语言中吸收了inline和const
  2. 为了支持64位CPU结构,gcc增加了一个新的基本类型 long long int
  3. gcc支持不少的属性描述符,如__inline__ __asm__ __attribute__
  4. linux只能使用gcc编译,linux内核的各个版本有着对gcc版本的依赖关系。
  5. linux中的宏定义, do while(0)
  6. linux中的队列操作 list.h

1.5 linux内核源代码中的汇编语言代码

使用汇编的场景

  1. 底层和硬件打交道需要专用的指令
  2. CPU中的一些指令在C语言中没有对应的语法
  3. 内核操作需要频繁调用,效率要求比较高的场景
  4. 特殊场景,空间效率要求严格

linux内核使用的是GNU的386汇编语言。

GNU的386汇编语言和Intel汇编语言区别:

  1. 在 AT&T 汇编格式中,寄存器名要加上 ‘%’ 作为前缀;而在 Intel 汇编格式中,寄存器名不需要加前缀。
  2. 在 AT&T 汇编格式中,用 ‘$’ 前缀表示一个立即操作数;而在 Intel 汇编格式中,立即数的表示不用带任何前缀。
  3. AT&T 和 Intel 格式中的源操作数和目标操作数的位置正好相反。在 Intel 汇编格式中,目标操作数在源操作数的左边;而在 AT&T 汇编格式中,目标操作数在源操作数的右边。
  4. 在 AT&T 汇编格式中,操作数的字长由操作符的最后一个字母决定,后缀’b’、‘w’、'l’分别表示操作数为字节(byte,8 比特)、字(word,16 比特)和长字(long,32比特);而在 Intel 汇编格式中,操作数的字长是用 “byte ptr” 和 “word ptr” 等前缀来表示的。
  5. 在 AT&T 汇编格式中,绝对转移和调用指令(jump/call)的操作数前要加上’*'作为前缀,而在 Intel 格式中则不需要。
  6. 远程转移指令和远程子调用指令的操作码,在 AT&T 汇编格式中为 “ljump” 和 “lcall”,而在 Intel 汇编格式中则为 “jmp far” 和 “call far”
  7. 在 AT&T 汇编格式中,内存操作数的寻址方式是section:disp(base, index, scale)而在 Intel 汇编格式中,内存操作数的寻址方式为:section:[base + index*scale + disp]
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐