zoukankan      html  css  js  c++  java
  • 以Qemu模拟Linux,学习Linux内核

    文章名称:以Qemu模拟Linux,学习Linux内核
    作      者:five_cent
    文章地址:http://www.cnblogs.com/senix/archive/2013/02/21/2921221.html
    维护日志:2013-02-21 建立文档
    (注:文章参考自http://www.linuxidc.com/Linux/2011-07/39373.htm, 是对该篇文章的一些补充和说明。文章内所使用的环境是Ubuntu 12.04,如果其中遇到编译问题,请自行参考错误说明,配置依赖环境)

    0.准备
    我们所有的工作都在指定目录下工作,使用以下变量来代替相关目录。
    $KERNEL     内核工作目录
    $LINUX       Linux内核源码目录
    $BUSYBOX  Busybox源码目录


    1.编译内核
    (1)下载合适的内核
    到http://www.kernel.org/上下载合适的内核,我选择的是linux-2.6.32,文件名是linux-2.6.32.60.tar.bz2。(选择使用这个版本是因为自己初学,最好使用低版本,防止新版本引入新的模块导致各种编译问题)
    复制linux-2.6.32.60.tar.bz2到$KERNEL,并通过以下命令解开文件

    $tar -xf linux-2.6.32.60.tar.bz2

    解压的文件保存在$KERNEL目录下的linux-2.6.32.60,为了避免差异化,下文使用$LINUX
    (2)编译内核
    每个内核都可能有自己的编译条件,为了避免差异化,请参考$LINUX/Documentation/HOWTO.以下是我的步骤

    $make help
    $make i386_defconfig
    $make

    2.安装qemu

    (1)ubuntu下安装

    $sudo apt-get install qemu

    我使用这个命令安装的是模拟器是qemu-system-i386和qemu-system-x86_64。因为我之前编译的linux内核是i386的,所以我创建一个软链接。

    $ln -s /usr/bin/qemu-system-i386 /usr/bin/qemu

    (2)源码安装
    到http://wiki.qemu.org/Download,下载适合的qemu源码,我下载的是qemu-1.3.1.tar.bz2,拷贝到$KERNEL目录,输入命令解压

    $tar -xf qemu-1.3.1.tar.bz2

    然后编译

    $./configure
    $make
    $make install


    3.编译busybox
    (1)下载busybox 源码
    到http://www.busybox.net/下载合适的busybox源码,我下载的是busybox-1.20.0.tar.bz2,拷贝到$KERNEL目录,输入命令解压

    $tar -xf busybox-1.20.0.tar.bz2

    (2)编译busybox

    $make defconfig
    $make menuconfig

    因为Linux运行环境当中是不带动态库的,所以必须以静态方式来编译BusyBox。修改

    Busybox Settings --->
        Build Options --->
             [*] Build BusyBox as a static binary(no shared libs)

    $make 
    $make install

    编译过程当中可能遇到

    inetd.c:(.text.prepare_socket_fd+0x8a): undefined reference to `bindresvport'

    $make menuconfig

    去掉不需要的功能,其它模块编译错误做法类似
    Networking Utilities ---> 
        [ ] inetd

    4.通过Qemu模拟Linux
    (1)编写initrd启动脚本

    $cd $BUSYBOX/_install
    #创建系统运行时的必须目录,其中,/proc用于挂载proc系统,/sys用于挂载sys系统,dev用于mdev创建设备节点,etc/init.d为放置busybox启动脚本的目录
    $mkdir proc sys dev etc etc/init.d
    $vim $BUSYBOX/_install/etc/init.d/rcS

    输入

    复制代码
    #!/bin/sh
    #将proc文件系统挂载到/proc目录,因为很多应用程序会使用到/proc中的信息,不挂载会导致各种异常
    mount -t proc none /proc
    #将sys文件系统挂载到/sys目录,因为很多应用程序会使用到/sys中的信息,不挂载会导致各种异常
    mount -t sysfs none /sys
    #mdev是busybox自带的一个udev,用于系统启动和热插拔或动态加载驱动程序时,自动产生设备节点,这句话如果不加上则需要手动mknod来挂载设备节点
    /sbin/mdev -s
    复制代码
    $chmod +x $BUSYBOX/_install/etc/init.d/rcS

    (注:为什么编辑这个文件呢?因为我们将使用busybox的init作为我们的Linux启动的第一个进程,而busybox的init所使用的启动脚本就是/etc/init.d/rcS,该路径被声明在$BUSYBOX/init/init.c当中)

    (2)编写构建initrd镜像脚本

    $vim $KERNEL/build-initrd.sh

    输入

    复制代码
    #!/bin/sh
    #定义变量 KERNEL=$(pwd) BUSYBOX=$(find busybox* -maxdepth 0) LINUX=$(find linux* -maxdepth 0)
    #通过cpio创建镜像 cd $BUSYBOX/_install find . | cpio -o --format=newc > $KERNEL/rootfs.img cd $KERNEL
    #通过gzip创建zip镜像 gzip -c rootfs.img > rootfs.img.gz
    复制代码
    $chmod +x build-initrd.sh

    (3)编写快速运行脚本

    $vim $KERNEL/run.sh
    #!/bin/sh
    #定义变量 LINUX=$(find linux* -maxdepth 0)
    #启动qemu qemu -kernel $LINUX/arch/i386/boot/bzImage -initrd rootfs.img.gz -append "root=/dev/ram rdinit=sbin/init noapic"

    5.其它说明
    镜像文件
    vmlinux                     编译出来的最原始的内核文件,未压缩
    zImage                      由mlinux经过gzip压缩后的文件
    bzImage big zImage。 zImage解压缩内核到低端内存(640K),bzImage解压缩内核到高端内存(1M以上)。如果内核比较小,采用zImage或者bzImage都行,如果比较大应该用bzImage。
    uImage                     U-boot专用的映像文件,它是在zImage之前加上一个长度为0x40的tag。
    vmlinuz                     是zImage/bzImage文件的拷贝或者是指向zImage/bzImage的链接。
    initrd                        initial ramdisk。linux系统引导过程当中挂载的一个临时根文件系统,被挂载于/dev/ram,它用于支持Linux第二阶段的引导过程。它是使用gzip进行压缩的cpio文件。

    QEMU
    qemu-system-i386        QEMU 模拟i386指令CPU的模拟器
    qemu-system-x86_64   QEMU 模拟x86_64指令CPU的模拟器
    qemu -kernel   参数,使用bzimage作为linux内核
    qemu -initrd    参数,指定initrd镜像
    qemu -append 参数,附加内核启动参数

    内核启动参数
    root=       使用哪个设备作为根文件系统。
    rdinit=      内核加载完毕之后,即运行initrd中指定路径的程序,来创建linux的第一个进程。
    init=         内核加载完毕之后,即运行initramfs中指定路径的程序,来创建linux的第一个进程。
    noapic      apic,高级可编程中断控制器。这里用于防止发生MP-BIOS BUG 8254 timer not connected。

    参考资料
    1.Qemu官方网站 http://www.qemu.org
    2.简单用Qemu模拟linux运行环境 http://www.linuxidc.com/Linux/2011-07/39373.htm
    3.initrd 内核描述文档 http://lxr.linux.no/linux/Documentation/initrd.txt
    4.initrd和initramfs http://blog.chinaunix.net/uid-25888519-id-3078218.html

  • 相关阅读:
    JS 的加密库简介
    十三、行为型模式之解释器、迭代器-----《大话设计模式》
    十二、行为型模式之中介者、访问者、备忘录-----《大话设计模式》
    十一、行为型模式之模板方法、职责链、策略-----《大话设计模式》
    十、行为型模式之观察者、命令、状态-----《大话设计模式》
    十、行为型模式之观察者、命令、状态-----《大话设计模式》
    九、结构型模式之装饰、组合、外观、享元-----《大话设计模式》
    八、结构型模式之适配器、桥接、代理-----《大话设计模式》
    七、创建型模式之建造者、原型、单例-----《大话设计模式》
    六、创建型模式之工厂模式进化史-----《大话设计模式》
  • 原文地址:https://www.cnblogs.com/findumars/p/5679704.html
Copyright © 2011-2022 走看看