一、安裝qemu
1、依賴安裝
輸入uname -a查看當前系統,根據系統運行依賴安裝腳本即可從Linux上安裝qemu。
Debian/Ubuntu apt-get install qemu
RHEL/CentOS yum install qemu-kvm
2、編譯安裝
wget https://download.qemu.org/qemu-3.1.1.tar.xz
tar xvJf qemu-3.1.1.tar.xz
cd qemu-3.1.1
./configure
make
make install
通過命令$ qemu-system-arm -M ? 可以獲得qemu所支持的armv7設備
通過命令$ qemu-system-aarch64 -M ? 可以獲得qemu所支持的armv8設備
二、下載樹莓派鏡像
這里首先需要明確交叉編譯的程序是基於armV7 還是armV8 ,然后下載對應版本的鏡像 https://www.raspberrypi.org/downloads/
0、查看鏡像的分區
$ file 2018-06-27-raspbian-stretch.img
output:
2018-06-27-raspbian-stretch.img: DOS/MBR boot sector; partition 1 : ID=0xc, start-CHS (0x0,130,3), end-CHS (0x6,4,22), startsector 8192, 88472 sectors; partition 2 : ID=0x83, start-CHS (0x6,30,25), end-CHS (0x24a,106,32), startsector 98304, 9322496 sectors
1、從鏡像拷貝出啟動qemu所需的內核文件和設備樹引導文件
從file命令的輸出中,將 partition 1 'startsector'的值乘以512,並使用這個數字作為下面mount命令中的偏移值.(8192x512)
$ sudo mount 2018-06-27-raspbian-stretch.img -o offset=4194304 /mnt
[TODO] #從 /mnt 目錄把鏡像里的文件拷貝出來
$ sudo umount 2018-06-27-raspbian-stretch.img /mnt
其中kernel.img與kernel7.img,kernel8.img就是啟動qemu所需的內核,*.dtd文件是設備樹引導文件,對應樹莓派的cpu及版本,其中kernel.img內核文件對應設備為:
kernel.img 對應 RPi 1B, 1A, A+, B+, 2B(第一版) Z, Z (攝像頭版本), ZW, CM1
kernel7.img 對應 RPi2B2, RPi3B, CM3 and CM3L.
kernel8.img 對應 RPi3B, CM3 and CM3L, RPi4B,
qemu-system-arm 支持Raspberry Pi 2(2B)設備,所以對應該設備我們使用kernel7.img以及對應2B的bcm2709-rpi-2-b.dtb文件。
qemu-system-aarch64 支持Raspberry Pi 3(3B)設備,所以對應該設備我們使用kernel8.img以及對應3B的bcm2710-rpi-3-b.dtb文件。
2、將交叉編譯好的執行程序放入鏡像
從file命令的輸出中,將 partition 2 'startsector'的值乘以512,並使用這個數字作為下面mount命令中的偏移值.(98304x512)
$ sudo mount 2018-06-27-raspbian-stretch.img -o offset=50331648 /mnt
[TODO] #將你交叉編譯好的執行程序放入該目錄下
$ sudo umount 2018-06-27-raspbian-stretch.img /mnt
3、如果鏡像空間不足需要給鏡像擴容
三、運行虛擬機
armV7:
qemu-system-arm -M raspi2 -kernel kernel7.img -sd 2018-06-27-raspbian-stretch.img -append "rw earlyprintk loglevel=8 console=ttyAMA0,115200 dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2 rootwait" -dtb bcm2709-rpi-2-b.dtb -nographic
armV8:
qemu-system-aarch64 -M raspi3 -kernel kernel8.img -sd 2020-08-20-raspios-buster-arm64-lite.img -append "rw earlyprintk loglevel=8 console=ttyAMA0,115200 dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2 rootwait" -dtb bcm2710-rpi-3-b.dtb -nographic
命令參數:
-M raspi2 模擬raspi2單板,你可以使用-M ?參數來獲取該qemu版本支持的所有單板
-m 512M 單板運行物理內存512M
-kernel /path/to/kernel/dir/arch/arm/boot/zImage 告訴qemu單板運行內核鏡像路徑
-nographic 不使用圖形化界面,只使用串口
-append "console=ttyAMA0" 內核啟動參數,這里告訴內核vexpress單板運行,串口設備是哪個tty
如果搭建其它單板,需要注意內核啟動參數的console=參數值,同樣地,可從生成的.config文件中找到
樹莓派默認用戶名密碼:(pi/raspberry)
qemu退出的方式:官方文檔給出的是ctrl + A 和 X,需要注意ctrl 與 A同時按住抬起后再按X,不要三個鍵同時按~
*鏡像擴容
1、查看現有樹莓派鏡像的空間
使用qemu-img的info命令:
qemu-img info 2018-06-27-raspbian-stretch.img
輸出可以看到如下信息:
image: 2018-06-27-raspbian-stretch.img//img鏡像名稱
file format: raw//文件格式類型
virtual size: 4.6G (4919918592 bytes)//實際鏡像文件大小
disk size: 4.6G//系統空間大小
2、對鏡像文件進行擴展
使用qemu-img的resize命令
qemu-img resize 2018-06-27-raspbian-stretch.img +1G
再通過info命令檢查當前鏡像文件:
file format: raw
virtual size: 5.6G (5993660416 bytes)//實際鏡像文件大小已經擴容1G空間
disk size: 4.6G
現在實際鏡像文件已經擴容,但實際文件系統暫時還未識別已擴容的空間,需要對該虛擬分區進行格式化。
通過resize命令不僅可以擴展鏡像大小,也可以對鏡像進行裁剪,但裁剪之前需要對分區進行格式化並釋放空間,否則裁剪時會損壞鏡像。
每個樹莓派鏡像的分區默認有兩個,sda1【boot分區】與sda2【linux分區】,此次擴容只對linux分區進行擴容。
3、啟動鏡像進入linux分區
擴展完畢后,進入鏡像的linux系統中,通過df -h命令查看當前系統文件大小,可以看到當前系統還未識別新擴展的空間,可以看到linux分區幾乎已經用光:
(/dev/sda2 會隨運行命令root=/dev/mmcblk0p2 改變)
Filesystem Size Used Avail Use% Mounted on
/dev/root 4.5G 4.1G 98M 98% /
devtmpfs 124M 0 124M 0% /dev
tmpfs 124M 0 124M 0% /dev/shm
tmpfs 124M 1.9M 122M 2% /run
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 124M 0 124M 0% /sys/fs/cgroup
/dev/sda1 41M 21M 21M 51% /boot
tmpfs 25M 0 25M 0% /run/user/1000
使用fdisk命令查看當前分區的起始位與結束位:sudo fdisk -l
Device Boot Start End Sectors Size Id Type
/dev/sda1 8192 93236 85045 41.5M c W95 FAT32 (LBA)
/dev/sda2 94208 9609215 9515008 4.6G 83 Linux
需要記錄sda2(Linux分區)的start位置的sector。
使用fdisk對sda設備進行分區:sudo fdisk /dev/sda
操作如下:
****************************************************************************************************
* Welcome to fdisk (util-linux 2.29.2).
* Changes will remain in memory only, until you decide to write them.
* Be careful before using the write command.
*
*
* Command (m for help): d #刪除分區指令
* Partition number (1,2, default 2): 2 #2即sda2分區
*
* Partition 2 has been deleted.
*
* Command (m for help): n #創建新分區
* Partition type
* p primary (1 primary, 0 extended, 3 free)
* e extended (container for logical partitions)
* Select (default p): p #創建主分區
* Partition number (2-4, default 2): 2 #創建sda2分區
* First sector (2048-11706367, default 2048): 94208 #輸入sda2分區起始sector
* Last sector, +sectors or +size{K,M,G,T,P} (94208-11706367, default 11706367): 11706367 #默認鏡像最后一個sector
*
* Created a new partition 2 of type 'Linux' and of size 5.6 GiB.
* Partition #2 contains a ext4 signature.
*
* Do you want to remove the signature? [Y]es/[N]o: N #此時已經擴展成功,選擇不刪除分區簽名
*
* Command (m for help): w #保存此次操作
*
* The partition table has been altered.
* Calling ioctl() to re-read partition table.
* Re-reading the partition table failed.: Device or resource busy
*
* The kernel still uses the old table. The new table will be used at the next reboot or after you run partprobe(8) or kpartx(8).
*
********************************************************************************************************
4、重啟檢查系統剩余空間
此時已經完成了對Linux分區的擴展,使用sudo reboot命令重啟qemu。重啟完成后使用resize2fs命令來時我們擴展的空間生效。
sudo resize2fs /dev/sda2
然后通過df -h命令來檢查系統剩余空間:
Filesystem Size Used Avail Use% Mounted on
/dev/root 5.4G 4.1G 1.1G 80% /
devtmpfs 124M 0 124M 0% /dev
tmpfs 124M 0 124M 0% /dev/shm
tmpfs 124M 2.0M 122M 2% /run
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 124M 0 124M 0% /sys/fs/cgroup
/dev/sda1 41M 21M 21M 51% /boot
tmpfs 25M 0 25M 0% /run/user/1000