写作缘由:本书在2012年9月值2012年12月选择部分关键章节阅读,如今对一些关键部分进行整理,当复习
参考书籍:赵炯老师的《Linux内核完全解析 ----0.12内核》,想想花了不少大洋,得好好看好好整理,始终认为书籍是最可靠地投资。辅助CSAPP
写作心态:不定计划,开心的时候就写,务求让自己能再次理解下linux内核中的关键概念
原先总结的一些关键概念
- CS,IP是最重要的寄存器,CS:代码段寄存器 IP:指令指针寄存器 CS(M):IP(N)决定了CPU当前要读取的指令地址:16M+N(16位CPU)
- 8086通用寄存器:SS:堆栈内存段 SP:堆栈的栈顶 BP:指针寄存器
- 8086CPU的工作过程:a从CS:IP指向内存读取指令 b IP=IP+指令长度 c 执行指令,启动时候CS=FFFFH,IP=0000H
- MOV不能设置CS:IP的值,只能用转移指令
as86汇编器
- 能产生16位代码的汇编器,linux用它来创建16位的启动引导扇区boot/bootsect.s和实模式下初始设置程序boot/setup.s的二进制执行代码
- 汇编器产生的目标文件包括三个段或区,正文段(.text)(包括程序的执行代码和只读数据)、数据段(.data)(可读写数据)和未初始化数据段(.bss)
GNU as汇编
- 内核中除了boot/setup.s用as86进行编译,其它的内核程序均使用gas编译
- 编译C语言程序时,GNU gcc编译器首先输出as汇编语言文件,然后gcc会调用as汇编器把程序编译成目标文件
C语言程序
- 嵌入式汇编
asm("汇编语句" :输出寄存器 :输入寄存器 :会被修改的寄存器);
- 关键词volatile,不希望汇编语句被gcc优化而做更改 asm volatile(....),也可以放在函数名前修饰函数,用来通知编译器gcc该函数不会反悔,这样gcc会产生更好的代码
- 寄存器变量:允许我们将一些值放在CPU寄存器中,这样CPU不用花较长时间访问内存去取值。寄存器变量分为:全局的和局部的
- 内联函数:inline,去掉函数调用时进入\退出时间开销
- inline与static组合,如果没有存在一个不能被替换集成的调用,那么内联函数就不会编译,一个非静态的inline函数一定会产生自己的汇编代码
- inline与extern组合在一起的作用类同于宏定义。使用这种组合就是把带有关键词的函数放在.h头文件中,把不含关键词的另一个相同函数定义在库文件中。此时头文件中的定义会使绝大多数对函数的调用被替换嵌入。
linux 0.12目标文件格式
链接器如何将目标文件模块链接在一起?内核二进制文件Image的生成原理和过程
- bss是进程未初始化数据区,用来存放静态的未初始化的数据,开始执行时会被设置为0.而heap是堆空间区,用于分配进程在执行过程中动态申请的内存空间。
- 目标文件的链接操作
- 内核在编译过程中更具makefile配置文件使用make命令指挥编译器和链接程序操作完成。make利用内核代码中build临时工具,它主要将bootsect,setup,system文件头去掉,并且把它们顺序组成在一起,生成Image镜像文件