Linux源码阅读基础入门

来源:互联网 发布:用什么编写python 编辑:程序博客网 时间:2024/06/04 15:14

一、X86架构的学习

X86(微处理器执行的计算机语言指令集)Intel 最先开发的一种CPU体系结构的总称,现在PC的CPU 基本都是X86架构,X86架构X86指令集,冯若依曼结构X86的特点有:指令多,应用范围广,但效率就显得低一点。它属于CISC指令集。

Intel在8086CPU中设置了四个“段寄存器”:CS、DS、SS、和ES。

CPU这样归纳出实际上应该放上数据总线的地址:

①根据指令的性质来确定应该使用哪一个段寄存器,例如转移指令中的地址在代码码段,而取数指令的地址在数据段。这一点与实地址模式相同。

根据段寄存器的内容,找到相应的“地址段描述结构”。

③从地址段描述结构中得到基地址。

④将指令中发出的地址作为位移,与段描述结构中规定的段长度相比,看看是否越界。

⑤根据指令的性质和段描述符中的访问权限来确定是否越权。

将指令中发出的地址作为位移,与基地址相加而得出实际的“物理地址”。

 

二、AT&T和Intel汇编的差异
    Linux内核代码中使用的是AT&T的汇编,而国内教学大多数在Windows平台上进行,所以大部分读者所熟悉的都是Intel的汇编语法,这两种汇编在语法组成上主要有如下的区别:
1)前缀:

Intel汇编语法中,寄存器和立即数没有前缀,但AT&T中寄存器名称前需要加上"%",而立即数前加上"$",16进制前加上0x,jump/call的操作数前要加上'*'作为前缀。
2)操作数的方向:

    两者操作数方向正好相反,Intel汇编中的第一个操作数伪目的操作数,而第二个为源操作数,而AT&A汇编有点类似copy操作,第一个数为源操作数,第二个数为目的操作数。
3)操作数位宽:

    Intel汇编中,由特定的字符指定操作数的位宽,而在AT&A汇编中由操作码的最后一个字符来指定操作数的位宽b,w,l分别代表8位,16位,32位。
4)内存单元操作数,基寄存器用()而不是[]。
5)间接寻址方式不同:

      %segreg:disp(base,index,scale),除base之外都可选,等价于Intel: segreg:[base+index*scale+disp],总的来说,Intel汇编语法相对直观,通用形式中的SCALE,INDEX等都可以位空。

 

三、Linux内核编译系统主要包括以下文件:

   ①交互配置工具,这些文件是编译生成的可执行文件,它负责提供内核编译工程中的交互,并把用户配置交互的结果保存到.config文件。

   ②Kconfig文件,位于各个子目录下。这个文件必须符合Kconfig language规范,它定义了交互配置时的菜单信息等。

   ③.config文件,这是内核配置文件,由配置工具生成.config文件,该文件由config_xxx=z组成,其中z是y,m,空,数字或者字符串。

   ④ Scripts/Makefile.*,这些Makefile定义了各种编译选项和编译规则,如gcc,Id的参数等。

   ⑤顶层Makefile,这个文件接受make xxx命令,然后根据xxx做相应的操作,最主要操作是编译出内核文件vmlinux 和相关模块文件。

   ⑥ Kbuild Makefiles,分布在各个子目录下的Makefile,它并不符合GNU Makefile的语法,为了区别于通常意义上的Makefile,所以被称为Kbuild Makefile。

   ⑦*.cmd文件,把一个.c文件编译成.O文件后,如果再次编译时,Make会根据.O和.C文件的修改事件来判断是否需要再次编译该.c文件。

 

四、Linux内核编程

linux内核编程,有一个入口的module_init()函数;同时还有一个善后处理的函数:module_exit()。在编译的时候,不同于用户态下的编程;可以直接使用gcc编译器编译链接,就能够成为可执行的;

而是需要编写一个Makefile文件:如图(1)

 

如图(1)

交互配置工具

   通常编译X86的平台命令是make bzImage,打开Makefile 却找不到bzImage,于是在主Makefile中添加bzImage,再次输入make bzImage这样的话打开

linux-4.9\arch\x86\Makefile_32.cpu:如图(2)


如图(2)

 

五、Linux内核源代码中的汇编语言代码

汇编语言编写核心代码中的部分代码大体上是出于如下几个方面的考虑:

    ①操作系统内核中的底层程序直接与硬件打交道,需要用到一些专用的指令,而这些指令在C语言中并无对应的语言成分。

    ②CPU中的一些特殊指令也没有对应的C语言成分,如关中断,开中断等等。

    ③内核中实现某些操作的过程、程序段或函数,在运行时会非常频繁地被调用,因此其效率就显得很重要。

④在某些特殊地场合,一段程序地空间效率也显得非常重要。操作系统地应道程序就是一个例子。

 

六、在Linux内核地源代码中,以汇编语言编写的程序或程序段,有几种不同的形式:

   ㈠第一种是完全的汇编代码,这样的代码采用.S作为文件的后缀。事实上,尽管时“纯粹”的汇编代码,现在的汇编工具也吸收了C语言预处理的长处,也在汇编之前加了一趟预处理,而预处理的文件则以.S为后缀。此类(.S)文件也和C程序一样,可以使用#include、#ifdef等等成分,而数据结构也一样可以在.h文件中加以定义。

   第二种时嵌入在C程序中的汇编语言片段。虽然在ANSI的C语言标准中并没有关于汇编段的规定,事实上各种实际使用的CA汇编中都做了这方面的扩充,而GUN的C编译gcc也在这方面做了很强的扩充。

 

另外想进一步学习这部分的内容,除上面提到的文档或者链接地址外,推荐阅读

《独辟蹊径品内核:Linux内核源代码导读》李云华

http://vdisk.weibo.com/s/u4L8Ev6HHbzzC

0 0
原创粉丝点击