• 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程序的过于简单,使得系统优化不能完全起到应有的效果。

  • 相关阅读:
    C#枚举的key值获取枚举name名称OK
    《[C#] int与System.Int32有什么区别》
    《[C#] int与System.Int32有什么区别》
    《算法竞赛入门经典》习题43 黑白棋(Othello, ACM、ICPC World Finals 1992, UVa220)
    《算法竞赛入门经典》习题42 正方形 (Squares,ACM,ICPC World Finals 1990,UVa201)——仅提供大体方法
    《算法竞赛入门经典》习题42 正方形 (Squares,ACM,ICPC World Finals 1990,UVa201)——仅提供大体方法
    《算法竞赛入门经典》习题42 正方形 (Squares,ACM,ICPC World Finals 1990,UVa201)——仅提供大体方法
    百练4103:踩方格
    百练4103:踩方格
    百练4103:踩方格
  • 原文地址:https://www.cnblogs.com/boyangx/p/4041469.html
Copyright © 2020-2023  润新知