ubuntu16.04环境下qemu模拟开发板vexpress-a9

B站课程学习记录,原视频 BV1NJ411m75T
若按此教程学习,不要使用版本差异太大的源码,会有问题,已经踩过坑。
如有错误感谢指正。

文章目录

        • 一、安装交叉编译链
        • 二、安装qemu
        • 三、内核编译
        • 四、busybox制作文件系统
        • 五、uboot启动内核

一、安装交叉编译链
apt install gcc-arm-linux-gnueabi   //arm通用(可选安装g++)
arm-linux-gnueabi-gcc -v     //查看安装版本
二、安装qemu
apt install qemu
qemu-system-arm --version
qemu-system-arm -M help   //查看支持的开发板
三、内核编译
  1. 自行选择下载内核版本,内核官网:www.kernel.org,推荐国内:mirrors.aliyun.com/linux-kernel/
  2. 下载解压后,修改Makefile,查找CROSS_COMPILE,将其改为"arm-linux-gnueabi-“,相邻的ARCH也改为"arm”
  3. 针对特殊的开发板编译内核,linux-4.4.76/arch/arm/configs下存放着当前内核支持的各种开发板配置
make vexpress_defconfig
  1. 开始编译,-j4启用多任务编译,可以加快编译速度(也可以直接"make all",但时间较长,所以分别编译需要的东西)
make zImage -j4   生成./arch/arm/boot/zImage
  1. 编译内核模块(此教程中没有用到,故没有执行安装,可以跳过)
make modules -j4   
  1. 编译dts,dts同一规划不同架构不同开发板等的配置,生成的是.dtb文件
make dtbs     //生成./arch/arm/boot/dts/vexpress-v2p-ca9.dtb,同时生成的其他dtb我们不需要
  1. 启动(停止运行直接kill pid)
//可以看到最后一行显示没有挂载文件系统,就算编译成功了,下面再继续制作文件系统
//-M指定开发板,-m指定内存大小,-kernel指定内核镜像,-dtb指定dtb文件,-nographic不适用图形显示,-append追加命令使用串口控制台
qemu-system-arm -M vexpress-a9 -m 512M -kernel ./zImage -dtb ./vexpress-v2p-ca9.dtb -nographic -append "console=ttyAMA0"

可以整理成脚本boot.sh

qemu-system-arm \
	-M vexpress-a9 \
	-m 512M \
	-kernel ./zImage \
	-dtb ./vexpress-v2p-ca9.dtb \
	-nographic \
	-append "console=ttyAMA0"
四、busybox制作文件系统
  1. 下载busybox源码,网址:busybox.net/downloads/
  2. 下载解压后,先修改Makefile
CROSS_COMPILE ?= arm-linux-gnueabi-
ARCH ?= arm 
  1. make配置文件
make defconfig
make menuconfig   //图形化配置方法,并且设置Busybox Settings-->Build Options中选静态库,可能需要安装apt install libncurses5-dev
  1. 编译安装
make -j4
make install    //生成的文件都在./_install目录下
  1. 制作文件系统根目录(以下命令仅描述步骤,根据实际情况执行)
