汇编语言

汇编语言一发入魂 – 杨河老李 (kviccn.github.io)

 

 

 

安装QEMU

QEMU安装有两种方式:一种是直接使用apt-get安装,一种是下载源码安装。我们选择第一种安装方式:

wit@ubuntu:~$ sudo apt-get install qemu
wit@ubuntu:~$ qemu-system-
qemu-system-aarch64       qemu-system-microblazeel  qemu-system-ppc           qemu-system-sparc64
qemu-system-alpha         qemu-system-mips          qemu-system-ppc64         qemu-system-tricore
qemu-system-arm           qemu-system-mips64        qemu-system-ppc64le       qemu-system-unicore32
qemu-system-cris          qemu-system-mips64el      qemu-system-ppcemb        qemu-system-x86_64
qemu-system-i386          qemu-system-mipsel        qemu-system-s390x         qemu-system-xtensa
qemu-system-lm32          qemu-system-moxie         qemu-system-sh4           qemu-system-xtensaeb
qemu-system-m68k          qemu-system-nios2         qemu-system-sh4eb         
qemu-system-microblaze    qemu-system-or1k          qemu-system-sparc 

安装成功后,敲击qemu-system-命令,在弹出的提示中我们可以看到qemu支持不同的CPU架构。弱水三千,只取一瓢饮,我们主要是使用qemu-system-arm 和 qemu-system-aarch64命令,分别仿真ARM 32位和64位的开发平台,敲入下面的命令可以查看qemu-system-arm目前支持的开发板种类:

wit@ubuntu:~$ qemu-system-arm --version
QEMU emulator version 2.11.1(Debian 1:2.11+dfsg-1ubuntu7.29)
Copyright (c) 2003-2017 Fabrice Bellard and the QEMU Project developers
​
wit@ubuntu:~$ qemu-system-arm -M help
Supported machines are:
akita                Sharp SL-C1000 (Akita) PDA (PXA270)
ast2500-evb          Aspeed AST2500 EVB (ARM1176)
borzoi               Sharp SL-C3100 (Borzoi) PDA (PXA270)
canon-a1100          Canon PowerShot A1100 IS
cheetah              Palm Tungsten|E aka. Cheetah PDA (OMAP310)
collie               Sharp SL-5500 (Collie) PDA (SA-1110)
connex               Gumstix Connex (PXA255)
cubieboard           cubietech cubieboard
emcraft-sf2          SmartFusion2 SOM kit from Emcraft (M2S010)
highbank             Calxeda Highbank (ECX-1000)
imx25-pdk            ARM i.MX25 PDK board (ARM926)
integratorcp         ARM Integrator/CP (ARM926EJ-S)
kzm                  ARM KZM Emulation Baseboard (ARM1136)
lm3s6965evb          Stellaris LM3S6965EVB
lm3s811evb           Stellaris LM3S811EVB
mainstone            Mainstone II (PXA27x)
midway               Calxeda Midway (ECX-2000)
mps2-an385           ARM MPS2 with AN385 FPGA image for Cortex-M3
mps2-an511           ARM MPS2 with AN511 DesignStart FPGA image for Cortex-M3
musicpal             Marvell 88w8618 / MusicPal (ARM926EJ-S)
n800                 Nokia N800 tablet aka. RX-34 (OMAP2420)
n810                 Nokia N810 tablet aka. RX-44 (OMAP2420)
netduino2            Netduino 2 Machine
none                 empty machine
nuri                 Samsung NURI board (Exynos4210)
palmetto-bmc         OpenPOWER Palmetto BMC (ARM926EJ-S)
raspi2               Raspberry Pi 2
realview-eb          ARM RealView Emulation Baseboard (ARM926EJ-S)
realview-eb-mpcore   ARM RealView Emulation Baseboard (ARM11MPCore)
realview-pb-a8       ARM RealView Platform Baseboard for Cortex-A8
realview-pbx-a9      ARM RealView Platform Baseboard Explore for Cortex-A9
romulus-bmc          OpenPOWER Romulus BMC (ARM1176)
sabrelite            Freescale i.MX6 Quad SABRE Lite Board (Cortex A9)
smdkc210             Samsung SMDKC210 board (Exynos4210)
spitz                Sharp SL-C3000 (Spitz) PDA (PXA270)
sx1                  Siemens SX1 (OMAP310) V2
sx1-v1               Siemens SX1 (OMAP310) V1
terrier              Sharp SL-C3200 (Terrier) PDA (PXA270)
tosa                 Sharp SL-6000 (Tosa) PDA (PXA255)
verdex               Gumstix Verdex (PXA270)
versatileab          ARM Versatile/AB (ARM926EJ-S)
versatilepb          ARM Versatile/PB (ARM926EJ-S)
vexpress-a15         ARM Versatile Express for Cortex-A15
vexpress-a9          ARM Versatile Express for Cortex-A9
virt-2.10            QEMU 2.10 ARM Virtual Machine
virt                 QEMU 2.11 ARM Virtual Machine (alias of virt-2.11)
virt-2.11            QEMU 2.11 ARM Virtual Machine
virt-2.6             QEMU 2.6 ARM Virtual Machine
virt-2.7             QEMU 2.7 ARM Virtual Machine
virt-2.8             QEMU 2.8 ARM Virtual Machine
virt-2.9             QEMU 2.9 ARM Virtual Machine
xilinx-zynq-a9       Xilinx Zynq Platform Baseboard for Cortex-A9
z2                   Zipit Z2 (PXA27x)

