当前位置:首页 > 技术 > 嵌入式 > 正文内容

qemu 防真arm

Watrt4年前 (2020-10-28)嵌入式24910

我使用的是:

qemu-system-arm -M versatilepb -kernel arm2/vmlinuz-2.6.26-2-versatile -hda arm2/arm.qcow2 -initrd arm2/initrd.gz -append "root=/dev/ram" -m 256

这是我打包的文件mv.zip

qqq.png

下面是常用的命令:


1       kernel + initrd

这种方式在QEMU启动方法中最常见和最直接,启动参数形式如下:


qemu-system-arm -kernel zImage -initrd rootfs.cramfs -append “init=/linuxrc”

   


每次zImage和rootfs修改后首先build出来,直接作为参数传入QEMU,方便快捷。

此方式原理是,QEMU内置了一个很精简的bootloader,作用类似于u-boot。zImage、rootfs和传递给kernel的参数(append后字串)直接被QEMU加载进虚拟机内存的相对位置,并从kernel第一条语句开始执行。

kernel成功引导后就会挂载rootfs,并从文件系统的/linuxrc脚本开始执行初始化动作。

 

此方式有局限性,原因在rootfs.cramfs为只读的文件系统,如果调用/linuxrc有创建文件夹或拷贝动作就会无法完成(这也许可以通过mount一个可读写设备解决)。

 

2       kernel + NFS

这种方式与第一种相比,文件系统的挂载位置和方式发生了改变,因为可以指定NFS为可读可写的,使用体验上比第一种进了一大步。

NFS需要网络支持,也就是QEMU的虚拟网卡支持,启动参数如下:


qemu-system-arm -kernel zImage -append "console=ttyS0 root=/dev/nfs nfsroot=/root/nfs rw  init=/linuxrc ip=dhcp nousb" -rtc base=localtime -serial stdio

   


用户不写-net的情况下,QEMU默认会追加上“-net nic -net user”。

-net nic表示为虚拟机创建一个虚拟网卡

-net user表示QEMU使用user模式,什么是user模式,请见-net章节。

 

然后大家注意到给kernel的传参,差异点着重在蓝色部分:

root=/dev/nfs指定根文件系统的挂载点,是在QEMU Guest OS上的位置

nfsroot=127.0.0.1:/root/nfs是指NFS在网络上的位置

ip=dhcp指定QEMU Guest OS的ip分配方式

 

总的引导过程就是,kernel引导完成就会通过寻找网关为Guest OS分配ip,然后与NFS建立连接,再把根文件系统挂载起来。

 

这种方式的好处是可以在host OS方便地修改根文件系统的内容,不用重新启动kernel。

但要注意前提,要使用NFS方式挂载rootfs,那就要先启动NFS服务,并定制好rootfs内容。

 


启动NFS服务过程举例:

1.         修改/etc/export文件,增加一行“/root/nfs/ *(rw,insecure,sync,no_root_squash)”

注意insecure很重要,保证本地访问NFS

*表示允许任何ip地址访问NFS

rw指NFS盘可读可写

sync指同步写入到磁盘上

no_root_squash指root用户访问则给予root权限

2.         使用命令$exportfs –av

使用命令$service nfs restart

   


 

 

如果使用本地NFS,那么只要配置好本地服务即可;如果是使用远程NFS,那么先确认你有网络,然后确认GuestOS能分到ip,最后网络模式参数要修改。-net user改为“-net tap...”,具体怎样改见-net章节。

 

3       bootstrap + NAND

这是最不用操心kernel传参的一种使用方式,为什么说最不用操心呢?因为你需要传参给kernel的东西已经都被uboot准备好了。

这同时也是最接近真实FPGA板启动过程的方式,启动参数如下:


-pflash bootstrap.bin -mtdblock firmware -serial stdio -m 32M

   


当你要运行qemu的时候,拿出已经build好的bootstrap.bin和firmware即可。注意firmware必须是nand build方式产生的。

 

bootstrap放在nor flash(-pflash)里,firmware放在nand flash(-mtdblock)里,可以注意到上面传参方式的差别。

 

firmware里面包含3部分:u-boot、kernel和rootfs,另外还有一个空白空间,每个部分占用一个逻辑分区。

 

启动过程如下:

1.         bootstrap.bin会被加载到memory的0地址,并开始运行

2.         bootstrap从nand里面取出u-boot放到memory并运行

