QEMU 模拟器(一)
安裝
安裝 比較簡單, 有幾種方案.
- 遠程倉庫安裝
- 官網下載可執行文件(Windows 平臺適用)
- 通過源碼自己編譯
可只裝指定平臺, 如 ARM: sudo apt-get install qemu-system-arm
u-boot 仿真
下載 uboot 源碼 這里以版本u-boot-2018.09.tar.bz2 為例
- -M 指定了主板類型, 和上面編譯的 uboot 主板參數一致
- -m 表示主板的 DRAM 大小
- -kernel 后面的可執行文件會被QEMU直接加載到內存并執行, 這里等效于 -device loader,file=u-boot,cpu-num=0
- -nographic 表示不啟動圖形界面
[注]: 先按 Ctrl-A 進入QEMU的功能選擇模式, 然后按 x 退出.
[提示]: Ctrl-A 后按 ? 可查看有哪些功能選項.
Linux kernel 仿真
下載 kernel 源碼, 這里以5.17版本為例
在 kernel 根目錄執行
export ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- # 設置編譯平臺和工具鏈 make vexpress_defconfig # 加載板子的配置信息 make zImage dtbs -j8 # 編譯目標在新版內核中,需要給內核生成對應的 dtb,因此目標 dtbs 是需要的
編譯后在 arch/arm/boot 生成 zImage, 在 arch/arm/boot/dts 生成 vexpress-v2p-ca9.dtb 可將它們拷貝出來使用, 后面將默認它們已經拷貝出來放在同一路徑了
直接加載內核到QEMU
load.sh 文件:
- -dtb 告訴QEMU將文件用作設備樹二進制(DTB)映像,并在引導時將其傳遞給內核。
執行上面腳本后, QEMU將運行Linux內核鏡像, 內核顯示許多引導消息,然后它將報告: not syncing: VFS, 表示沒有找到根文件系統
制作簡單的根文件系統, 并在內核初始化時執行 Hello World 程序
hello.c
編譯 hello 程序
arm-linux-gnueabi-gcc -static hello.c -o hello- -static 表示靜態編譯, 靜態編譯會將所有庫都鏈接在一個二進制文件中
[注] 引入無限循環是因為當Linux執行根文件系統中的第一個程序時,它預計該程序不會退出
制作基于內存的初始根文件系統 (initramfs), 參考
Linux 支持把一段內存用來充當臨時的文件系統, 這樣做是因為在內核啟動完成后很可能硬盤等設備并未初始化完成, 將內存作為臨時根文件系統, 并在該根文件系統下執行用戶程序, 由用戶程序來完成初始化工作并掛載在硬盤上的真正的根文件系統
我們使用cpio工具創建一個簡單的文件系統:
echo hello | cpio -o --format=newc > rootfscpio 工具輸入一個文件列表, 輸出一個文件. 這里指明輸出的文件格式是 newc, 它是 initramfs 文件系統格式,Linux內核可以識別.
load.sh
qemu-system-arm \-M vexpress-a9 \-m 256M \-nographic \-kernel zImage \-dtb vexpress-v2p-ca9.dtb \-initrd rootfs \-append "root=/dev/ram init=/hello console=ttyAMA0"- -initrd QEMU可以使用initrd參數將 initramfs 文件系統二進制映像傳遞給內核;
- -append 用于向內核傳遞參數, 內核還必須知道根文件系統將位于RAM中(因為這是QEMU寫入initrd二進制文件的位置),并且指明第一個啟動的程序是我們的測試可執行文件hello
- console=ttyAMA0 是將輸出定向到串口, 否則需要去掉 -nographic 才能查看
上面的shell 腳本執行后將會看到屏幕上顯示Hello World, 并且內核停留在 while 循環.
initrd vs initramfs
initrd 是 Linux 2.6 版本以前制作內存根文件系統的方法了, 該方法已經過時. 這是因為 initrd (initial ram disk 初始化內存磁盤) 是把內存當做一塊磁盤, 內核需要先創建 ramdev 塊設備, 然后將 initrd 拷貝到塊設備,最后掛載.
同時 initrd 內的文件系統還需要驅動支持, 如果是 ext2 則必須在內核中編譯 ext2 驅動程序. initrd 最大的缺點是占用較大內存,不可伸縮. 參考官方文檔
下面演示如何制作 initrd
新版本 kernel 默認不再支持內存塊設備支持, 需要手動打開:
在內核目錄執行 grep BLK_DEV_RAM .config 查看 BLK_DEV_RAM 是否被編譯進去, 若沒有則需要使用 make menuconfig 進入設置后按 / 查找 BLK_DEV_RAM 并到對應區域打開該功能
重新編譯內核后拷貝出 zImage 執行下面的腳本
qemu-system-arm \-M vexpress-a9 \-m 256M \-nographic \-kernel zImage \-dtb vexpress-v2p-ca9.dtb \-initrd rootfs.img \-append "root=/dev/ram0 init=/hello console=ttyAMA0"新版的 initramfs 直接把內存作為文件系統, 因為內核總是內置 tmpfs 文件系統 (initramfs就是tmpfs的實例), 可以直接掛載不需要設備和額外的文件系統驅動程序.
根文件系統在外部設備
現代的高級的系統引導程序, 往往都直接支持文件系統, 在初始化磁盤后可以識別文件系統, 并將參數傳遞給內核從哪個外部設備掛載根文件系統. 制作外部設備的根文件系統鏡像和制作 initrd 是一樣的, 因為它們其實本質都是包含文件系統的鏡像文件, 因此可以直接使用上一節的 rootfs.img 來使用, 只是它們被放到了真正的磁盤, 而 initrd 則是內存虛擬的磁盤. 例如, 我們把它虛擬成sd卡, 讓 QEMU 的引導程序傳遞給內核
load.sh
總結
以上是生活随笔為你收集整理的QEMU 模拟器(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 魔方 大模拟
- 下一篇: html div背景自动居中显示,网站背