(说明:这篇文章是我的朋友写的,他在我的博客上首次发表,姑且算为原创吧)

 

基于Qemu的RTEMS仿真平台搭建

 

1 概述

此文档描述了在Windows Qemu虚拟机下建立RTEMS仿真测试环境的过程。
QEMU是一个开源的虚拟机程序,主要应用在Linux系统中,使用命令行方式进行操作。QEMU在Windows下有移植版本,并且技术爱好者为Windows的QEMU提供了免费UI界面,使其更符合Windows用户的软件操作习惯。这个UI程序称为QEMU Manager,平均每年更新一次,目前最新版本号为7.0。用户可以从官网http://www.davereyn.co.uk/获取QEMU Manager的相关信息。

本文构造的RTEMS仿真平台使用到了如下资源:
1.    Win7操作系统;
2.    QEMU Manager 7.0安装程序;
3.    network-demos-4.9.4.tar.bz2(可选,用于平台功能验证)。

2 QEMU虚拟机的安装与设置

2.1 下载安装程序

在这份文档示例中使用的是当前最新的QEMU Manager 7.0安装版程序,程序来源于http://www.davereyn.co.uk/download.htm。此程序下集成了QEMU 0.11.1与相应的加速器KQemu。

2.2 安装QEMU Manager

    安装过程相对简单,指定好安装路径即可,没有需要特别留意的地方。
 
图1 QEMU Manager安装界面

 
图2 初次运行QEMU Manager配置界面

2.3 配置QEMU Manager

2.3.1 添加NAT网卡

    QEMU Manager主界面下选择“Tools->Configure TAP Network Devices”
 
图3 添加虚拟网卡界面

第一次添加NAT网卡时系统可能会要求安装特定驱动,允许安装即可。
添加成功后Windows系统会生成一个新网卡配置项--“本地连接”,为了方便以后应用,用户可以重新指定这个新网卡名称,文档示例中将此NAT网卡重命名为“qemu_tap”。

2.3.2 添加虚拟机

QEMU Manager主界面下选择“VM->New Virtual Machine”,在这里需要指定新虚拟机名、虚拟机使用的CPU类型、内存与硬盘容量配置。根据需要,示例中的新虚拟机命名为“rtems_pc386”,CPU类型为“Standard x86”,内存为256M,硬盘为128M。

 
图4 添加虚拟机界面1

 
图5 添加虚拟机界面2
 
图6 添加虚拟机界面3

    添加成功一个新虚拟机后会出现如下界面:
 
图7 虚拟机配置界面

2.4 配置虚拟机

2.3节新创建的虚拟机使用默认工作参数。一般来说,在不使用网络功能的前提下,RTEMS自带pc386 BSP已经可以在默认的虚拟机配置中正常运行。如果需要打开网络功能则还应该对虚拟机参数做适当修改。
示例使用了RTEMS源码包自带的NE2000网卡驱动,所作参数修改如下:修改系统总线类型、选择网卡类型、配置网络参数。

2.4.1 修改系统总线类型

由于RTEMS自带的NE2000驱动无法在PCI总线PC中运行,所以要将“Machine Type”修改为ISA类型。

 
图8 选择“Machine Type”界面

 
图9 配置“CPU Type”界面

2.4.2 选择网卡类型

要确保“Hardware”配置界面中的“Enable Networking”参数为“Yes”,否则配置界面不会显示网卡选择项。
 

双击“Hardware”配置界面中的“Network Card 1”项,需要选择网卡类型、VLAN类型、网卡MAC地址、指定TAP网络适配器。其中,选择“NE2000 ISA”网卡,VLAN类型为“Tap Networking”, MAC地址可以使用默认值或自己重新指定,TAP适配器选择2.3节中创建的新网卡名,本例使用的是“qemu_tap”。


图10 “Network Card”配置界面







2.4.3 配置NAT网络参数

1.在Windows“网络连接”界面中找到“qemu_tap”网卡。

 
图11 Windows“网络连接”界面

2.为NAT网卡配置IP。注意,这里设置的NAT网卡IP地址可以与宿主机上的真实物理网卡的地址不在一个段内;而是与虚拟机中NE2000网卡设置的网络地址在一个段内就可以了。
示例使用的物理主机网卡IP为192.168.2网段,配置的NAT网卡IP为192.168.10网段。


图12 修改NAT网卡IP界面

3 网络例程编译