3.         u-boot为kernel设置好传入参数和环境变量,将kernel从nand取出,加载到内存并运行。

4.         kernel从nand挂载rootfs,完成初始化动作

5.         rootfs脚本将nand空白分区挂载到etc目录,完成启动。

 

4       kernel + NAND

此方式与前一种启动方式相比,好处是省掉了bootstrap,启动时也无需读取加载u-boot,这样省掉了不少启动时间。

坏处是要自己配kernel启动参数,其实也不是难事,怎样配见下表。

 


-kernel zImage -serial stdio -mtdblock firmware -append "console=ttyS0 init=/linuxrc root=/dev/mtdblock4" -net nic,macaddr=00:14:78:00:01:03 -old-param

   


 

为什么这里就要配kernel启动参数,而前一种启动方法不用呢?

因为前一种方法,u-boot启动后帮你配好了启动参数再启动的kernel。

相当于前一种方法是bootstrap+uboot+kernel+rootfs

这一种方法是qemu bootloader+kernel+rootfs,所以bootloader要代劳u-boot了。

 

u-boot怎样传参,我们就怎样传参给kernel。这里有几个要注意的:


1.         root=/dev/mtdblock4 rootfs在nand的第4个分区,那么挂载点要变一下咯~

2.         -old-param uboot使用旧式方法传参,也就是将参数排到内存的固定地址(0x100),那么我们也照办。

3.         -net nic,macaddr=00:14:78:00:01:03 u-boot通过serial_low和serial_high环境变量传给kernel mac地址,所以我们对qemu代码的boot过程做了一点小修改,将mac地址参数值存放到serial_low和serial_high的对应位置。(注意:使用了-old-param,这个参数才会有效)

   


 

 

 

 

5       常用参数简介

5.1    -kernel

顾名思义,后面跟kernel档。可以是zImage、uImage、Image、u-boot.elf、u-boot.bin。

 

5.2    -initrd

后面跟文件系统,支持的格式有很多如cramfs、jffs、cpio,能否挂载起来要看kernel支不支持。

 

5.3    -append

kernel的启动参数,后面最好用引号(”)引起来。常用的kernel参数如下:


1.         console:常与qemu的-serial搭配使用。常见取值有

a)         ttyS0:串口0

b)        ttyS1:串口1

c)         ttyAMA0:调试kernel的终端

d)        tty0:虚拟终端0

e)         tty1:虚拟终端1

2.         root,指定根文件系统的挂载点,常用取值有

a)         /dev/ram:文件系统在内存里

b)        /dev/ram0:文件系统在内存里

c)         /dev/nfs:NFS文件系统

d)        /dev/mtdblock*:文件系统在nand里。*的值看分区方式

3.         ramdisk_size=%dK

a)         ramdisk默认8192K,如果实际size大于8192则引导时会报出错误

b)        通过此参数来指定实际大小,与rootfs文件大小一致

4.         nfsroot

a)         是NFS文件系统才有用,用来指定NFS所在位置

b)        值的格式为:[IP]:/[FOLDER PATH]。eg.”nfsroot=172.21.2.76:/root/SONiX_NFS”,IP在root server确定时可以省略。

5.         rw

a)         文件系统读写权限,这里是可读可写

b)        其他可选值有ro

6.         init

a)         挂载根文件系统后第一个执行的程序或脚本

b)        常见的有/sbin/init,/linuxrc,/usr/init,因具体文件系统而异

7.         ip:值格式为

a)         [ip] : [boot/root server ip] : [gateway ip] : [netmask]。 eg.”ip=10.0.2.15:10.0.2.2:10.0.2.1:255.255.255.0”

b)        可以自动分配的话写为”ip=dhcp”即可

8.         nousb

a)         不启用usb功能

   


 

 

5.4    -old-param

设定kernel传参方式,目前是为了向kernel传入macaddr信息

 

5.5    -rtc

用于设定系统时间,格式如下


-rtc [base=utc|localtime|date][,clock=host|vm]

   


常用的是-rtc base=localtime


5.6    -serial dev

指定qemu内串口数据的输出方向,dev的取值:


stdio 标准IO

vc   虚拟终端

pty  伪tty

null  空设备

/dev/XXX 使用主机的tty,如/dev/ttyS0 /dev/parportN

filename 写入文件

   


通常我们取值stdio,这样就能够在控制台输出了。

 

5.7    -net

