?潭水无风?

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

一、简介

QEMU是一套由法布里斯·贝拉(Fabrice Bellard)所编写的以GPL许可证分发源码的虚拟操作系统模拟器,在GNU/Linux平台上使用广泛。Bochs,PearPC等与其类似,但不具备其许多特性,比如高速度及跨平台的特性,通过KQEMU这个闭源的加速器,QEMU能模拟至接近真实电脑的速度。
目前,0.9.1及之前版本的qemu可以使用kqemu加速器。在qemu1.0之后的版本,都无法使用kqemu,主要利用qemu-kvm加速模块,并且加速效果以及稳定性明显比kqemu好。

QEMU有两种主要运作模式:

  • * User mode模拟模式,亦即是用户模式。QEMU能启动那些为不同中央处理器编译的Linux程序。而Wine及Dosemu是其主要目标。
  • * System mode模拟模式,亦即是系统模式。QEMU能模拟整个电脑系统,包括中央处理器及其他周边设备。它使得为跨平台编写的程序进行测试及除错工作变得容易。其亦能用来在一部主机上虚拟数部不同虚拟电脑。

QEMU的主体部份是在LGPL下发布的,而其系统模式模拟则是在GPL下发布;而kqemu这个加速器则是在免费但闭源的条件下发布的。使用kqemu可使QEMU能模拟至接近实机速度,但其在虚拟的操作系统是 Microsoft Windows 98或以下的情况下是无用的。

二、安装配置方法

(1)源码安装

到http://wiki.qemu.org/Download,下载适合的qemu源码,我下载的是qemu-1.3.1.tar.bz2,拷贝到内核工作目录,输入命令解压


$tar -xf qemu-1.3.1.tar.bz2

然后编译

1 $./configure
2 $make
3 $make install

 

(2)在线安装

Arch:

pacman -S qemu

Debian/Ubuntu:

apt-get install qemu

Fedora:

dnf install @virtualization

Gentoo:

emerge --ask app-emulation/qemu

RHEL/CentOS:

yum install qemu-kvm

SUSE:

zypper install qemu

 

注意:如果编译的linux内核是i386的,需要创建一个软链接,通过以下命令安装的是模拟器是qemu-system-i386和qemu-system-x86_6:

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

 

三、使用方法(i386:以Qemu模拟Linux,学习Linux内核)

  • 内核工作目录:内核相关代码存放目录,Busybox,qemu,kernel全部存放于此目录下
  • Linux内核源码目录:linux内核源码压缩包解压后的根目录
  • Busybox源码目录:Busybox源码解压缩后的根目录

 

1.编译内核
(1)下载合适的内核
到http://www.kernel.org/上下载合适的内核,本文件名是linux-2.6.32.60.tar.bz2。
复制linux-2.6.32.60.tar.bz2到Linux内核工作目录,并通过以下命令解开文件

$tar -xf linux-2.6.32.60.tar.bz2

(2)编译内核
每个内核都可能有自己的编译条件,为了避免差异化,请参考Linux内核源码目录/Documentation/HOWTO.以下是参考步骤:

$make help
$make i386_defconfig
$make

 

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

$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

 

3.通过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  内核工作目录/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 >  内核工作目录/rootfs.img
cd  内核工作目录#通过gzip创建zip镜像
gzip -c rootfs.img > rootfs.img.gz

赋予执行权限

$chmod +x build-initrd.sh

 

(3)编写快速运行脚本

$vim Linux内核源码目录/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"

附:其它说明
镜像文件

  • 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。

 

posted on 2020-12-21 12:44  万物拾光  阅读(1191)  评论(0)    收藏  举报