以Qemu模擬Linux,學習Linux核心

2021-07-25 02:49:01 字數 3995 閱讀 5455

維護日誌:2013-02-21 建立文件

(注:文章參考自 是對該篇文章的一些補充和說明。文章內所使用的環境是ubuntu 12.04,如果其中遇到編譯問題,請自行參考錯誤說明,配置依賴環境)

0.準備

我們所有的工作都在指定目錄下工作,使用以下變數來代替相關目錄。

$kernel     核心工作目錄

$linux       linux核心原始碼目錄

$busybox  busybox原始碼目錄

$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
$tar -xf qemu-1.3.1.tar.bz2
然後編譯

$./configure

$make

$make install

$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

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

核心啟動引數

root=       使用哪個裝置作為根檔案系統。

rdinit=      核心載入完畢之後,即執行initrd中指定路徑的程式,來建立linux的第乙個程序。

init=         核心載入完畢之後,即執行initramfs中指定路徑的程式,來建立linux的第乙個程序。

noapic      apic,高階可程式設計中斷控制器。這裡用於防止發生mp-bios bug 8254 timer not connected。

參考資料

1.qemu官方**

2.簡單用qemu模擬linux執行環境

3.initrd 核心描述文件

4.initrd和initramfs

在qemu環境中用gdb除錯Linux核心

對使用者態程序,利用gdb除錯 是很方便的手段。而對於核心態的問題,可以利用crash等工具基於coredump檔案進行除錯。其實我們也可以利用一些手段對linux核心 進行gdb除錯,qemu就是一種。qemu是一款完全軟體模擬 binary translation 的虛擬化軟體,在虛擬化的實現中...

qemu模擬A9 A15執行Linux4 2 3

根據修改 主機執行作業系統,deepin2015 1.安裝qemu sudo apt get install qemu system arm 2.安裝arm編譯工具 sudo apt get install gcc arm linux gnueabi 修改makefile,arch arm cros...

linux 檢視核數

總核數 物理cpu個數 x 每顆物理cpu的核數 總邏輯cpu數 物理cpu個數 x 每顆物理cpu的核數 x 超執行緒數 檢視物理cpu個數 cat proc cpuinfo grep physical id sort uniq wc l 或grep physical id proc cpuinf...