1. 程式人生 > >Qemu虛擬機器中掛載NFS

Qemu虛擬機器中掛載NFS

在Qemu執行的虛擬機器中經常需要掛載NFS檔案系統,在CenterOS 6.0系統中做了一次配置,在虛擬機器中執行一個initramfs並在其中成功地掛載了NFS。下面是實驗步驟的記錄。

一、建立開發環境
yum groupinstall "Development Tools"
yum install glibc-static

二、安裝Qemu
yum install zlib
yum install SDL SDL-devel
yum install gnutls-devel
cd ~
wget http://wiki.qemu.org/download/qemu-0.15.1.tar.gz
tar zxvf qemu-0.15.1.tar.gz

cd qemu-0.15.1
./configure; make; make install
注意:編譯過程中可能出現"out of memory"錯誤,可以嘗試在Makefile中加入
    CFLAGS += $(CFLAGS) -pipe
來解決。

三、 製作一個initramfs用於啟動虛擬機器
cd ~
mkdir image
wget http://busybox.net/downloads/busybox-1.19.3.tar.bz2
tar jxvf busybox-1.19.3.tar.bz2
cd busybox-1.19.3
make defconfig
make menuconfig
    Build options

        --> Build BusyBox as a static binary (no shared libs) 
make
make install CONFIG_PREFIX=~/image
cd ~/image 
mkdir proc sys dev etc mnt 
mknod -m 600 dev/console c 5 1
mknod -m 600 dev/null c 1 3 
mkdir etc/init.d
emacs etc/init.d/rcS
    #!/bin/sh
    mount -t proc proc /proc
    mount -t sysfs sysfs /sys
    mdev -s

chmod +x etc/init.d/rcS
emacs etc/inittab
    ::sysinit:/etc/init.d/rcS
    tty1::askfirst:/bin/sh
    tty2::askfirst:/bin/sh
    tty3::askfirst:/bin/sh
    tty4::askfirst:/bin/sh
    tty5::askfirst:/bin/sh
    tty6::askfirst:/bin/sh
    ::restart:/sbin/init
    ::ctrlaltdel:/sbin/reboot
    ::shutdown:/bin/umount -a -r 
mv linuxrc init
find . | cpio -o -H newc | gzip > ~/image.cpio.gz
cd /usr/src
wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.34.tar.bz2
tar jxvf linux-2.6.34.tar.bz2
ln -s linux-2.6.34 linux
cd /usr/src/linux
make menuconfig
   Device Drivers
       --> Block devices
           --> RAM block device support (使用獨立的initrd)
make
make modules_install
qemu -kernel arch/x86/boot/bzImage -initrd ~/image.cpio.gz -vnc :1

四、配置虛擬網橋和TAP裝置,使宿主機與虛擬機器可以通訊


1. 如果核心不支援TAP裝置或虛擬網橋就需要編譯核心。Center OS 6.0預設是支援的,所以無需編譯核心。
yum install kernel
yum install ncurses-devel
    Device Drivers
                --> Network device support
                            --> Universal TUN/TAP device driver support (支援TAP裝置)
    Networking support
            --> Networking options
                        --> 802.1d Ethernet Bridging (支援虛擬網橋)
注:CenterOS有自己的一套編譯核心的方法。參見:

2. 安裝相關軟體並進行虛擬網橋和TAP裝置的配置。
yum install brctl
yum install tunctl
emacs /etc/sysconfig/network-scripts/ifcfg-eth0
    DEVICE="eth0"
    BOOTPROTO="dhcp"
    HWADDR="00:0C:29:20:dc:25"
    NM_CONTROLLED="yes"
    ONBOOT="yes"
    BRIDGE="br0"
emacs /etc/sysconfig/network-scripts/ifcfg-br0
    DEVICE="br0"
    TYPE="Bridge"
    BOOTPROTO="dhcp"
    ONBOOT="yes"
emacs /etc/qemu-ifup
    #!/bin/sh
    if [ -n "$1" ];then
        brctl addif br0 tap0
        ifconfig tap0 0.0.0.0 up
        exit 0
    else
        echo "Error: no interface specified"
        exit 1
    fi
emacs /etc/qemu-ifdown
    #! /bin/sh
    if [ -n "$1" ];then
        ifconfig tap0 down
        brctl delif br0 tap0
        exit 0
    else
        echo "Error: no interface specified"
        exit 1
    fi
chmod +x /etc/qemu-ifup
chmod +x /etc/qemu-ifdown

