首页 > 代码库 > linux编译内核

linux编译内核

(1):准备好Linux主机环境,安装好开发工具链(说明低版本gcc的安装过程):

 

本次实验我使用的主机环境是Ubuntu10.04,其自带的内核是2.6.26。需要的工具有gcc4.1.3,qemu和SourceInsight。

 

低版本的gcc安装过程 :

 

首先,在终端里输入:sudo apt-get install gcc-4.1 g++4.1 linux-headers-$(uname -r)

 

然后运行一个脚本文件

 

这样就可以把linux默认的gcc版本换成gcc4.1.3.

 

(2):下载并缺省编译Linux-2.6.38,成功:

 

操作如下:

 

第一步从https://www.kernel.org/ 网址下载2.6.38的内核并解压缩;

 

第二步从终端进入到linux-2.6.38中,输入:make menuconfig,不过马上会出现一个缺少库文件的错误,此时输入:sudo apt-get install libncurses5-dev,就可以顺利安装好;

 

第三步是从进入系统本身的/boot文件夹中,使用查看隐藏文件的操作将其中的一个隐藏文件config-2.6.32-38-generic文件copy到下载下来的2.6.38的/boot文件夹中,并修改文件名为.config;

 

第四步是在终端里进入linux-2.6.38中,按顺序依次输入:make, make modules(编译内核模块), make modules_install(安装内核模块), mkinitramfs -o initrd.img-2.6.38 2.6.38,最后更新一下grub即可,输入:sudo update-grub。

 

   

 

(3):安装源代码阅读工具,推荐SourceInsight,并基于编译过的Linux-2.6.26源代码,建立Linux-2.6.26的源代码工程:

 

    • 若使用SourceInsight,建立利用SourceInsight的文件管理功能,去除arch目录和include目录下非x86的其他体系结构的源代码
    • 使用其他源码阅读工具,可是可以的
    • 要能看到若干Makefile文件
    • 要能看到若干*.lds文件

 

 

 

(4):使用主机环境中的工具重新编译test.c并反汇编,观察函数调用框架的形成、参数的传递、返回值的传递和局部变量的定义方法,比较与课堂上讲解的有什么区别:

 

反汇编代码,首先是进行拆分区域初始化,将初始化数据进行压栈操作

 

之后还是编辑程序,首先对寄存器esp清零,之后进入test的main函数体中,首先调用Add函数

 

mov       %eax,-0xc(%ebp)

 

mov       -0xc(%ebp),%eax

 

mov       %eax,0x4(%esp)

 

movl       $0xb,(%esp)

 

执行完之后返回到主函数,将结果返回到寄存器eax中,然后调用printf函数打印结果。之后对esp进行赋值找到下面要运行代码地址。然后接着调用Minus

 

函数。

 

通过观察反汇编可知,反汇编代码先进行初始化数据的压栈,然后对链接进行编译,之后开始执行主函数,在函数内再调用其他函数,形成函数调用框架,以及对数据进行压栈出栈操作,运算完毕返回主函数,将结果赋给通用寄存器,返回现场继续执行。

 

而函数框架为分区进行初始化,调用函数顺序,和结束处理。参数传递是运用栈操作,和move函数。而值得返回也是通过move操作传给寄存器输出。局部变量会赋给通用寄存器,当数据不再使用会将通用寄存器的值弹出或是重新赋值。

 

 

 

(5):对gcc的优化编译进行尝试,对采用不同优化编译选项得到的可执行文件,使用time命令来获得它们各自的运行时间并进行简单比较:

 

下载$ time ./m0

 

 

 

real 0m18.474s

 

user 0m18.397s

 

sys  0m0.024s

 

xby@ubuntu:~/下载$ time ./m1

 

 

 

real 0m0.001s

 

user 0m0.000s

 

sys  0m0.000s

 

xby@ubuntu:~/下载$ time ./m2

 

 

 

real 0m0.001s

 

user 0m0.000s

 

sys  0m0.000s

 

xby@ubuntu:~/下载$ time ./m3

 

 

 

real 0m0.001s

 

user 0m0.000s

 

sys  0m0.000

 

 

 

由此可见,优化编译确实可以给程序的运行效率带来很大提升,在用了m1的优化后,是效率提升最明显的,后面的m2,m3的效率提升就不是很大。我分析原因可能在于test程序的过于简单,使得系统优化不能完全起到应有的效果。

 

linux编译内核