使用QEMU搭建U-Boot+LinuxKernel+busybox+NFS嵌入式开发环境
目录
- 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/Linux git clone https://gitlab.com/qemu-project/qemu.git git checkout remotes/origin/stable-8.2 -b stable-8.2 sudo apt-get install git libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev ninja-build sudo 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 menuconfig Settings ---> [*] 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 4 sudo mknod -m 666 console c 5 1 sudo 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: 2 ethernets: enp0s8: #替换为实际网卡 dhcp4: false dhcp6: false bridges: br0: interfaces: [enp0s8] #替换为实际网卡 dhcp4: true parameters: stp: false dhcp6: false
ipv4 静态分配:
network: version: 2 ethernets: enp0s8:#替换为实际网卡 dhcp4: false dhcp6: false bridges: br0: interfaces: [enp0s8] #替换为实际网卡 dhcp4: false addresses: [192.168.1.250/24] routes: - to: default via: 192.168.1.1 nameservers: addresses: [114.114.114.114] parameters: stp: false dhcp6: true
sudo netplan apply
ifconfig
br0: flags=4099 mtu 1500 inet 192.168.1.25 netmask 255.255.255.0 broadcast 192.168.1.255 inet6 fe80::3027:2dff:fe41:8595 prefixlen 64 scopeid 0x20 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 0 TX packets 89 bytes 12062 (12.0 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 enp0s8: flags=4163 mtu 1500 inet 192.168.1.3 netmask 255.255.255.0 broadcast 192.168.1.255 inet6 fe80::c8ff:ec6f:253e:ad4e prefixlen 64 scopeid 0x20 inet6 2409:8a1e:d52:a9b0:39df:8d80:83d3:9e prefixlen 64 scopeid 0x0 inet6 2409:8a1e:d52:a9b0:3292:9a45:5481:28ad prefixlen 64 scopeid 0x0 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 0 TX packets 836 bytes 88212 (88.2 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73 mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10 loop txqueuelen 1000 (Local Loopback) RX packets 318 bytes 29095 (29.0 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX 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-hpa TFTP_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
- 用来生成适应U-boot引导的镜像文件格式
-
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。