3. 測試虛擬機器與宿主機的連通性。
首先需要將宿主機的防火牆關閉:
/etc/init.d/iptables stop 
chkconfig iptables off
調整虛擬機器initramfs內容以支援DHCP客戶端:
cd ~/image
cp ~/busybox-1.19.3/examples/udhcp/simple.script usr/share/udhcpc/default.script
find . | cpio -o -H newc | gzip > ~/image.cpio.gz
虛擬機器核心中需要編入至少一種網絡卡驅動:
cd /usr/src/linux
make menuconfig
    Device drivers
        --> Network device support
            --> Ethernet (1000Mbit)
                --> Intel(R) PRO/1000 Gigabit Ethernet support (Intel 82540EM,Qemu預設網絡卡)
    Device drivers
        --> Network device support
            --> Ethernet (10 or 100Mbit)
                --> AMD PCnet32 PCI support (PCNet32)
make
make modules_install
qemu -kernel arch/x86/boot/bzImage -initrd ~/image.cpio.gz -net nic -net tap,ifname=tap0 -vnc :1
在虛擬機器中輸入:
ifconfig eth0 0.0.0.0 up
udhcpc -i eth0

五、在虛擬機器中掛載NFS

首先安裝並設定宿主機中的NFS伺服器

yum install nfs-utils
emacs /etc/exports
    /    192.168.0.0/24(rw,no_root_squash)
/etc/init.d/nfs start
chkconfig nfs on
需要編譯虛擬機器核心中對NFS客戶端的支援:
cd /usr/src/linux
make menuconfig
    File systems
        --> Network File systems
            --> NFS client support
make 
make modules_install
qemu -kernel arch/x86/boot/bzImage -initrd ~/image.cpio.gz -net nic -net tap,ifname=tap0 -vnc :1
在虛擬機器中輸入:
ifconfig eth0 0.0.0.0 up
udhcpc -i eth0
mount -t nfs -o nolock 192.168.0.24:/ /mnt
mount -t proc proc /mnt/proc
mount -t sysfs sysfs /mnt/sys
mount -v -o bind /mnt/dev dev
chroot /mnt /bin/bash --login


參考文獻
1. 
I Need to Build a Custom Kernel
2. 精通initramfs構建step by step
3. 安裝qemu虛擬機器

搭建Embedded Linux kernel環境--在QEMU上執行ARM linux系統


本文的目的:

搭建Embedded Linux kernel學習的環境,在PC(Linux) 的QEMU虛擬機器上執行Linux系統,以便之後的進一步除錯。 .

本文闡述的內容:

在Linux主機上執行QEMU虛擬機器,模擬ARM versatile平臺,並在該平臺上啟動Linux系統的步驟


本文大綱:

1. 安裝Toolchain
2. 安裝QEMU
3. Build Linux kernel
4. 準備root filesystem
5. 啟動QEMU



1. 安裝Toolchain

1). 開啟以下頁面:
http://www.mentor.com/embedded-software/sourcery-tools/sourcery-codebench/editions/lite-edition/

2). 在Supported processors中選擇ARM processors->Download the GNU/Linux Release

3). 填寫Name, Email, Country的資訊,click 'Get Lite'. 下載地址會發到Email郵箱中

4). 在Email中click下載地址,開啟下載頁面後click "Download Sourcery CodeBench Lite 2011.09-70"

5). 在列出的Packages中選擇Recommended Packages中IA32 GNU/LINUX Installer, 此時將下載arm-2011.09-70-arm-none-linux-gnueabi.bin,該檔案可直接執行圖形介面安裝。(也可選擇Advanced Packages中的TAR包自行安裝,但執行圖形介面安裝非常方便,不需要考慮太多設定)

6). 在shell中執行
$./arm-2011.09-70-arm-none-linux-gnueabi.bin
開始圖形安裝介面,按提示安裝。

7). 安裝完畢後,在shell中確認arm-none-linux-gnueabi-的命令是否已有效。
(如果在安裝中選擇將CodeSourcery安裝到user的home目錄下的話,path將被自動新增到user的bash profile中,可重新執行bash profile來enable codesourcery的path. [centos: source ~/.bash_profile, ubuntu: source ~/.profile]

2. 安裝QEMU

1). 開啟http://wiki.qemu.org/Download,下載qemu-1.0.1.tar.gz

