在服务器上进行海思开发板的仿真

参考文章
https://www.cnblogs.com/pengdonglin137/p/5023342.html
https://blog.csdn.net/sxw1002/article/details/52841671
https://wiki.ubuntu.com/Kernel/Dev/QemuARMVexpress
https://translatedcode.wordpress.com/2016/11/03/installing-debian-on-qemus-32-bit-arm-virt-board/
https://gmplib.org/~tege/qemu.html

1、编译linux内核

https://mirrors.edge.kernel.org/pub/linux/kernel/v3.x/ 下载合适的内核源码。我用的是linux-3.18.24

除了arm-hisiv400-linux的工具链,编译内核还需要安装bc、ncurses-devel(在make menuconfig时用到)
yum install bc ncurses-devel

然后就可以开始编译了
make CROSS_COMPILE=arm-hisiv400-linux- ARCH=arm O=./_out vexpress_defconfig
make CROSS_COMPILE=arm-hisiv400-linux- ARCH=arm O=./_out menuconfig

可以选上,否则对ext4不能支持
[*] Enable the block layer --->
 [*] Support for large (2TB+) block devices and files

make CROSS_COMPILE=arm-hisiv400-linux- ARCH=arm O=./_out zImage -j4

2、安装qemu

偷个懒,直接用yum装。CentOS7在epel里面有
yum install qemu-system-arm

列出qemu-system-arm可以支持的机型
qemu-system-arm -machine help

3、试运行内核

cd _out/arch/arm/boot
qemu-system-arm -M virt -m 512M -kernel zImage -nographic

如果能走到
---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)

这一步,说明内核可以成功运行了

PS:其他参考文章,一般提到qemu-system-arm要模拟vexpress-a9这个型号。但是这个型号只有sd卡一个存储,不太方便进行定制。用virt虚拟型号可定制性更强。用virt型号的时候,不用指定tty

参考文章1提到的找console tty的方法有些不对及不完善。首先,生成的.config文件位于O=指定的输出_out目录下。其次.config文件中相关的配置项是
CONFIG_CMDLINE="console=ttyAMA0"
因此,应该以console=来查找,而不是按CONFIG_CONSOLE来查找。后来我曾经尝试编译内核的时候改成hisi_defconfig来取代vexpress,结果.config中CONFIG_CMDLINE是空的,qemu-system-arm启动后看不到输出了

4、编译busybox

wget http://www.busybox.net/downloads/busybox-1.25.1.tar.bz2
tar xjf busybox-1.25.1.tar.bz2
cd busybox-1.25.1
export ARCH=arm
export CROSS_COMPILE=arm-hisiv400-linux-
make menuconfig

在 Busybox Settings ---> Build Options 中注意选中
[*]Build BusyBox as a static binary (no shared libs)

make -j4
make install

编译后生成的文件在busybox的_install目录下

5、制作根文件系统