用于设定网络模式,一般有两种模式:user和tap

默认为user模式,缺省参数为”-net user -net nic”

网络选项:

 

5.7.1   -net nic[,vlan=n][,macaddr=addr]

用来设定虚拟网卡,

目前n的取值可以为0~7

addr形式为00:14:07:00:01:03,当局域网络限制mac时,此功能很有用

 

5.7.2   -net user[,vlan=n]

全部参数如下:


-net user[,vlan=n][,name=str][,net=addr[/mask]][,host=addr][,restrict=y|n]

         [,hostname=host][,dhcpstart=addr][,dns=addr][,tftp=dir][,bootfile=f]

         [,hostfwd=rule][,guestfwd=rule][,smb=dir[,smbserver=addr]]

 

用来设定guest os为user模式。

user模式其实是QEMU虚拟的NAT模式。原理图如下:

 

此模式下Host数据通过QEMU流入guest os时,host ip被解释为虚拟的ip。

默认情况下,local ip:10.0.2.15 host ip:10.0.2.2 DHCP server:10.0.2.15 DNS server:10.0.2.3

 

此模式只可实现Guest OS与Host OS的单向通信,即Guest OS可以访问Host OS的端口,但反过来就不行。怎样才能可以呢?

我们有如下参数可以配合user mode使用:


-redir [tcp|udp]:host-port:[guest-host]:guest-port

   


 

此法将连接到主机端口host-port的tcp或udp连接重定向到客户机端口guest-port上。guest-host未指定则默认值为10.0.2.15(DHCP默认地址)。

eg.


$qemu-system-arm -redir tcp :5555::23 [...]

$telnet localhost 5555

   


这样host就能够通过本机端口来访问qemu guest os的端口了。

但此法也有不便之处:只能静态映射端口,动态端口绑定就不给力了。

 

5.7.3   -net tap[,vlan=n][,fd=h][,ifname=name][,script=file] [,downscript=file]

用来设定guest OS为tap模式,在此模式下Guest OS能与任何网内机器互访。

此法需要host机配置网桥。原理图如下:

 

5.7.4   -net socket[,vlan=n]

全部参数如下:


-net socket[,vlan=n][,name=str][,fd=h][,listen=[host]:port][,connect=host:port]

                connect the vlan 'n' to another VLAN using a socket connection

-net socket[,vlan=n][,name=str][,fd=h][,mcast=maddr:port]

                connect the vlan 'n' to multicast maddr and port

   


此模式用于两个或多个QEMU的VLan远程连接

 

5.8    -pflash

模拟nor flash设备卡,一般传入bootstrap.bin

 

5.9    –mtdblock

模拟nand flash设备卡,一般传入烧写的firmware




分享给朋友:

相关文章

LittleFS - 一个高度完整的嵌入式文件系统

LittleFS - 一个高度完整的嵌入式文件系统

LittleFS - 一个高度完整的嵌入式文件系统拥有小巧灵活的文件系统对许多物联网设备至关重要。使用文件系统并将其与正确的存储技术(如外部闪存或SD卡)配对可能很困难。Mbed操作系统使文件系统的组合变得简单。Mbed OS 5.7既支持FAT文件系统,又引入了高度集成的嵌入式文件系统。这包括对没有自己的磨损平衡控制器的闪存芯片的磨损平衡支持。LittleFS  - 一个高度完整的嵌入式文件系统将数据存储在嵌入式设备上非常有用:无论是配置文件,传感器信息批量还是新的固件更新。您可以抓...

Qt5.x移植后的环境配置

Qt5.x移植后的环境配置

环境配置脚本如下#!/bin/sh export QTDIR=/usr/lib/qt5 export QT_QPA_PLATFORM_PLUGIN_PATH=$QTDIR/plugins export QT_QPA_PLATFORM=eglfs:fb=/dev/fb0 export QT_QPA_GENERIC_PLUGINS=evdevtouch:/dev/input/event1 export QT_QPAFONTDIR=/usr/...

嵌入试设备中杂记

嵌入试设备中杂记

WIFI:首先确定是否正确的加载USB无线网卡的驱动然后配置连接wifi配置:文件位置:/etc/wpa_supplicant.confctrl_interface=/var/run/wpa_supplicant ap_scan=1 network={   ssid="ZCWH"   key_mgmt=WPA-PSK   psk="00004157" }配置好后开始连接:wpa_sup...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。