经过以上配置之后QEMU虚拟机的环境已经搭建完毕,但想要正常运行RTEMS程序则还需要对相关应用代码做修改。
文档示例使用的netdemo应用程序来源于RTEMS官方提供的程序包network-demos-4.9.4.tar.bz2。解压network-demos-4.9.4.tar.bz2,在解压后的文件夹中有一个名为networkconfig.h的文件,所有的修改都在此文件中完成。

3.1 定义网卡类型

    RTEMS 的i386 BSP 默认安装的是DEC21140 网卡,而QEMU 中仿真的
是NE2000 网卡,所以要重新定义相关的宏:

#define  RTEMS_BSP_NETWORK_DRIVER_NAME
                   BSP_NE2000_NETWORK_DRIVER_NAME
#define  RTEMS_BSP_NETWORK_DRIVER_ATTACH
                   BSP_NE2000_NETWORK_DRIVER_ATTACH




3.2 配置网卡MAC地址

这里设置的物理地址一定要与2.4.2节中设置的QEMU NAT网卡MAC值一致。

/*
 * Define RTEMS_SET_ETHERNET_ADDRESS if you want to specify the
 * Ethernet address here.  If RTEMS_SET_ETHERNET_ADDRESS is not
 * defined the driver will choose an address.
 */
static char ethernet_address[6] = { 0x52, 0x54, 0x00, 0x38, 0xFE, 0x22 };







3.3 配置其他网络参数

在netdriver_config结构体中配置本地IP、网卡IO地址、中断号和所在槽号。其中IP 地址和IP 掩码可以根据自己的需要设置。注意,IP 地址必须与宿主机中TAP 网卡的IP 地址在同一个段内,才能实现虚拟机下RTEMS 与宿主机的网络通信。
关键是最后三个设置参数。这三个参数是在例程的基础上添加上去的。分别设置的是网卡的IO 地址、中断号和所在插槽号。如果在这个定义中省略这三个参数,则RTEMS 采用默认值。而默认NE2000 网卡IO 地址是0x240,中断号是5,与QEMU 虚拟机仿真的网卡不符,所以必须按照上述参数进行设置。

/*
 * Default network interface
 */
static struct rtems_bsdnet_ifconfig netdriver_config = {
        RTEMS_BSP_NETWORK_DRIVER_NAME,          /* name */
        RTEMS_BSP_NETWORK_DRIVER_ATTACH,        /* attach function */
#ifdef RTEMS_USE_LOOPBACK
        &loopback_config,               /* link to next interface */
#else
        NULL,                           /* No more interfaces */
#endif
        "192.168.10.2",                 /* IP address(自行配置) */
        "255.255.255.0",                /* IP net mask */
#endif /* !RTEMS_USE_BOOTP */
        ethernet_address,               /* Ethernet hardware address */
        0,                              /* ignore broadcast */
        0,                              /* mtu */
        0,                              /* rbuf_count */
        0,                              /* xbuf_count */
        0x300,                          /* port (配置为0x300) */
        9,                              /* irq  (配置为9)*/
        0,                              /* bpar (配置为0)*/
        NULL                            /* driver control pointer */
};


在rtems_bsdnet_config结构体中配置网关等参数:

/*
 * Network configuration
 */
struct rtems_bsdnet_config rtems_bsdnet_config = {
        &netdriver_config,
#if (defined (RTEMS_USE_BOOTP))
        rtems_bsdnet_do_bootp,
#else
        NULL,
#endif
        8,                              /* Default network task priority */
        256 * 1024,                     /* Default mbuf capacity */
        256 * 1024,                     /* Default mbuf cluster capacity */
        "leo",                          /* Host name */
        "leo",                          /* Domain name */
        "192.168.10.1",                 /* Gateway */
        "192.168.10.1",                 /* Log host */
        {"192.168.10.1"  },             /* Name server(s) */
        {"192.168.10.1"  },             /* NTP server(s) */

        0,                      /* efficiency */
        0,                      /* udp TX buffer */
        0,                      /* udp RX buffer */
        0,                      /* tcp TX buffer */
        0,                      /* tcp RX buffer */
};


    经过上述设置之后就可以正确编译使用RTEMS 的网络例程了。文档中的Netdemo 例程实现了一个Telnet echo server 功能。也就是说,其它机器(客户端)只要执行telnet 命令与该运行该程序的机器(服务器)的24742 端口建立了连接,则任何在客户端机器键盘上键入的字符,都会被服务器接收并且回传给客户端。这样,在客户端机器键盘上按下