mkdir rootfs
cp -r busybox-1.25.1/_install/* rootfs/

busybox只是让这个根文件系统有了最基本的命令。linux中还需要添加一些必要的目录和文件

mkdir -p rootfs/dev/ rootfs/lib/ rootfs/proc/ rootfs/tmp/ rootfs/var/ rootfs/sys/
mknod rootfs/dev/tty1 c 4 1
mknod rootfs/dev/tty2 c 4 2
mknod rootfs/dev/tty3 c 4 3
mknod rootfs/dev/tty4 c 4 4
mknod rootfs/dev/urandom c 1 9
mknod rootfs/dev/null c 1 3
cd rootfs
wget http://files.cnblogs.com/files/pengdonglin137/etc.tar.gz
tar xzf etc.tar.gz
rm etc.tar.gz -rf

cp /opt/hisi-linux/x86-arm/arm-hisiv400-linux/target/lib/*.so* rootfs/lib/ -d

etc目录下需要放一些系统初始化的必要脚本,待会再细讲。这里先用别人现成的

将rootfs目录下的内容,制作成镜像。回退到rootfs的父级目录

yum install qemu-img
qemu-img create -f raw rootfs.img 1G
mkfs.ext3 -F rootfs.img
mkdir tmpfs
mount -t ext3 rootfs.img tmpfs/ 
cp -r rootfs/*  tmpfs/
umount tmpfs/

6、尝试启动

qemu-system-arm -M virt -m 512M -kernel linux-3.18.24/_out/arch/arm/boot/zImage -nographic -drive if=none,file=rootfs.img,format=raw,id=hd -device virtio-blk-device,drive=hd -append "root=/dev/vda rw console=ttyAMA0"

这组参数也是试了很久才试验出来的。加了硬盘之后,需要append console才能有启动日志输出。而且要指定root路径。由于还不能敲命令行,硬盘挂载在/dev/下面的什么也要靠猜。

想退出qemu,先按Ctrl+D退出console,然后再按Ctrl+a,松手再按x,结束qemu

参考网上其他文章,将设备型号模拟成vexpress-a9也是可以的,不过文件系统要挂载在sd卡上面,不是硬盘上面。模拟成vexpress-a15无法启动,不知道为什么。
qemu-system-arm -M vexpress-a9 -m 512M -kernel linux-3.18.24/_out/arch/arm/boot/zImage -nographic -append "root=/dev/mmcblk0 rw console=ttyAMA0" -sd rootfs.img

7、添加网络支持

网络的各种文章,都没有把qemu网络该怎么设置,说得很清楚。说得比较清楚的是
https://www.linux-kvm.org/page/Networking

qmeu的网络分为user-mode和tap两种。user-mode只能让虚拟机访问外网,但外网不能访问虚拟机。如果要让外面能访问虚拟机,就必须要使用tap。

要使用tap,必须要在宿主机上面创建一个bridge,这点和kvm使用网桥是一样的
https://www.jianshu.com/p/eb7d8bd7e477

然后添加一个/etc/qemu-ifup的文件

#!/bin/sh
set -x

switch=br0

if [ -n "$1" ];then
        #tunctl -u `whoami` -t $1
        ip tuntap add $1 mode tap user `whoami`
        ip link set $1 up
        sleep 0.5s
        #brctl addif $switch $1
        ip link set $1 master $switch
        exit 0
else
        echo "Error: no interface specified"
        exit 1
fi

qemu-ifup文件需要赋予执行权限。注意switch变量要设置为宿主机上面的网桥名字

然后可以往虚拟机中添加网卡了
qemu-system-arm -M virt -m 512M -kernel linux-3.18.24/_out/arch/arm/boot/zImage -nographic -drive if=none,file=rootfs.img,format=raw,id=hd -device virtio-blk-device,drive=hd -append "root=/dev/vda rw console=ttyAMA0" -device virtio-net-device,netdev=network0 -netdev tap,id=network0,ifname=tap0

或者用vexpress-a9也可以
qemu-system-arm -M vexpress-a9 -m 512M -kernel linux-3.18.24/_out/arch/arm/boot/zImage -nographic -append "root=/dev/mmcblk0 rw console=ttyAMA0" -sd rootfs.img -net nic,vlan=0 -net tap,vlan=0,ifname=tap0

在虚拟机中用ip link命令可以看到lo和eth0两个网卡了。不过要等网络通起来,还需要一些配置

ifconfig eth0 192.168.1.33 netmask 255.255.255.0 broadcast 192.168.1.255 up

这样,宿主机和虚拟机之间就可以通信起来了。我们可以把设置ip地址等初始化工作放到/etc/init.d/rcS脚本里面。不过现在的网络功能还是有缺陷的,域名解析的工作还不正常

参考
http://blog.sina.com.cn/s/blog_6de4c6c30100tiw7.html
https://blog.csdn.net/prog_6103/article/details/78569510

首先,即时busybox是静态链接编译的,系统中/lib目录下还是需要有libnss_dns.so.2、libresolv.so.2这些库,否则域名解析无法工作。这些库可以从海思的gcc里面找到、

其次,根文件系统中还没有/etc/resolv.conf,没有配置dns服务器

DNS配置好了之后,在虚拟机上面依然无法解析成功域名。在宿主机上面通过tcpdump抓包,发现dns请求是发出了,但是宿主机会回复一条ICMP命令,Destination Unreachable (Host administratively prohibited)。这里主要是宿主机启用了iptables,复杂的FORWARD规则拦截了。最简单的解决方法是在iptables插入一条
iptables -I FORWARD -i br0 -j ACCEPT
让所有br0进来的数据都允许转发

8、编译dropbear

为了方便往虚拟开发板上面传文件,远程控制,需要在虚拟开发板上面加上dropbear,方便用ssh远程登录及传输文件

mkdir dropbear
cd dropbear

wget http://zlib.net/zlib-1.2.11.tar.gz
tar xzf zlib-1.2.11.tar.gz
cd zlib-1.2.11
./configure --prefix=/home/kernel/dropbear/lib/zlib --static

修改Makefile
CC=gcc  改为  CC=arm-hisiv400-linux-gcc
LDSHARED=gcc  改为 LDSHARED=arm-hisiv400-linux-gcc
CPP=gcc -E  改为  CPP=arm-hisiv400-linux-cpp -E

make -j4
make install

wget https://matt.ucc.asn.au/dropbear/releases/dropbear-2017.75.tar.bz2
tar xjf dropbear-2017.75.tar.bz2
cd dropbear-2017.75
./configure --with-zlib=/home/kernel/dropbear/lib/zlib --host=arm-hisiv400-linux
make -j4

编译出dropbear后,把它拷贝到rootfs的/sbin目录下。然而,直接运行dropbear,会发现进程还是启动不起来。使用dropbear -E启动,可以看到报错信息是因为缺少了秘钥文件。回到宿主机上面,进入把dropbearkey也拷贝到rootfs/sbin目录下,另外根文件系统也要确保有/dev/urandom这个设备,否则dropbearkey无法运行。进入虚拟机

mkdir -p /etc/dropbear
cd /etc/dropbear/
dropbearkey -t rsa -s 4096 -f dropbear_rsa_host_key

记得从虚拟机中把/etc/dropbear/dropbear_rsa_host_key备份
这时候,使用dropbear -E是可以启动的,但是使用dropbear不带任何参数是启动失败的。把syslog打印出来,发现报错信息为Early exit: Failed to daemonize: No such file or directory。这是一个相当奇葩的问题,居然在调用daemon函数的时候出现了ENOENT的errno。谷歌找到的答案是
https://www.linuxquestions.org/questions/linux-networking-3/sshd-fatal-daemon-failed-no-such-device-279664/
mknod /dev/null c 1 3

9、其余优化

虚拟多核心的arm cpu,qemu-system-arm启动时加上-smp 4,虚拟四核。不过CentOS 7 epel带的qemu 2.0.0还不支持虚拟多核心,需要自己编译更新的qemu版本
上面创建的根文件系统镜像rootfs.img,采用的是raw格式,而且容量只有1G。如果希望虚拟更大的硬盘,则建议用qcow2格式
qemu-img create -f qcow2 rootfs.img 300G

附1:虚拟机根文件中的/etc/init.d/rcS文件参考

#!/bin/sh

# Mount fs accroding to /etc/fstab 
mount -a

# Network
ipaddr=192.168.1.33
netmask=255.255.255.0
gateway=192.168.1.1

ifconfig lo 127.0.0.1 up  
ifconfig eth0 $ipaddr \
  netmask $netmask up
route add default gw $gateway

dropbear 

/etc/fstab 文件参考

#device         mount-point     type    options         dump    fsck order
proc            /proc           proc    defaults        0       0
sysfs           /sys            sysfs   defaults        0       0
#/dev目录在qemu下不能设置为tmpfs,否则会覆盖了mknod已经创建好的tty1-tty4
#dev             /dev            tmpfs   defaults        0       0
var             /var            tmpfs   defaults        0       0
tmp             /tmp            tmpfs   defaults        0       0

附2:交叉编译strace

wget https://strace.io/files/5.7/strace-5.7.tar.xz
tar xJf strace-5.7.tar.xz
cd strace-5.7
./configure --host=arm-hisiv400-linux
make -j4
arm-hisiv400-linux-strip strace

附3:查看syslog的方法
首先要手动启动syslogd
其次要手动创建好/var/log/目录

附4:编译更新版本的qemu
wget https://download.qemu.org/qemu-4.0.1.tar.xz
tar xJf qemu-4.0.1.tar.xz
cd qemu-4.0.1
./configure --target-list=arm-softmmu,aarch64-softmmu --audio-drv-list=
make -j4
make install

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343