【工程技術】QEMU運行Linux Kernel環境配置

目錄

 

爲什麼選擇QEMU

資源下載

環境配置

QEMU運行Linux

解決SSH遠程登錄Linux Server沒有GUI界面的問題


爲什麼選擇QEMU

QEMU Architecture

    QEMU(Quick Emulator)是個模擬器(官網鏈接:https://www.qemu.org),它能夠動態模擬特定架構的CPU指令,如X86,ARM,RSIC等。
    如上圖所示,QEMU模擬系統架構稱爲TARGET,運行 QEMU的系統架稱爲HOST,QEMU的核心模塊是微型代碼生成器(TCG),它用來將TARGET系統上的代碼動態翻譯成HOST系統的代碼,QEMU的工作原理就是不斷提取TARGET代碼並且翻譯成HOST代碼。整個翻譯分爲兩個部分:第一個部分是將做TARGET代碼(TB)轉化成TCG中間代碼,然後再將中間代碼轉化成HOST代碼。

    Linux Kerenl 涉及到具體硬件driver適配,選擇QEMU將Linux 模擬爲TARGET上的GUEST OS系統,運行在HOST的開發機(通常是X86 window/MacOS/Ubuntu OS)上,可以避免做硬件driver適配的時間與人力投入,大大提升學習kernel的效率。

 

資源下載

Linux Kernel

 

QEMU

 

Busybox

 

環境配置

Linux Kernel

  • HOST OS開發環境:  Linux version 4.10.0-28-generic (gcc version 5.4.0 20160609 (ubuntu~16.04.4) ) #32~16.04.2
  • 下載Linux Kernel linux-3.16.84 https://cdn.kernel.org/pub/linux/kernel/v3.x/linux-3.16.84.tar.xz (選擇老版本避免太多的編譯依賴問題)
  • cd linux-3.16.84
  • make menuconfig (默認配置exit 生成.config)
  • make -j24
  • 編譯成功後可以在arch目錄下看到壓縮後的Linux Kernel Image: bzImage

 

QEMU編譯

  • Host OS開發環境:同上
  • 下載QEMU 最新master代碼:git clone https://github.com/qemu/qemu.git
  • 編譯
    • cd qemu
    • make build
    • cd build
    • ../configure
      • 注意:一定要確認configure的結果中"SDL support“ 爲yes,否則QEMU運行無法正常顯示Linux終端窗口(參考”SSH遠程登錄Linux Server沒有GUI界面的問題“章節)

  • make -j24
  • 編譯成功後生成QEMU執行程序:qemu/build/x86_64-softmmu/qemu-system-x86_64

 

Busybox編譯與rootfs

  • Host OS開發環境:同上
  • 下載Busybox 代碼:https://busybox.net/downloads/busybox-1.30.0.tar.bz2  (下載哪個版本取決與開發環境的編譯依賴)
  • 編譯Busybox
    • cd busybox-1.30.0
    • make menuconfig (記得打開靜態編譯busybox選項,否則後續busybox作爲QEMU虛擬機中的linux的init進程啓動會由於找不到鏈接庫出現kernel panic)

  • make -j24
  • 編譯成功後可以在當前目錄下看到生成了busybox
  • make install 生成_install目錄以及必須的rootfs 目錄結構
  • 創建rootfs
    • cd busybox-1.30.0/_install
    • mkdir proc sys dev etc etc/init.d (創建Linux系統運行時的必須目錄,/proc用於掛載proc系統,/sys用於掛載sys系統,dev用於mdev創建設備節點,etc/init.d爲放置busybox啓動腳本的目錄)
       

 

  • vim etc/init.d/rcS
  • chmod +x etc/init.d/rcS (確保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

Linux第一個啓動的進程是init(通過busybox生成的rootfs中sbin/init其實是指向busybox的連接,所以第一個啓動的就是busybox),通過該腳本指定init使用的啓動腳本爲/etc/init.d/rcS,該路徑被聲明在 busybox-1.30.0/init/init.c當中

  • 創建rootfs鏡像img
  • find . | cpio -o --format=newc > rootfs.img

  • gzip -c rootfs.img > rootfs.img.gz

QEMU運行Linux

  • cd qemu/build/x86_64-softmmu/
  • ./qemu-system-x86_64 -kernel <path to linux kernel image>/bzImage -initrd <path to rootfs img>/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
  • 如果HOST 系統是通過ssh 遠程登錄的,那麼大概率會遇到QEMU卡死在下面的提示信息,看不到Linux啓動的終端GUI界面

VNC server running on 127.0.0.1:5900

 

解決SSH遠程登錄Linux Server沒有GUI界面的問題

SSH 登錄後沒有X11 Server支持示意

    如上圖所示,完整的Linux Host OS中有完整的X11 Window System顯示系統,作爲X11 Client的應用程序(比如 QEMU)可以正常連接到X11 Server 顯示它的終端GUI 窗口,但是SSH 遠程登錄某個Linux Host OS後是沒有X11 Server支持的,所以會出現QEMU無法顯示終端GUI界面的問題

將SSH遠程登錄的Host OS上對X11的調用Forward到支持X11 顯示系統的本地OS

如上圖所示,通過將SSH遠程登錄的Host OS上對X11的調用Forward到支持X11 顯示系統的本地OS,就可以解決該問題

以遠程Host OS爲ubuntu,本地OS爲MacOS爲例,做如下配置:

  • Server = ”SSH遠程登錄Host OS爲ubuntu系統“
  • Client = ”本地OS爲MacOS“
  • Client與Server端修改/etc/ssh/ssh_config
    • X11Forwarding    yes
    • ForwardAgent    yes
  • Client
    • xhost +  # 允許任何機器連接
    • ssh -X 用戶名@ip -p 22 # 連接遠程服務器
  • Server
    • export $(cat /proc/1/environ |tr '\0' '\n' | xargs)  (如果是docker容器需要設置和主進程相同的環境變量)
    • 運行xclock 測試程序確認看到GUI界面證明X11的forward已經成功

如下圖所示,再次運行./qemu-system-x86_64 -kernel <path to linux kernel image>/bzImage -initrd <path to rootfs img>/rootfs.img.gz -append "root=/dev/ram rdinit=sbin/init noapic" 可以看到QEMU的GUI正常顯示,如果Linux 啓動一切順利就可以進入到busybox的shell環境,通過在/目錄執行ls -l 命令可以看到rootfs就是我們在<host os>/busybox-1.30.0/_install 目錄中手工創建的rootfs目錄結構

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章