mkdir rootfs
cd rootfs
mkdir lib
mkdir dev
cp -r busybox-1.27.0/_install/* rootfs/
cp -p /usr/arm-linux-gnueabi/lib/* rootfs/lib/
cd rootfs/dev
mknod -m 666 tty1 c 4 1   //新建串口节点,-m权限,tty1串口,c字符设备,4主设备号(类型),1次设备号(编号)
mknod -m 666 tty2 c 4 2
mknod -m 666 tty3 c 4 3
mknod -m 666 tty4 c 4 4
mknod -m 666 console c 5 1
mknod -m 666 null c 1 3   //null表示什么都没有,可以理解为垃圾站
  1. 制作sd卡文件镜像,sd卡一般都是ext3格式
dd if=/dev/zero of=rootfs.ext3 bs=1M count=32  //dd生成镜像,if输入,of输出,bs缓冲区大小,count块的大小
mkfs.ext3 rootfs.ext3   //格式化该sd卡,存储设备一般都是块设备,所以要挂载后才能读写
mount -t ext3 rootfs.ext3 /mnt -o loop
  1. 将所有的东西拷贝到sd卡
cp -r rootfs/* /mnt/
umount /mnt/  //挂载只是为了进行读写,所以都写完就可以卸载掉
    1. 命令行启动,与之前比添加了追加选项,root指定sd卡节点,rw指定sd卡可读可写,-sd挂载sd卡
qemu-system-arm \
	-M vexpress-a9 \
	-m 512M \
	-kernel ./zImage \
	-dtb ./vexpress-v2p-ca9.dtb \
	-nographic \
	-append "root=/dev/mmcblk0 rw console=ttyAMA0" \
	-sd rootfs.ext3

启动后该系统可以直接进入命令行进行操作;也可以在关闭后重新在rootfs文件夹下修改,然后再挂载复制到挂载目录下达到修改的目的

    1. 图形窗口启动,去掉-nographic选项,并且将console设置为当前终端(tty0代表当前终端),但该种方式并不好用
qemu-system-arm \
	-M vexpress-a9 \
	-m 512M \
	-kernel ./zImage \
	-dtb ./vexpress-v2p-ca9.dtb \
	-append "root=/dev/mmcblk0 rw console=tty0" \
	-sd rootfs.ext3
五、uboot启动内核

一般情况下,机器上电后会有bootloader检测硬件并将操作系统从磁盘上读取到内存进行启动,如个人PC的BIOS,嵌入式设备一般用uboot(开源,且兼容大多数板子)启动内核,常见的有从flash/sd卡/网络启动内核

  1. 下载uboot源码,网址:ftp.denx.de/pub/u-boot/
  2. 修改Makefile,重新定义一个CROSS_COMPILE
CROSS_COMPILE ?= arm-linux-gnueabi-
  1. 修改config.mk,修改ARCH = arm
ARCH := arm
  1. make指定配置文件,若报错可尝试apt-get install bison flex
make vexpress_ca9x4_defconfig
vim u-boot-2017.05/include/configs/vexpress-common.h
	//在这个打开的头文件中找到CONFIG_BOOTCOMMAND,屏蔽原来的定义,重新定义
	#define CONFIG_BOOTCOMMAND "tftp 0x60003000 uImage;\
		tftp 0x60500000 vexpres s-v2p-ca9.dtb;\
		setenv bootargs 'root=/dev/mmcblk0 console=ttyA MA0';\
		bootm 0x60003000 - 0x60500000;"
	#define CONFIG_IPADDR 192.168.31.153 //与CONFIG_SERVERIP 在同一网段就行
	#define CONFIG_NETMASK 255.255.255.0
	#define CONFIG_SERVERIP 192.168.31.152  //qemu所在主机的ip
  1. 编译
make -j4
  1. 检测编译是否成功,能运行就成
qemu-system-arm -M vexpress-a9 -m 512M -nographic -kernel u-boot
  1. qemu网络配置,目的是让qemu模拟的开发板跟主机互通网络
apt install uml-utilities bridge-utils   //必要插件
ls /dev/net/    //查看该目录有无tun,有才支持,无。。。
vim /etc/network/interfaces //添加以下内容,大致意思是桥接两个网卡,配置成功后要重启
   auto ens33 ##本机网卡名,根据实际情况变更
   auto br0
   iface br0 inet dhcp
    bridge_ports ens33
  1. 编译uImage格式内核,之前编译的zImage不能给uboot用(并非一定要用uboot启动,我们的目的是qemu模拟开发板运行,之前能运行起来进入命令行就够用了,但多学一些总是好的)
cd linux-4.4.76/
make LOADADDR=0x60003000 uImage -j4   //编译完成后生成linux-4.4.76/arch/arm/boot/uImage
  1. 安装tftp工具,用以和qemu模拟开发板收发文件(uboot通过tftp方式下载内核镜像和dtb)
apt install tftp-hpa tftpd-hpa xinetd
vim /etc/default/tftpd-hpa   //修改为以下形式
	TFTP_USERNAME="tftp"
	TFTP_DIRECTORY="/home/tftpboot"
	TFTP_ADDRESS="0.0.0.0:69"
	TFTP_OPTIONS="-l -c -s"
mkdir /home/tftpboot    //创建tftp目录
chmod 777 tftpboot
/etc/init.d/tftpd-hpa restart   //配置完成后,tftp重启
  1. 将编译好的uImage和vexpress-v2p-ca9.dtb复制到tftpboot目录
cp linux-4.4.76/arch/arm/boot/uImage /home/tftpboot/
cp linux-4.4.76/arch/arm/boot/dts/vexpress-v2p-ca9.dtb /home/tftpboot/
  1. 修改原来的启动脚本(主要的变化就是内核和dtb加载方式变了)
qemu-system-arm \
	-M vexpress-a9 \
	-m 512M \
	-kernel u-boot \
	-nographic \
	-net nic,vlan=0 -net tap,vlan=0,ifname=tap0 \
	-sd rootfs.ext3
  1. 启动脚本检测是否能启动

事实上以上教程仅能够达到运行qemu的作用,并不能完全模拟开发板进行开发,还有很多配置没有进行,任重而道远。

你可能感兴趣的:(嵌入式,linux,嵌入式硬件,c语言,ubuntu)