目錄
- 0.課程大綱
- 1.為什么要使用QEMU學習嵌入式
- QEMU簡介
- 使用QEMU可以做哪些事情?
- 當前嵌入式行業現狀
- 如何適應這種變化
- 使用QEMU學習嵌入式有哪些好處?
- 驅動開發技能
- 為什么要學習Linux
- 2.搭建嵌入式開發基本環境
- 2.1.安裝u-boot-tools
- 2.2.安裝交叉編譯工具
- 什么是ABI和EABI
- 3.QEMU安裝及仿真開發板介紹
- 自動安裝
- 手動編譯安裝
- QEMU使用
- ARM express 開發板簡介
- Vexpress系列開發板
- Vexpress系列支持的CPU
- 嵌入式最小系統
- QEMU運行系統
- 4.編譯Linux內核和dtb文件
- 4.1.下載Linux內核
- 4.2.修改Makefile
- 4.3.編譯內核,模塊,dtb文件
- 5.使用Busybox制作根文件系統
- 5.1.什么是根文件系統?
- 5.1.1.文件系統
- 5.1.2.為什么要使用文件系統
- 5.1.3.根文件系統
- 5.2.使用busybox制作根文件系統
- 5.2.1.什么是busybox
- 5.2.2.編譯安裝
- 5.2.3.制作根文件系統
- 5.2.4.制作SD卡文件系統鏡像
- 6.使用u-boot引導啟動Linux內核
- 6.1.嵌入式啟動概述
- 6.1.1.嵌入式bootloader
- 6.1.2.常見的啟動方式
- 6.2.u-boot編譯
- 6.3.QEMU網絡功能設置
- 6.3.1.配置QEMU與主機的網絡連接
- 6.3.2.配置
- 6.4.內核配置編譯
- 6.4.1.使用u-boot引導內核鏡像
- 6.5.主機TFTP工具安裝
- 6.6.啟動測試
- 6.7.自動化引導
- 參考資料
0.課程大綱
- 為什么要使用QEMU學習嵌入式
- 搭建嵌入式開發基本環境
- QEMU安裝及A9開發板配置介紹
- 編譯,運行Linux內核
- 使用Busybox制作根文件系統
- 使用u-boot引導啟動Linux內核
- 掛載NFS文件系統
- 在虛擬開發板上開發應用程序,驅動
1.為什么要使用QEMU學習嵌入式
QEMU簡介
- QEMU是一個模擬器,可以模擬CPU,ARM,X86,MIPS等架構
- 可以仿真的ARM處理器:ARM926E,ARM1136,Cortex-A8/A9
- 模擬真實的開發板,外設:串口,LCD,網卡,USB,SD卡…
使用QEMU可以做哪些事情?
- 研究內核虛擬化
- 模擬CPU,對于芯片公司,流片之前在QEMU上做驗證,仿真,軟硬件協同設計,開發BSP和驅動
- 模擬開發板,在模擬平臺上進行系統軟件開發,驅動開發
- 學生,工程師可以利用qemu-system-arm學習嵌入式開發,研究Bootloader,Linux內核,驅動開發,應用開發等.
當前嵌入式行業現狀
- CPU廠家越來越多,各種開發板層出不窮
- 物聯網芯片,AI芯片…
- SOC越來越集成化,軟硬件分工越來越明顯
如何適應這種變化
- 分工
- 精專
- 嵌入式80%的知識系統和技能,都可以脫離"開發板",在QEMU仿真平臺上學習和練習
使用QEMU學習嵌入式有哪些好處?
- 節省學習成本
- 跳過開發板,硬件的各種"坑",縮短學習曲線
- 重構嵌入式知識體系和技能,跟硬件無關的放到QEMU上學習
- 跟開發板相關的驅動,BSP針對具體開發板深入突破
- 適應不同CPU,開發板的技術要求
驅動開發技能
- 基本的硬件知識
- Linux內核,系統架構的理解
- 芯片手冊,開發板
為什么要學習Linux
-
開源,免費
-
持續更新,強大的BSP支持
-
Android,YunOS,Tizen,ubuntu等操作系統的內核
-
應用領域廣:嵌入式,服務器,桌面PC,云…
-
示例
2.搭建嵌入式開發基本環境
2.1.安裝u-boot-tools
- 用來生成適應U-boot引導的鏡像文件格式
sudo apt install -y u-boot-tools
2.2.安裝交叉編譯工具
什么是ABI和EABI
- ABI:二進制應用程序接口(Application Binary Interface(ABI) for the ARM Architecture),在計算機中,應用二進制接口描述了應用程序(或者其他類型)和操作系統之間或其他應用程序的低級接口,涵蓋了數據類型的大小,布局和對齊,調用約定.
- EABI:嵌入式ABI 嵌入式應用二進制接口指定了文件格式,數據類型,寄存器使用,堆積組織優化和在一個嵌入式軟件中的參數的標準約定.
- Arm-none-gnueabi-linux比arm-linux-gcc要好,在可一致性,兼容性上面
- 早期u-boot和Linux編譯可能使用的都不是一個arm-linux-gcc版本
sudo apt install -y gcc-arm-linux-gnueabi
sudo apt install -y g++-arm-linux-gnueabi
#區別
gcc-arm-linux-gnueabi
gcc-arm-linux-gnueabihf
gcc-arm-none-eabi
arm-linux-gnueabi-gcc -v
arm-linux-gnueabi-gcc -o hello main.c
readelf -h hello
3.QEMU安裝及仿真開發板介紹
自動安裝
# For full system emulation
sudo apt install qemu-system#For emulating Linux binaries
sudo apt install qemu-user-static
手動編譯安裝
https://www.qemu.org/
https://wiki.qemu.org/Hosts/Linuxgit clone https://gitlab.com/qemu-project/qemu.git
git checkout remotes/origin/stable-8.2 -b stable-8.2sudo apt-get install git libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev ninja-buildsudo apt-get install git-email
sudo apt-get install libaio-dev libbluetooth-dev libcapstone-dev libbrlapi-dev libbz2-dev
sudo apt-get install libcap-ng-dev libcurl4-gnutls-dev libgtk-3-dev
sudo apt-get install libibverbs-dev libjpeg8-dev libncurses5-dev libnuma-dev
sudo apt-get install librbd-dev librdmacm-dev
sudo apt-get install libsasl2-dev libsdl2-dev libseccomp-dev libsnappy-dev libssh-dev
sudo apt-get install libvde-dev libvdeplug-dev libvte-2.91-dev libxen-dev liblzo2-dev
sudo apt-get install valgrind xfslibs-dev sudo apt-get install libnfs-dev libiscsi-dev./configure --target-list=arm-softmmu --audio-drv-list=
make
sudo make install
QEMU使用
qemu-system-arm --version#查看支持的開發板
qemu-system-arm -M help
#vexpress-a9
ARM express 開發板簡介
Vexpress系列開發板
- 全稱versatile express family, ARM公司自己推出的開發板
- 主要用于SOC廠商設計,驗證和測試自己的SOC芯片
- 采用主板+子板設計,主板提供各種外圍接口,子板提供CPU運算
Vexpress系列支持的CPU
- Cortex-A9: 處理器子板 Express A9x4 (V2P-CA9x4)
- Cortex-A5: 處理器子板 Express A5x2 (V2P-CA5x2s)
- Cortex-R5:
- Cortex-A15: 處理器子板 Express A15x2 (V2P-CA15x2)
DDR
外圍
DUI0448I_v2p_ca9_trm.pdf
嵌入式最小系統
CPU+DDR/SDRAM
FLASH/SD
串口+LCD
QEMU運行系統
#-M vexpress-a : 指定具體開發板
#-m 512M : 指定內存大小
#-kernel ./zImage : 指定內核
#-dtb ./vexpress-v2p-ca9.dtb : 指定設備樹
#-nographic : 不使用圖像界面
#-append "console=ttyAMA0" : 指定串口控制臺
qemu-system-arm -M vexpress-a9 -m 512M -kernel ./zImage -dtb ./vexpress-v2p-ca9.dtb -nographic -append "console=ttyAMA0"
4.編譯Linux內核和dtb文件
4.1.下載Linux內核
https://www.kernel.org/
longterm
4.2.修改Makefile
vim Makefile
ARCH ?= arm
CROSS_COMPILE ?=arm-linux-gnueabi-
4.3.編譯內核,模塊,dtb文件
make vexpress_defconfig
make zImage
make modules
make dtbs
5.使用Busybox制作根文件系統
5.1.什么是根文件系統?
5.1.1.文件系統
對存儲設備上的數據進行組織的機制
5.1.2.為什么要使用文件系統
- Linux的哲學: 一切皆文件
- 用戶與操作系統進行交互的主要工具: 文件系統調用
- 用戶和底層存儲的接口
5.1.3.根文件系統
- Linux內核啟動后第一個掛載的文件系統
- 主要由基本的shell命令,各種庫,字符設備,配置腳本組成
- 提供了根目錄/
- RFS可以放在: nor/nand flash, SD卡, 磁盤, 網絡空間上
5.2.使用busybox制作根文件系統
5.2.1.什么是busybox
- 一個集成100多個Linux常用命令和工具的軟件
- 一個適合制作嵌入式文件系統的軟件工具
5.2.2.編譯安裝
#1.下載源代碼
https://busybox.net/
#2.修改Makefile
ARCH ?= arm
CROSS_COMPILE ?=arm-linux-gnueabi-
#3.配置
make defconfig
make menuconfigSettings ---> [*] Build static binary (no shared libs)
#4.編譯
make -j2
#5.安裝
make install
#安裝生成目錄"_install"
5.2.3.制作根文件系統
mkdir rootfs
cd rootfs/
mkdir lib
cp -avf busybox-1.36.1/_install/* rootfs/
cp -avf /usr/arm-linux-gnueabi/lib/* rootfs/lib/
mkdir dev
cd dev/#mknod: 創建塊或字符設備節點
#-m 666: 權限讀寫
#tty1: 節點名稱
#c: 字符設備
#4: 主設備號
#1: 次設備號
sudo mknod -m 666 tty1 c 4 1
sudo mknod -m 666 tty2 c 4 2
sudo mknod -m 666 tty3 c 4 3
sudo mknod -m 666 tty4 c 4 4sudo mknod -m 666 console c 5 1sudo mknod -m 666 null c 1 3
5.2.4.制作SD卡文件系統鏡像
#1.生成鏡像
#bs: 緩沖區塊的大小
#count: 塊的個數
dd if=/dev/zero of=rootfs.ext3 bs=1M count=32
#2.格式化為ext3文件系統
mkfs.ext3 rootfs.ext3
#3.將各種文件copy到文件系統鏡像中
sudo mount -t ext3 rootfs.ext3 /mnt -o loop
sudo cp -avf rootfs/* /mnt
sudo umount /mnt
6.使用u-boot引導啟動Linux內核
6.1.嵌入式啟動概述
6.1.1.嵌入式bootloader
- 功能類似于PC的BIOS,硬件檢測是否正常
- 加載操作系統鏡像到RAM
- 設置不同的啟動方式
6.1.2.常見的啟動方式
- NOR/NAND FLASH啟動
- 從SD卡啟動
- Bootloader從網絡加載Linux內核啟動
6.2.u-boot編譯
#1.下載u-boot
git clone https://gitee.com/naonano/u-boot.git
git checkout --track origin/u-boot-2023.07.y#2.修改 Makefile
ifeq ($(HOSTARCH),$(ARCH))
CROSS_COMPILE ?=
endif
CROSS_COMPILE ?=arm-linux-gnueabi-#3.修改 config.mk
#ARCH := $(CONFIG_SYS_ARCH:"%"=%)
ARCH := arm#4.配置
make vexpress_ca9x4_defconfig#5.編譯
make -j2#6.運行u-boot
qemu-system-arm -M vexpress-a9 -m 512M -nographic -kernel ../test/u-boot/u-boot
6.3.QEMU網絡功能設置
6.3.1.配置QEMU與主機的網絡連接
- 采用橋接(bridge)的網絡連接與Host通信
- 需要主機內核tun/tap模塊支持
6.3.2.配置
參考:ubuntu 22.04 設置網橋 - netplan
#1.主機安裝工具包
sudo apt install -y uml-utilities bridge-utils
#2.創建tun設備文件
ls -al /dev/net/tun
#3.編輯文件
sudo touch /etc/netplan/br0.yaml
#使用ipv4 dhcp
ipv4 dhcp:
network:version: 2ethernets:enp0s8: #替換為實際網卡dhcp4: falsedhcp6: falsebridges:br0:interfaces: [enp0s8] #替換為實際網卡dhcp4: trueparameters:stp: falsedhcp6: false
ipv4 靜態分配:
network:version: 2ethernets:enp0s8:#替換為實際網卡dhcp4: falsedhcp6: falsebridges:br0:interfaces: [enp0s8] #替換為實際網卡dhcp4: falseaddresses: [192.168.1.250/24]routes:- to: defaultvia: 192.168.1.1nameservers:addresses: [114.114.114.114]parameters:stp: falsedhcp6: true
sudo netplan apply
ifconfig
br0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500inet 192.168.1.25 netmask 255.255.255.0 broadcast 192.168.1.255inet6 fe80::3027:2dff:fe41:8595 prefixlen 64 scopeid 0x20<link>ether 32:27:2d:41:85:95 txqueuelen 1000 (Ethernet)RX packets 55 bytes 9272 (9.2 KB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 89 bytes 12062 (12.0 KB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0enp0s8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 192.168.1.3 netmask 255.255.255.0 broadcast 192.168.1.255inet6 fe80::c8ff:ec6f:253e:ad4e prefixlen 64 scopeid 0x20<link>inet6 2409:8a1e:d52:a9b0:39df:8d80:83d3:9e prefixlen 64 scopeid 0x0<global>inet6 2409:8a1e:d52:a9b0:3292:9a45:5481:28ad prefixlen 64 scopeid 0x0<global>ether 08:00:27:05:ef:4f txqueuelen 1000 (Ethernet)RX packets 962 bytes 156528 (156.5 KB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 836 bytes 88212 (88.2 KB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536inet 127.0.0.1 netmask 255.0.0.0inet6 ::1 prefixlen 128 scopeid 0x10<host>loop txqueuelen 1000 (Local Loopback)RX packets 318 bytes 29095 (29.0 KB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 318 bytes 29095 (29.0 KB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
6.4.內核配置編譯
6.4.1.使用u-boot引導內核鏡像
#需要將內核編譯為uImage格式
#需要指定uImage的加載地址
#編譯時指定:
make LOADADDR=0x60003000 uImage -j2
6.5.主機TFTP工具安裝
#1.安裝
sudo apt-get install -y tftpd-hpa tftp-hpa xinetd
#2.配置ftp服務器工作目錄為"/home/tftp"
sudo vim /etc/default/tftpd-hpaTFTP_USERNAME="tftp"TFTP_DIRECTORY="/home/tftp"TFTP_ADDRESS=":69"TFTP_OPTIONS="-l -c -s"
#3.建立目錄
sudo mkdir -p /home/tftp
sudo chown lei:lei /home/tftp
chmod 777 -R /home/tftp
#4.啟動服務
sudo service tftpd-hpa restart
#5.測試
#5.1測試下載
cd /home/tftp/
touch readme.txt
#在readme.txt中輸入一些內容
#運行開發板,進入控制臺
tftp -g -r readme.txt 192.168.10.107
#可以看出在開發板當前目錄下下載了readme.txt
#5.2測試上傳
#在開發板上,進入控制臺運行命令
tftp -p -l uvc_app 192.168.10.107
#uvc_app為開發板當前目錄下的文件
#在ubuntu上可以看到開發板上傳上來的文件uvc_app
6.6.啟動測試
#1.復制u-boot鏡像到tftp服務器目錄下
cp /home/qemu/test/u-boot/u-boot /home/tftp/
#2.復制uImage鏡像到tftp服務器目錄下
cp /home/qemu/test/linux-6.6.18/arch/arm/boot/uImage /home/tftp/
#3.復制設備樹二進制編譯結果到tftp服務器目錄下
cp /home/qemu/test/linux-6.6.18/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dtb /home/tftp/
#4.uboot引導kernel啟動
qemu-system-arm \-M vexpress-a9 \-m 512M \-nographic \-kernel /home/tftp/u-boot \-net nic,vlan=0 -net tap,vlan=0,ifname=tap0 \-sd /home/qemu/test/rootfs.ext3
6.7.自動化引導
u-boot/include/configs/vexpress_common.h
#define CONFIG_BOOTCOMMAND \"tftp 0x60003000 uImage; tftp 0x60500000 vexpress-v2p-ca9.dtb; \setenv bootargs 'root=/dev/mmcblk0 console=ttyAMA0'; \bootm 0x60003000 - 0x60500000; "#define CONFIG_IPADDR 192.168.244.128
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_SERVERIP 192.168.244.129
參考資料
B站
QEMU系列文章: https://blog.csdn.net/phmatthaus/category_12072874.html