2). 解壓縮tar包,編譯qemu-system-arm:
$tar zxvf qemu-1.0.1.tar.gz
$cd qemu-1.0.1
$./configure --target-list=arm-softmmu --prefix=/usr/local/  (必須指定target-list,否則會編譯所有arch型別的binary)
$make;make install

3). 在shell中確認qemu-system-arm命令已有效


3. Build Linux kernel


1). 從kernel.org下載kernel原始碼
方法1:直接得到tar包:
$wget www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.33.7.tar.gz
$tar zxvf linux-2.6.33.7.tar.gz
方法2:用git:
$git clone http://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
$git checkout -B v2.6.33.7 v2.6.33.7  #<---將建立v2.6.33.7的Branch

2). 配置,編譯kernel
進入kernel的目錄
$make mrproper  #清除所有配置和編譯產生的檔案
$make ARCH=arm versatile_defconfig  #使用versatile的default configuration
$make ARCH=arm menuconfig #做微小改動
在Kernel Feature中選中 "Use the ARM EABI to compile the kernel"選項。儲存退出。
$make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- #開始編譯

編譯完成後,在arch/arm/boot/下會生成zImage

4. 準備root filesystem
(部分內容來自opencsl.openfoundry.org)

1). 下載busybox
$wget http://www.busybox.net/downloads/
$bunzip2 busybox-1.19.4.tar.bz2

2).配置編譯busybox
進入busybox-1.19.4
$make mrproper  #清除所有配置和編譯產生的檔案
$make ARCH=arm defconfig #使用default configuration
$make ARCH=arm menuconfig #做微小改動
選中Busybox Settings->Build Options->Build BusyBox as a static binary (no shared libs),儲存退出。
$make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- #開始編譯
$make ARCH=arm install #編譯生成的目標可執行檔案等將被安裝在_install/目錄下。

3). 建立root file system

進入上述busybox make install後的_install/目錄

建立root file system必要的目錄:
$mkdir etc etc/init.d dev root tmp

在dev/下建立裝置開機必須的裝置node:
$cd dev
$sudo mknod console c 5 1
$sudo mknod null c 1 3
$sudo mknod ttyAMA0 c 204 64

指定開機要執行的init程式,busybox已包含此功能,只要建立一個指向busybox的init軟link即可:
¥ln -s bin/busybox init

建立開機要執行的script:

$vi etc/inittab,內容以下:

*******************************************************
::sysinit:/etc/init.d/rcS

::respawn:/sbin/getty -L ttyAMA0 115200 xterm
*******************************************************

$vi etc/init.d/rcS,內容以下:

*******************************************************
#! /bin/sh

mkdir -p /proc
mount -t proc proc /proc
mkdir -p /sys
mount -t sysfs sysfs /sys
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
hostname LINUX-EXPLORER
*******************************************************

建立登入帳號的檔案:

$vi etc/passwd,內容如下:

*******************************************************
root::0:0:root:/root:/bin/sh
*******************************************************

$vi etc/group,內容如下:

*******************************************************
root:x:0:
*******************************************************

到此一個簡單的root file system就在_install/下建立好了。因為每次make install busybox時都會更新_install目錄下的檔案,為了便於管理,我們將製作好的root file system複製到另外的地方。

$mkdir /path/of/rootfs (e.g. ~/rootfs/)
$cp -a /.../busybox-1.19.4/_install/* /path/of/rootfs

4). 使用nfs訪問root file system
因為系統啟動時將通過nfs訪問檔案系統,所以必須使剛剛建立的root file system可以被nfs mount.

安裝nfs server:
每個Linux系統略有不同,這裡不詳述。

將/path/of/rootfs新增到/etc/exportfs中:

$sudo vi /etc/exportfs
新增一行:
/path/of/rootfs  *(rw,sync,no_root_squash,insecure)
儲存退出。

更新nfs export的目錄:
$sudo exportfs -r

確認剛才export的目錄能夠被nfs mount:
$sudo mount localhost:/path/of/rootfs /mnt

5. 啟動QEMU

以上在qemu中啟動Linux的準備工作都做好了,下面試著啟動:

在kernel目錄下啟動:

$qemu-system-arm -nographic -cpu arm926 -M versatilepb -kernel arch/arm/boot/zImage -append "console=ttyAMA0 rw ip=on root=/dev/nfs nfsroot=localhost:/path/to/rootfs"

-append後面""中是kernel的啟動引數,詳細解釋請看kernel src目錄下Documentation/kernel-parameters.txt