我们接下来想在vexpress-a9虚拟开发板上运行Linux内核镜像zImage,来检测qemu-system-arm安装是否正确。

$ touch boot.sh
$ gedit boot.sh
qemu-system-arm  \
    -M vexpress-a9 \
    -m 512M \
    -dtb ./vexpress-v2p-ca9.dtb \
    -kernel ./zImage \
    -append "root=/dev/mmcblk0 rw console=tty0" \
    -sd rootfs.ext3
$ chmod +x boot.sh
$ ./boot.sh

创建一个启动脚本boot.sh,将上面的启动命令添加到脚本中,增加脚本执行权限,通过脚本即可直接执行qemu-system-arm,不用每次都输入命令了。

其中zImage和vexpress-v2p-ca9.dtb为A9 vexpress ARM 开发板的内核镜像和设备树文件,rootfs.ext3为SD卡文件系统镜像。为了验证软件安装是否正常,我们先使用测试镜像看是否正常启动,测试镜像下载地址,可关注公/众/号:宅学部落,然后回复:测试镜像,即可获取下载地址。

将zImage、vexpress-v2p-ca9.dtb、rootfs.ext3三个文件跟脚本boo.sh放置在同一个目录下,然后就可以运行脚本文件了。每次重启qemu-system-arm前,要将原来的qemu-system-arm进程先关掉。

如果你想在窗口控制台下启动Linux内核镜像,可以使用下面的脚本启动qemu-system-arm:

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

第08步:使用u-boot引导Linux内核

在嵌入式系统中,我们通常使用U-boot、vivi等BootLoader来引导Linux内核启动,接下来我们也在虚拟开发板上使用U-boot通过TFTP工具来引导Linux内核启动。

安装依赖的包:

$ sudo apt install net-tools
$ sudo apt install net-tools uml-utilities bridge-utils

在安装Ubuntu18.04时,我们配置了2个虚拟网卡,一个用来跟虚拟开发板桥接通信,一个用来共享主机的网络,访问互联网,保证我们能正常使用 apt/apt-get 安装软件。使用 ifconfig命令查看网卡的名字,在我的虚拟机上,分别是ens33和ens34,对应的IP分别为:

ens33:192.168.230.135
ens34:192.168.230.136

配置虚拟开发板与主机Ubuntu的桥接,修改/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

重启后,再次使用ifconfig命令:

br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.230.135  netmask 255.255.255.0  broadcast 192.168.230.255
        inet6 fe80::20c:29ff:fed7:c2d9  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:d7:c2:d9  txqueuelen 1000  (Ethernet)
        RX packets 7614  bytes 925743 (925.7 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 7461  bytes 10786796 (10.7 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
​
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::20c:29ff:fed7:c2d9  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:d7:c2:d9  txqueuelen 1000  (Ethernet)
        RX packets 969  bytes 737515 (737.5 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 398  bytes 45850 (45.8 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
​
ens34: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.230.136  netmask 255.255.255.0  broadcast 192.168.230.255
        inet6 fe80::49ca:25c9:5944:75d3  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:d7:c2:e3  txqueuelen 1000  (Ethernet)
        RX packets 348  bytes 44710 (44.7 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 163  bytes 16043 (16.0 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

如果发现出现了br0说明配置成功。接下来我们在开发板上运行u-boot,在开发板端ping 主机,看是否能ping通,来验证开发板和Ubuntu主机之间是否网络通畅。启动U-boot的脚本如下:

qemu-system-arm  \
    -M vexpress-a9 \
    -m 512M \
    -nographic \
    -kernel ./u-boot \
    -net nic,vlan=0 -net tap,vlan=0,ifname=tap0 \
    -sd rootfs.ext3

在u-boot环境下,分别设置ipaddr和serverip,分别对应开发板的IP和主机的IP,两个IP要设置在同一个网段内,主机的IP即桥接网口br0的IP:192.168.230.135

=> setenv ipaddr 192.168.230.130
=> setenv serverip 192.168.230.135
=> ping 192.168.230.135

在开发板上ping主机host有反应,说明开发板和Ubuntu主机网络已经搞通。如果我们想使用TFTP工具从主机Ubuntu上下载uImage镜像,还得在主机上安装TFTP服务。

安装主机Host上的TFTP服务

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

在Ubuntu下修改配置文件:/etc/default/tftpd-hpa

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/home/wit/tftpboot"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="-l -c -s"

通过配置文件,开发板默认会从/home/wit/tftpboot目录下去下载指定的文件。我们需要在主机上创建这个目录:

$ sudo mkdir /home/wit/tftpboot
$ sudo chmod 777 /home/wit/tftpboot
$ sudo /etc/init.d/tftpd-hpa restart

主机的TFTP服务开起来之后,我们接下来重启u-boot,设置ipaddr和serverip,就可以直接从主机上的/home/wit/tftpboot目录下加载uImage内核镜像运行了。

=> setenv ipaddr 192.168.230.135
=> setenv serverip 192.168.230.130
=> tftp 0x60003000 uImage
=> tftp 0x60500000  vexpress-v2p-ca9.dtb
=> bootm 0x60003000 - 0x60500000

到了这一步,说明网络配置成功,u-boot可以通过网络引导Ubuntu中的内核镜像启动。

 

第09步:自动化引导

如果每次嫌敲命令麻烦,我们可以修改bootcmd变量,这就需要自己编译u-boot源码了。从官网上下载最新的U-boot源码,解压后,修改:include/configs/vexpress_common.h:

/*Netmask*/
196 #define CONFIG_IPADDR 192.168.230.130
197 #define CONFIG_NETMASK 255.255.255.0
198 #define CONFIG_SERVERIP 192.168.230.135

安装ARM交叉编译器,并编译u-boot:

安装编译器:$ sudo apt install gcc-arm-linux-gnueabi gcc make libncurses-dev bison flex
下载u-boot源码: http://ftp.denx.de/pub/u-boot/

最新版的u-boot2020.07,ARCH和bootcmd可以通过make menuconfig 菜单选项配置。在Architecture select选项中选择:ARM architecture

设置bootcmd命令:

 

在弹出的输入栏中输入bootcmd命令:

tftp 0x60003000 uImage;tftp 0x60500000 vexpress-v2p-ca9.dtb;setenv bootargs 'root=/dev/mmcblk0 console=ttyAMA0';bootm 0x60003000 - 0x60500000;

将修改保存,退出菜单配置界面,然后就可以直接编译u-boot了:

$ CROSS_COMPILE=arm-linux-gnueabi-
$ export CROSS_COMPILE
$ make vexpress_ca9x4_defconfig
$ make

将生成的u-boot拷贝到/home/wit/tftpboot目录,运行脚本启动u-boot看是否能自动引导uImage启动。

 

第10步:挂载NFS文件系统

开发板挂载NFS文件系统,在开发板上要运行的文件不需要拷贝到开发板上,直接拷贝到主机Ubuntu的NFS上即可,非常方便。要想开发板挂载NFS文件系统,主机Ubuntu上首先要开启NFS服务:

$ sudo apt install nfs-kernel-server

在/etc/exports文件中添加:

 /home/rootfs *(rw,sync,no_root_squash,no_subtree_check)

开启NFS服务:

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

修改bootargs启动参数:

tftp 0x60003000 uImage;tftp 0x60500000 vexpress-v2p-ca9.dtb;setenv bootargs 'root=/dev/nfs rw nfsroot=192.168.230.139:/home/wit/rootfs,proto=tcp,nfsvers=4,nolock init=/linuxrc ip=192.168.230.130 console=ttyAMA0';bootm 0x60003000 - 0x60500000;

Ubuntu18.04使用的NFS版本是4,因此我们需要编译内核,支持NFS v4版本

 

接着配置和编译内核:

修改Makefile:ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
$ make vexpress_defconfig
$ make zImage
$ apt install u-boot-tools
$ make uImage  LOADADDR=0x60003000
$ make dtbs

将生成的arch/arm/boot/uImage和arch/arm/boot/dts/vexpress-v2p-ca9.dtb拷贝到/home/wit/tftpboot目录下,使用下面的命令启动内核:

qemu-system-arm  \
    -M vexpress-a9 \
    -m 512M \
    -nographic \
    -kernel ./u-boot \
    -net nic,vlan=0 -net tap,vlan=0,ifname=tap0 \
    -sd rootfs.ext3

 

编辑于 2020-11-01 16:26
posted @ 2022-05-10 21:14  Bigben  阅读(58)  评论(0编辑  收藏  举报