以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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM