VMwareUbuntu20.04LTS使用Qemu虚拟机uboot启动或者配合busybox模拟ARM开发板

编程

这里提供相关工具的下载地址

Linux内核下载地址

busybox下载地址

Qemu下载地址

u-boot下载地址

文中使用的版本为Linux-4.9.268、busybox-1.33.0、qemu-5.2.0、u-boot-2021.01-rc4

版本差别不大,应该都没有问题的

一、busybox制作根目录,通过镜像启动linux内核模拟ARM板

1、编译linux内核

编译条件:gcc编译器,交叉编译器

sudo apt install gcc

sudo apt install arm-linux-gnueabi

清除做过的配置

make clean


自定义内核配置,通过空格键选择配置。这里不做修改,采用默认配置,后面可以根据需要再修改。

make menuconfig

如果运行make menuconfig出错,则需要安装如下的支持包

sudo apt-get install lncurses-dev

sudo apt-get install libncurses5-dev

保存退出后会自动生成.config配置文件

然后创建一个脚本build.sh

输入下面内容,运行即可编译

#! /bin/sh

make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm vexpress_defconfig

make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm

运行命令,开始编译,内容比较多,会花一些时间

sudo sh build.sh

然后会在源码目录下的arch/arm/boot/文件夹下生成镜像Image和zImage

2、编译busybox

进入到busybox目录下,编辑Makefile

搜索如下两个变量,更改成这样

ARCH ?= arm

CROSS_COMPILE ?= arm-linux-gnueabi-

执行下面命令,使得编译器生效

source /etc/profile

修改配置文件

make menuconfig

如果出现没有<curses.h>头文件,尝试安装如下支持包

sudo apt-get install libncurses5-dev

修改配置完成后,make编译

再make install生成默认文件_install

文件内容

记住这个_install文件夹位置,制作根目录的时候会用到

3、编译安装qemu

为了更好的使用qemu,安装前先下载一些安装包

#必要安装包

sudo apt-get install git libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev

#推荐安装包

sudo apt-get install git-email

sudo apt-get install libaio-dev libbluetooth-dev libbrlapi-dev libbz2-dev

sudo apt-get install libcap-dev 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 libsdl1.2-dev libseccomp-dev libsnappy-dev libssh2-1-dev

sudo apt-get install libvde-dev libvdeplug-dev libvte-2.90-dev libxen-dev liblzo2-dev

sudo apt-get install valgrind xfslibs-dev

#额外安装包

sudo apt-get install libnfs-dev libiscsi-dev

自带的qemu可能比较老,这里采用安装包的方式安装新版本

解压后进入qemu文件夹

这里选择一种在其他目录安装的方式,比较安全,不会向原目录增加多余的文件

 # 在qemu根目录打开终端

# 准备一个本机debug版本

mkdir -p bin/debug/native cd bin/debug/native

# 配置 QEMU 并启动构建

../../../configure --enable-debug

如果提示没有Ninja,则进行下面的操作

#安装支持包

sudo apt install re2c

#安装编译ninja

git clone git://github.com/ninja-build/ninja.git && cd ninja

./configure.py --bootstrap

#如果提示没有python,则sudo apt install python

#如果还报错没有c++,则安装sudo apt-get install g++,装完后再次执行上面的命令

ls #查看生成的ninja文件

cp ninja /usr/bin/ #拷贝ninja文件到/usr/bin/路径下

#检查ninja版本

ninja --version

#如果检查报错就安装

sudo apt install ninja-build

错误解决,再回到出错的步骤继续执行

cd ..   #回到native目录

../../../configure --enable-debug

配置完成,然后make编译

这里有8000多行的编译,时间会比较长

安装

sudo make install

# 返回到QEMU根目录

cd ../../..

运行./configure --help 可以获得帮助信息

测试qemu编译是否正常,输入命令

bin/debug/native/x86_64-softmmu/qemu-system-x86_64 -L pc-bios

弹出QEMU界面,安装成功。由于还没有制作根目录,所以显示没有设备

根据界面顶端提示,使用ctrl+alt+g退出输入界面

可以用qemu-system-arm -machine help命令来查看所支持的开发板

4、制作启动根目录

自己选择一个地方创建rootfs目录

在rootfs里面创建下面的这些空目录(和busybox的_install文件夹里重复的文件夹也可以不用创建,马上要复制过来)

(1)完善编译环境

先将刚刚busybox里生成的_install文件夹内部的全部内容复制到rootfs文件夹里。

在rootfs文件夹内打开终端

sudo cp -r ../../busybox-1.33.0/_install/* ./

命令里的文件夹路径根据自己的情况来写

当然lib库还是不够的,因为文件系统运行在arm平台,所以还需要arm-linux-gnueabi的库,直接从系统里安装的交叉编译器里复制过来。

sudo cp -p /usr/arm-linux-gnueabi/lib/* ./lib

接着来完善根目录文件

(2)完善设备文件dev内容

从终端进入dev文件夹

  • 创建四个串口设备

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

  • 创建null

sudo mknod -m 666 null c 1 3

(3)完善配置文件etc内容

从终端进入etc文件夹

  • 创建inittab

::sysinit:/etc/init.d/rcS

#::respawn:-/bin/sh

#::respawn:-/bin/loginconsole

::askfirst:-/bin/sh

#tty2::askfirst:-/bin/sh

::ctrlaltdel:/bin/umount -a -r

  • 创建fstab

proc    /proc      proc     defaults    0   0

none /dev/pts devpts mode=0622 0 0

mdev /dev ramfs defaults 0 0

sysfs /sys sysfs defaults 0 0

tmpfs /dev/shm tmpfs defaults 0 0

tmpfs /dev tmpfs defaults 0 0

tmpfs /mnt tmpfs defaults 0 0

var /dev tmpfs defaults 0 0

ramfs /dev ramfs defaults 0 0

  • 创建profile

# /etc/profile: system-wide .profile file for the Bourne shells

echo "-----------------------------------"

echo "Mini2440 FileSystem is Ready ..."

echo "-----------------------------------"

USER="`id -un`"

LOGNAME=$USER

#PS1="[u@h W]# " #显示主机名、当前路径等信息

PS1="pymeia@Mini2440:w # " #显示主机名、当前路径等信息

PATH=$PATH

HOSTNAME=`/bin/hostname`

export USER LOGNAME PS1 PATH

  • 创建init.d/rcS

#! /bin/sh

PATH=/bin:/sbin:/usr/bin:/usr/sbin #可执行程序 环境变量

export LD_LIBRARY_PATH=/lib:/usr/lib #动态链接库 环境变量

/bin/mount -n -t ramfs ramfs /var

/bin/mount -n -t ramfs ramfs /tmp

/bin/mount -n -t sysfs none /sys

/bin/mount -n -t ramfs none /dev

/bin/mkdir /var/tmp

/bin/mkdir /var/modules

/bin/mkdir /var/run

/bin/mkdir /var/log

/bin/mkdir -p /dev/pts //telnet服务需要

/bin/mkdir -p /dev/shm //telnet服务需要

#echo /sbin/mdev > /proc/sys/kernel/hotplug//USB自动挂载需要

/sbin/mdev -s //启动mdev在/dev下自动创建设备文件节点

/bin/mount -a

echo "-----------------------------------"

echo " welcome to Mini2440 board"

echo "-----------------------------------"

  • 创建group

root:*:0:

daemon:*:1:

bin:*:2:

sys:*:3:

adm:*:4:

tty:*:5:

disk:*:6:

lp:*:7:

lpmail:*:8:

news:*:9:

uucp:*:10:

proxy:*:13:

kmem:*:15:

dialout:*:20:

fax:*:21:

voice:*:22:

cdrom:*:24:

floppy:*:25:

tape:*:26:

sudo:*:27:

  • 创建passwd

root::0:0:root:/:/bin/sh

ftp::14:50:FTP User:/var/ftp:

bin:*:1:1:bin:/bin:

创建var文件夹,存放日志信息

sudo ln -s /tmp var/lock

sudo ln -s /tmp var/log

sudo ln -s /tmp var/run

sudo ln -s /tmp var/tmp

5、qemu启动开发板镜像

制作根文件系统镜像,把rootfs根目录的内容复制到这个镜像中,然后用qemu启动模拟开发板。

方法1

制作磁盘镜像启动方式

(1)制作磁盘镜像img

制作磁盘镜像并格式化

qemu-img create -f raw disk.img 512M   #生成512M大小的磁盘镜像

mkfs -t ext4 ./disk.img #把磁盘镜像格式化成ext4文件系统

也可以将其打包成mkdisk.sh脚本,方便再次创建

sudo sh mkdisk.sh

#!/bin/sh

qemu-img create -f raw disk.img 512M

mkfs -t ext4 ./disk.img

(2)复制rootfs内容到磁盘镜像

将rootfs根目录中所有内容复制到磁盘镜像中

mkdir tmpfs #创建一个临时文件夹,文件夹与rootfs同级

sudo mount -o loop ./disk.img tmpfs/ #创建挂载点并挂载

sudo cp -r rootfs/* tmpfs/ #复制文件到镜像

sudo umount tmpfs #卸载

也可以打包起来方便更新磁盘内容

sudo sh update.sh

#!/bin/sh

sudo mount -o loop ./disk.img tmpfs/

sudo cp -r rootfs/* tmpfs/

sudo umount tmpfs

更新期间会将rootfs的内容复制到tmpfs,再删除

检查镜像文件信息

file disk.img

(3)启动开发板

不带qemu界面

直接在终端启动,不带lcd界面

sudo sh runnolcd.sh

#! /bin/sh

qemu-system-arm -M vexpress-a9 -m 512M -dtb ../linux-4.9.268/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -kernel ../linux-4.9.268/arch/arm/boot/zImage -nographic -append "root=/dev/mmcblk0 rw console=ttyAMA0" -sd disk.img

如果遇到拒绝访问的情况,请授予文件访问权限,删掉磁盘重新创建(直接更新不成功)

chmod +x rcS

chmod -R 777 init.d/*

或者授予etc的所有文件访问权限

chmod -R 777 etc/

启动界面如下

带qemu界面

带lcd界面启动方式

sudo sh runlcd.sh

#! /bin/sh

qemu-system-arm -M vexpress-a9 -m 512M -dtb ../linux-4.9.268/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -kernel ../linux-4.9.268/arch/arm/boot/zImage -append "root=/dev/mmcblk0 rw console=tty0" -sd disk.img

启动界面如下

【注意】:启动终端的命令,里面的路径一定要根据自己创建的文件夹填写正确。启动命令也可以直接在终端输入,但是比较麻烦。

方法2

制作sd根文件系统镜像启动方式

(1)制作sd卡镜像

生成虚拟sd卡并格式化为ext格式

sudo sh mksd.sh

#! /bin/sh

dd if=/dev/zero of=rootfs.ext3 bs=1M count=32

mkfs.ext3 rootfs.ext3

(2)复制内容到sd镜像

将虚拟sd卡挂载到/mnt,拷贝rootfs的所有文件到sd,然后卸载sd

sudo sh update.sh

#! /bin/sh

mount -t ext3 rootfs.ext3 /mnt/ -o loop

cp -r rootfs/* /mnt

umount /mnt

(3)启动开发板

不带qemu界面

sudo sh runnolcd.sh

#! /bin/sh

qemu-system-arm -M vexpress-a9 -m 512M -dtb ../linux-4.9.268/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -kernel ../linux-4.9.268/arch/arm/boot/zImage -nographic -append "root=/dev/mmcblk0 rw console=ttyAMA0" -sd rootfs.ext3

带qemu界面

sudo sh runlcd.sh

#! /bin/shqemu-system-arm -M vexpress-a9 -m 512M -dtb ../linux-4.9.268/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -kernel ../linux-4.9.268/arch/arm/boot/zImage -append "root=/dev/mmcblk0 rw console=tty0" -sd rootfs.ext3

6、关闭虚拟开发板

方法一:直接关掉终端

方法二:ctrl +a 放手,然后按x

方法三:打开另一个终端输入

sudo killall qemu-system-arm

二、u-boot启动Linux内核方式,模拟ARM开发板

1、生成uImage内核映像

我们的目的是:uImage文件

生成它的步骤是:编译u-boot生成mkimage--->用mkimage生成uImage

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

这里解释一下uImage:

Linux内核编译(make)之后会生成两个文件,一个Image,一个zImage,其中Image为内核映像文件,而zImage为内核的一种映像压缩文件,Image大约为4M,而zImage不到2M

而uImage是用mkimage工具根据zImage制作而来的,它是uboot专用的映像文件,它是在zImage之前加上一个长度为64字节的“头”,说明这个内核的版本、加载位置、生成时间、大小等信息;其0x40之后与zImage没区别。

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

(1)编译u-boot

修改配置

进入u-boot源码目录,分别进入Makefile和config.mk修改配置

修改顶层Makefile,指定交叉编译器

CROSS_COMPILE ?= arm-linux-gnueabi-

修改顶层config.mk,指定ARM架构

ARCH := arm

编译

#配置开发板

make vexpress_ca9x4_defconfig

#编译u-boot

make –j4

如果编译出错,缺少如下配置

则安装如下,解决问题

sudo apt install bison flex

如果make -j4报错可能是上面的配置没有起到作用,则尝试如下命令

export CROSS_COMPILE=arm-linux-gnueabi-

export ARCH=arm

make clean

make vexpress_ca9x4_defconfig

make -j4

编译完成后如图

测试效果

在u-boot源码路径下,运行u-boot看是否成功

qemu-system-arm -M vexpress-a9 -kernel u-boot -nographic -m 512M

这里由于u-boot还没有uImage镜像,让倒计时结束自动加载会出问题。看到提示后,快速按任意按键,停止自动加载,出现下图,说明编译成功。

(2)拷贝mkimage

编译完u-boot源码,会在tools目录下生成mkimage,用它可以将zImage转变成uImage

把u-boot目录下tools/mkimage 拷贝到/usr/bin目录下,为了可以执行mkimage相关的命令。

如果不拷贝直接执行命令,你会发现/usr/bin缺少文件

除此之外,还可以,直接命令下载,也会再该/usr/bin目录下生成mkimage

sudo apt install u-boot-tools

这种方法下载自带的u-boot-tools不知道会不会出问题,可以尝试尝试。

为nfs服务做准备

再生成uImage前,需要nfs配置的修改,重新编译Linux内核,让内核支持nfs功能,生成新的zImage,然后再转化成uImage

修改配置如下,在Linux内核目录下输入:make menuconfig

进入File system --->

再进入Network File System --->

将带有NFS的都用空格键选上

选中后如图

保存退出

(3)生成uImage(疑问待解决)

方法一:

直接按照以下命令重新编译(待验证,地址也有问题)

 export ARCH=arm

export CROSS_COMPILE=arm-linux-gnueabi-

make vexpress_defconfig

make zImage -j8

make modules -j8

make LOADADDR=0x60003000 uImage -j8

make dtbs

方法二:将编译生成的zImage转化成uImage(也是地址问题待解决)

切换到Linux内核目录下,执行下面命令

mkimage -n "mini2440" -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008040 -d  arch/arm/boot/zImage  arch/arm/boot/uImage

参数说明

-n "mini2440"   #指定镜像名称

-A arm #设置为arm架构

-O linux #设置操作系统为linux

-T kernel #设置镜像类型为kernel

-C none #设置压缩类型为none

-a 0x30008000 #指定加载地址为0x30008000

-e 0x30008040 #执行入口地址为0x30008040

-d arch/arm/boot/zImage #指定镜像数据文件路径

arch/arm/boot/uImage #最终生成的uImage的路径和文件名称

这里直接在zImage旁边生成uImage

到此uImage镜像生成结束

然后将uImage文件拷贝到tftpboot目录下(这一步也可以后面再一起做),这个文件夹是在配置tftp的时候创建的。

sudo cp ../../linux-4.9.268/arch/arm/boot/uImage ./		#路径根据自己的情况来

2、安装配置nfs服务

在前面我们已经装好了tftp服务器,但还需要安装nfs服务

(1)安装

sudo apt-get install  nfs-kernel-server

(2)创建nfs共享目录,设置权限

sudo chmod 777 ./rootfs

(3)添加NFS共享目录路径

vi /etc/exports

在/etc/exports添加以下路径

/home/pymeia/qemu/ARM/ubootA9/rootfs *(rw,sync,no_subtree_check)

其中:

rw 可读可写操作

sync 内存和磁盘上的内容保持同步

no_root_squash Linux主机不再将开发板设置为匿名用户,可以操作文件读写

注意:Ubuntu20.04,这个文件里不填这个参数,会报错。exports文件里有参考实例说明,只有三个参数

no_subtree_check 不检查根文件系统子目录文件

(4)重启nfs服务

sudo /etc/init.d/rpcbind restart

sudo /etc/init.d/nfs-kernel-server restart

或者

systemctl restart nfs-kernel-server

(5)检查nfs是否启动正常

sudo showmount -e

#显示全部可以挂载的目录

sudo /etc/init.d/nfs-kernel-server status #查看nfs服务的当前状态

ps -e |grep nfs #看进程中nfs服务是否启动

(6)nfs使用

自己创建一个目录当作nfs目录,然后再/etc/exports中添加路径,可以把你的程序放到这个目录下,通过挂载映射到./mnt。./mnt可以再主机上,也可以在开发板上,方便进行代码的调试。

在本机localhost上挂载nfs目录到./mnt,这样rootfs的内容就映射到了./mnt

sudo mount -t nfs localhost:/home/pymeia/qemu/ARM/ubootA9/rootfs ./mnt/

#这里挂载的目录一定要在/etc/exports里添加,否则挂载无效

卸载后,文件删除

umount ./mnt

同理,在开发板上挂载nfs目录到/mnt(假设主机IP地址为192.168.146.129)

mount -t nfs -o nolock 192.168.146.129:/dev/nfs  /mnt

#其中:-o nolock是去除文件锁,否则会报错

3、安装配置tftp服务

(1)安装tftp

sudo apt-get install tftp-hpa tftpd-hpa xinetd

(2)更改配置文件

sudo cp  /etc/default/tftpd-hpa  /etc/default/tftpd-hpa_back	#备份原始设置

sudo gedit /etc/default/tftpd-hpa

填写自己要创建tftpboot文件的路径

(3)创建tftp目录,设置权限

配置好后,到上面填写的路径,创建文件夹,并设置权限

#切换到上面填写的路径

sudo mkdir tftpboot

sudo chmod 777 tftpboot

(4)重启tftp服务,让其生效

sudo /etc/init.d/tftpd-hpa restart

(5)测试tftp服务是否正常

把需要的文件如u-boot、dtb、uImage等拷贝到tftpboot文件夹(后面u-boot启动要用到)

uImage

cp -r /home/pymeia/qemu/ARM/linux-4.9.268/arch/arm/boot/uImage ./

u-boot

cp -r /home/pymeia/qemu/ARM/ubootA9/u-boot/u-boot ./

vexpress-v2p-ca9.dtb

cp -r /home/pymeia/qemu/ARM/linux-4.9.268/arch/arm/boot/dts/vexpress-v2p-ca9.dtb ./

整理copy.sh

#! /bin/sh

cp -r /home/pymeia/qemu/ARM/linux-4.9.268/arch/arm/boot/uImage ./

cp -r /home/pymeia/qemu/ARM/ubootA9/u-boot/u-boot ./

cp -r /home/pymeia/qemu/ARM/linux-4.9.268/arch/arm/boot/dts/vexpress-v2p-ca9.dtb ./

tftp 192.168.146.129   #主机ip可以用ifconfig来查看

tftp> get uImage #获取文件,保存到用户名目录下

tftp> q #退出tftp

ps -e | grep "tftp" #查看 tftp 的进程号

可以看到,获取的文件和获取失败的文件都会显示在用户目录下

4、配置qemu和ubuntu网络桥接功能(这一部分,暂时没有搞完)

VMware 需要配置成NAT模式, 在VMware的桥接模式下面,目前qemu无法成功连接网络

VMware也不能设置成静态ip地址,设置成静态ip地址也是无法连接网络

安装桥接依赖包

sudo apt install uml-utilities bridge-utils

#bridge-utils 虚拟网桥工具

#uml-utilities UML(User-mode linux)工具

查看是否tun设备文件,如果存在说明宿主机的内核支持TAP网络接口

ls /dev/net

如果没有,则要手动创建

sudo mkdir /dev/net

sudo mknod /dev/net/tun c 10 200

加载tun模块

sudo /sbin/modprobe tun

非常建议更改重要配置的节点时,及时创建虚拟机快照,方便恢复,已经重装一次,吸取教训了

下面是大雷区,不要乱用,或者在用之前创建还原快照,否则会直接导致Ubuntu 20.04 LTS失去网络,甚至运气差点要重装

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

修改配置文件(重启生效)

sudo gedit /etc/network/interfaces

添加以下内容

# interfaces(5) file used by ifup(8) and ifdown(8)

auto lo

iface lo inet loopback

auto ens33

auto br0

iface br0 inet dhcp

bridge_ports ens33

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

添加qemu有关系统脚本

在/etc/qemu-ifup文件中添加以下内容

#!/bin/sh

echo sudo tunctl -u $(id -un) -t $1

sudo tunctl -u $(id -un) -t $1

echo sudo ifconfig $1 0.0.0.0 promisc up

sudo ifconfig $1 0.0.0.0 promisc up

echo sudo brctl addif br0 $1

sudo brctl addif br0 $1

echo brctl show

brctl show

sudo ifconfig br0 192.168.146.129

# 根据自己的实际情况修改 IP地址,注意:uboot 中的 CONFIG_SERVERIP(serverip) 要跟这里一样

在/etc/qemu-ifdown文件中添加以下内容

#!/bin/sh

echo sudo brctl delif br0 $1

sudo brctl delif br0 $1

echo sudo tunctl -d $1

sudo tunctl -d $1

echo brctl show

brctl show

给上面的脚本添加执行权限

sudo chmod +x /etc/qemu*

重启网络使生效

sudo service network-manager restart

u-boot启动

修改u-boot配置文件include/configs/vexpress_common.h

sudo gedit include/configs/vexpress_common.h

#define CONFIG_BOOTCOMMAND 

"tftp 0x60003000 uImage;tftp 0x60500000 vexpress-v2p-ca9.dtb;

setenv bootargs "root=/dev/mmcblk0 console=tty0";

bootm 0x60003000 - 0x60500000;"

#define CONFIG_IPADDR 10.0.2.14

#define CONFIG_NETMASK 255.255.255.0

#define CONFIG_SERVERIP 192.168.146.129

所有配置完成后,开始建立u-boot启动内核文件

新建启动脚本ubootqemu.sh

#! /bin/sh

qemu-system-arm

-M vexpress-a9

-kernel u-boot

-nographic

-m 512M

-net nic,vlan=0 -net tap,vlan=0,ifname=tap0

-sd rootfs.ext3

未完....问题解决后更新

参考文章链接:

https://blog.csdn.net/u010344264/article/details/82949143

https://zhuanlan.zhihu.com/p/340362172

https://www.jianshu.com/p/8619a6739040

https://www.cnblogs.com/schips/p/12350122.html

https://blog.csdn.net/wxh0000mm/article/details/90056912

以上是 VMwareUbuntu20.04LTS使用Qemu虚拟机uboot启动或者配合busybox模拟ARM开发板 的全部内容, 来源链接: utcz.com/z/519675.html

回到顶部