导航:首页 > 操作系统 > linux虚拟接口

linux虚拟接口

发布时间:2022-09-18 04:30:26

Ⅰ 求教,linux下网口虚拟串口驱动程序

开发虚拟串口驱动程序

虚拟串口就是当本地并没有对应的串口硬件设备,而为应用层提供串口设备一样的系统调用接口,以兼容原本使用本地串口的应用软件的“虚”设备。本文作者给出了一种在Windows平台上实现虚拟串口的方法,由此实现的“串口”具有真实串口完全相同的系统调用接口。
在很多应用中需要用到虚拟串口,如在Modem卡出现之前,已经有了接在计算机串口上的外部Modem,而且各种拔号程序也是通过串口与外部Modem通信的。为了让已有的拔号程序不做修改,像使用外部Modem一样使用内置卡,就需要内置卡的驱动程序虚拟一个串口设备。又如当前工业界使用的一些串口服务器,往往有8个或16个甚至更多的串口,以连接多个串口设备,再通过一个网卡直接连入以太网。与它在同一网络上的计算机就通过以太网与串口服务器上挂接的串口设备通信。为了让计算机中原来使用本地串口的软件兼容,就需要在计算机上提供虚拟串口驱动。
虚拟串口的设计关键在于,该“串口”实现后必须具有与真实串口完全相同的系统调用接口。要做到这点,从已有的串口设备驱动程序上做修改是最佳捷径。下文就介绍以Windows NT上的串口驱动程序为基础,开发可运行于Windows NT、Windows 2000、Windows XP的各个版本虚拟串口驱动程序。
串口驱动中使用的几个链表
由于串口是双工设备,在一个读请求发出来还没有完成之前,同时可以发出写请求,加上在驱动程序层所有I/O请求都要求异步完成,即前一个请求尚没有完成,下一个相同的请求可能又来了。为此,串口驱动程序需要使用多个双向链表数据结构来处理各种IRP(I/O Request Packet,I/O请求包)。当收到一个IRP,先判断是否可立即完成,可以马上处理并返回,如果不允许则将IRP插在相应链表尾,在适当的时候如设备有空闲时处理,这时往往会产生一个硬件中断,激发DPC(Deferred Procere Call,暂缓过程调用)过程,由DPC处理函数逐个从链表头取出IRP并试着完成它。串口驱动中有以下几个链表和DPC(在serial.h中有定义):
ReadQueue 和 CompleteReadDpc
用于保存Read IRP的链表和用于调度的DPC,与DPC对应的处理函数是SerialCompleteRead,它在read.c文件中,该函数的主要任务就是从ReadQueue中提取下一个IRP,并试着完成它。
WriteQueue 和 CompleteWriteDpc
用于保存Write IRP的链表和对应的DPC,与DPC对应的函数是SeriaCompleteWrite,它的实现在write.c中,该函数负责从WriteQueue中提取IRP,并试着完成它。
MaskQueue 和 CommWaitDpc
这一对链表用于处理Windows串口驱动的一个特性:事件驱动机制。它允许应用程序预设一个事件标志,而后等待与标志对应事件发生。DPC所调用的函数是SerialCompleteWait,它实现在Waitmask.c文件中,该函数也是试着从MaskQueue中提取IRP并完成它。
PurgeQueue
该链表与前面几个稍有不同,它没有与之相对应的DPC机制,而是在每次收到Purge请求时从PurgeQueue中逐个提取IRP并试着完成,因某种原因不能完成时则插入链表。相应的函数是purge.c文件中的SerialStartPurge。
以上机制是串口驱动程序的重要实现方法,在虚拟串口驱动中需要保留,但不同的是,硬件串口驱动中是ISR(中断服务程序)根据收、发或MODEM中断来激发相应的DPC,而在虚拟串口驱动中将因实际情况不同会有不同的激发机制。
DriverEntry的实现
DriverEntry是驱动程序的入口函数,相当于应用程序C语言中的main函数,开发一个虚拟串口驱动首先要修改的就是它。它的函数实体在initunlo.c文件中。只是在虚拟串口驱动中由于不与具体的硬件打交道,就不存在硬件资源分析、硬件初始化、判断其工作状态等处理,只需要为虚拟串建立设备对象、符号链接和初始化数据结构。一个典型函数实现大体如下:
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
/*填写DriverObject->MajorFunction[]数组*/
/*建立设备对象*/
/*初始化SERIAL_DEVCIE_EXETENSION数据结构*/
Status = IoCreateDevice(DriverObject, sizeof(SERIAL_DEVICE_EXTENSION), &uniNameString, FILE_DEVICE_SERIAL_PORT, 0,TRUE,&deviceObject);
//初始化所有链表
InitializeListHead(&extension->ReadQueue);
InitializeListHead(…);
…;
//初始化所有DPC
KeInitializeDpc(&extension->CompleteReadDpc,SerailCompleteRead,extension);
KeInitializeDpc(…);
/*建立符号链接*/
SerialSetupExternalNaming(extension);
return Status;
}
SerialRead和SerialCompleteRead的实现
函数SerailRead和SerialCompleteRead决定了对Read IRP的响应策略,它们都存于read.c中。以串口服务器要用的虚拟串口为例,当串口服务器收到来自外部数据时将通过网络发至计算机,计算机则产生相应的网络中断并进行协议数据处理。网络接收线程缓存新收到的数据并激活CompleteReadDpc,从而SerialCompleteReadIrp得到调用,它再调用CompleteReadIrp对每个IRP进行处理。它们的实现大体如下:
NTSTATUS SerialRead(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
/*此处略去变量声明和初始化*/
/*提取IRP中相关的数据*/
stack = IoGetCurrentIrpStackLocation(Irp);
ReadLen = stack->Parameters.Read.Length;
/*先看本地缓冲有数据否?有的话先读取*/
if(Extension->InCounter > 0 )
{ //注意这里要加锁,以防数据访问冲突
KeAcquireSpinLock(&Extension->
ReadBufferLock,&lIrql);
FirstRead = (ReadLen>Extension->
InCounter)? Extension->InCounter: ReadLen;
RtlCopyMemory(Irp->AssociatedIrp.
SystemBuffer,Extension->pInBuffer,FirstRead);
Extension->InCounter -= FirstRead;
ReadLen -= FirstRead;
KeReleaseSpinLock(&Extension->
ReadBufferLock,lIrql);//释放锁
}
/*是否已读到足够数据?是的话则完成该IRP*/
if( 0 == ReadLen)
{
status=STATUS_SUCCESS;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = FirstRead;
IoCompleteRequest(Irp,0);
return status;
}
/*没有则将IRP插入队列中,通过网络向串口服务器发出读数据请求*/
IoMarkIrpPending(Irp);
InsertWaitList(Extension->ReadQueue,Irp);
status = TdiSendAsync(Extension->ComChannel,pAckPacket,PacketLen(pAckPacket),(PVOID)ReadAckComplete,Irp);
/*返回PENDING,表示该IRP尚没有完成*/
return STATUS_PENDING;
}
Void CompleteReadIrp(IN PSERIAL_DEVICE_EXTENSION extension,IN PIRP Irp,IN PUCHAR pInData,IN ULONG Length )
{
/*此处略去变量声明和初始化*/
/*读取新数据*/
ReadLen = (ReadLen > Length)? Length : ReadLen;
if(ReadLen != 0)
{
RtlCopyMemory(pReadAsync->
pReadBuffer,pInData,ReadLen);
pReadAsync->pReadBuffer += ReadLen;
pReadAsync->ReadAlready += ReadLen;
extension->PerfStats.ReceivedCount +=
ReadLen;
}
else
{
/*因为串口服务器端只有在已经有了相应的数据或超过时间(此时,Length=0)才会发来应答并激活本DPC过程,所以此时已经超时,为了便于结束本IRP,这里有意改变TotalNeedRead,造成接收完毕的假象*/
pReadAsync->TotalNeedRead =
pReadAsync->ReadAlready;
}
if(pReadAsync->TotalNeedRead == pReadAsync->ReadAlready)
{
/*该IRP是否已经接收完毕,是的话则结束该
IRP*/
EndReadIrp(Irp);
/*从ReadQueue中取下一个IRP*/
}
/*本IRP没有完成也没有超时,则继续等待本DPC下次被激活,注意此时要判断IRP是否被要求取消*/
}
SerialWrite和SerailCompleteWrite的实现
SerialWrite和SerailCompleteWrite决定了Write IRP的实现。在SerialWrite中调用了网络发送函数TdiSendAsync,当该发送完成后将激活CompleteWriteDpc,调度SerialCompleteWrite函数,而它主要就是取出当前的WriteIRP,设置已经发送的数据数量,调用CompleteWriteIrp做该IRP的进一步处理。它们大体如下:
NTSTATUS SerialWrite(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
/*此处略去变量声明和初始化*/
/*从IRP中提取有关数据*/
stack=IoGetCurrentIrpStackLocation(Irp);
SendLen = stack->Parameters.Write.Length;
/*为网络发送和异步操作分配缓冲,在CompleteWrite中全部数据发送完后释放*/
pWriteAsync = ExAllocatePool(NonPagedPool,
SendLen+PACKET_HEADER_LEN+sizeof(WRITE_ASYNC));
if(pWriteAsync == NULL)
{
//错误处理
}
//保存异步数据

//设置网络发送数据包
BuildDataPacket(pPacket,WRITE,(USHORT)SendLen,pWriteAsync->pWriteBuffer);
/*先将IRP暂时阻塞并插入队列,在CompleteWrite中完成*/
IoMarkIrpPending(Irp);
InsertWaitList(extension->WriteQueue, Irp);
/*将写请求和相关数据通过网络发向串口服务器,由它负责将数据传到具体串口设备*/
status = TdiSendAsync(Extension->ComChannel,pPacket,PacketLen(pPacket),(PVOID)CompleteWriteIrp,Irp);
//统计数据累加
Extension->PerfStats.TransmittedCount += SendLen;
return STATUS_PENDING;
}

NTSTATUS CompleteWriteIrp(IN PDEVICE_OBJECT deviceobject,IN PIRP pIrp,IN PVOID context)
{
/*此处略去变量声明和初始化*/
SendLen=pWriteAsync->TotalNeedWrite - pWriteAsync->WroteAlready;
if(SendLen == 0)//全部数据发送完毕
{
EndWaitWriteIrp(pWriteIrp,STATUS_SUCCESS,
pWriteAsync->WroteAlready,pWriteAsync);
//从WriteQueue中取下一个IRP;
}
else //发送剩余数据
{
if(pWriteIrp->Cancel)
{
//IRP被要求取消,完成WriteIrp
EndWaitWriteIrp(pWriteIrp,STATUS_CANCELLED,
pWriteAsync->WroteAlready,pWriteAsync);
return STATUS_CANCELED;
}
else
{
//再次设置网络数据包并发送
BuildDataPacket(…);
status = TdiSendAsync(…);
//统计数据累加
Extension->PerfStats.TransmittedCount +=
SendLen;
return STATUS_MORE_PROCESSING_REQUIRED;
}
}
}
其他几个接口函数的实现
除Read/Write外,SerialUnload、SerialCreateOpen、 SerialClose、SerialCleanup、SerailFlush等调用接口是硬件相关性比较弱的接口函数,基本不要修改,直接删除原来操作硬件的部分即可。复杂一点就是SerialIoControl,该接口函数包含有大量设置、读取串口硬件状态的处理,可建立一个本地数据结构随时保存虚拟串口的当前硬件状态。同时为了保证串口服务器端的真实串口状态和上层软件要求的一致,需要将所有设置请求通过网络发送到服务器端,由它负责改变真实硬件的状态。

Ⅱ 如何在虚拟机上运行linux系统

下载VMWare解压后根据提示正触安装VMWare到硬盘中
(1) 建立虚拟机

A.用鼠标左建双击桌面中的"VMware workstation"图标,运行虚拟机

B.建立一台虚拟机。点击“FILE(文件)”-“NEW(新建)”--“NewVirtual Machine(

新建虚拟机)”,弹出虚拟机创建菜单。

C.根据向导一步一步地创建虚拟机,首先选择安装方式是“TYPICAL(典型)”还是

“CUSTOM(自定义)”安装。 我这里选择典型。

D.因为这里是用于安装REDHAT,所以在Guest operating system(客户操作系统)“

中选择”LINUX“,点击下一步。

E.在Virtual machine name(虚拟机名字)中输入你想建立的虚拟机的名字

F.在Location(位置)中选择虚拟机的安装位置。因为会在虚拟机中安装操作系统

和应用软件,所以建议将虚拟机安装在一个有较大空间的磁盘分区中

G.如果你的电脑连接在网络中,那么选择一个合适的网络环境。我这里选择

Use bridged net-working(使用路由网络)

H.点击finish,返回VMWARE主界面,LINUX虚拟机就建好了。

2. 安装操作系统

A. 选中LINUX虚拟机,点击VMWARE工具栏中的Power ON按钮,启动LINUX虚拟机

B.然后插入REDHAT7.3光盘,虚拟系统根据你选择的安装方式开始安装。

3.从硬盘安装REDHAT7.3

如果你认为从光驱中安装比较费时间,又不方便,那你可以将光盘文件转换成ISO文件拷

贝在硬盘中,然后从硬盘安装。

A.点击Settings(设置)--Configuration Editor(编辑配置)进入设置界面对虚拟机进行

配置。

B.在Hardware(硬件)选项中,选择DVD/CD--ROM[IDE 1:0]项,在左边的选项中进行设置。

C.在Connection(连接)选项选中Use ISO image(使用ISO镜像包),然后点击Browse(预览)

按钮,找到放置ISO文件的目录。

D.在打开对话框中选择RedHat.ISO文件,然后点击打开,将ISO文件打开(如果第一个ISO

文件安装完后,计算机提示你插入第二张光盘,则在此选择RedHat.ISO,如此类推)

E.在Virtual device mode(虚拟设备模式)选择虚拟设备的接口方式,选择IDEO:0项

然后点击OK返回到虚拟机界面下,点击Power ON就可以直接从硬盘安装操作系统了

Ⅲ 求救!colinux安装之后虚拟网卡的本地连接总是网络电缆没有插好,怎么解决

上网的时候提示网络电缆没有插好,通常是由于网卡没有插好或网卡驱动程序存在问题等情况导致,建议重新插入网卡或重新安装驱动程序再试,同时留意网线和网卡接口是否正常,可换一根网线尝试。
另外,如果是网卡工作模式存在问题,也会影响使用,可找到电脑“我的电脑”图标,右键点击,选择“管理-设备管理器-点到网络适配器”,找到网卡,然后右键点击网卡,在“属性---高级--mediatype或者链接速度”,把网卡的工作模式设定外10m半双工即可。

Ⅳ 虚拟网络接口怎么设置 我在一台计算机上面安装了linux操作系统 然后安装了 虚拟机但是虚拟机不能上网

虚拟机选择NAT或者BRIGE,然后在linux中定义一下网卡,NAT选择dhcp获取,BRIGE选择固定IP-------以上要根据你实际上网方式选择。
然后重启linux下的network服务或重启网卡,一般就能上网了

Ⅳ 如何将linux虚拟机和主机之间连接 详细�0�3

将Linux虚拟机连接到主机的方法如下:

1、打开计算机中的虚拟机软件,然后打开Linux系统。

Ⅵ linux系统中,有关网络服务接口,是什么定义的

(1)网络接口的命名
这里并不存在一定的命名规范,但网络接口名字的定义一般都是要有意义的。例如:
eth0:
ethernet的简写,一般用于以太网接口。
wifi0:wifi是无线局域网,因此wifi0一般指无线网络接口。
ath0:
Atheros的简写,一般指Atheros芯片所包含的无线网络接口。
lo:
local的简写,一般指本地环回接口。
(2)网络接口如何工作
网络接口是用来发送和接受数据包的基本设备。
系统中的所有网络接口组成一个链状结构,应用层程序使用时按名称调用。
每个网络接口在linux系统中对应于一个struct
net_device结构体,包含name,mac,mask,mtu…信息。
每个硬件网卡(一个MAC)对应一个网络接口,其工作完全由相应的驱动程序控制。
(3)虚拟网络接口
虚拟网络接口的应用范围非常广泛。最着名的当属“lo”了,基本上每个linux系统都有这个接口。
虚拟网络接口并不真实地从外界接收和发送数据包,而是在系统内部接收和发送数据包,因此虚拟网络接口不需要驱动程序。
虚拟网络接口和真实存在的网络接口在使用上是一致的。
(4)网络接口的创建
硬件网卡的网络接口由驱动程序创建。而虚拟的网络接口由系统创建或通过应用层程序创建。
驱动中创建网络接口的函数是:register_netdev(struct
net_device
*)或者register_netdevice(struct
net_device
*)。
这两个函数的区别是:register_netdev(…)会自动生成以”eth”作为打头名称的接口,而register_netdevice(…)需要提前指定接口名称.事实上,register_netdev(…)也是通过调用register_netdevice(…)实现的。
2、LINUX中的lo(回环接口)
1)
什么是LO接口?
在LINUX系统中,除了网络接口eth0,还可以有别的接口,比如lo(本地环路接口)。
2)
LO接口的作用是什么?
假如包是由一个本地进程为另一个本地进程产生的,
它们将通过外出链的’lo’接口,然后返回进入链的’lo’接口.具体参考包过滤器的相关内容。
PART2
实验:
本地一个进程发起连接,到一个本地的daemon监听的内网IP地址(eth1:
10.1.1.1)的端口(8085),此时在eth1上是抓不到包的,在
lo
上抓到,说明使用的是本地回环接口lo,而网络层的IP地址则是内网IP地址.

Ⅶ VirtualBox Linux虚拟机 怎么配置vlan

virtualBox虚拟机上安装linux系统,如何在两个虚拟接口上配置网络

环境:
1.VirtualBox虚拟机,Ubuntu 64位系统,虚拟机网卡设置为:
网1用于管理linux系统,与本地主机为桥接关系,网卡2用于与另一个虚拟pc机相连,网卡3用桥接模式与本地主机连接
2.其配置方法为:
进入目录:cd etc/sysconfig/network-scripts
其下创建ifcfg-eth0,ifcfg-eth1,ifcfg-eth2
ifcfg-eth0文件内容为:
DEVICE="eth0"
HWADDR="08:00:27:FA:85:8B"
NM_CONTROLLED="yes"
ONBOOT="yes"
#BOOTPROTO="dhcp"
IPADDR=10.60.52.42 //我的本地主机ip为10.60.52.52,需在同一个局域网中;
PREFIX=16
GATEWAY=10.60.10.252//这是我的网关
DNS1=8.8.8.8
DEFROUTE=yes
ifcfg-eth1文件内容为:
DEVICE="eth1"
HWADDR="08:00:27:71:DC:D5"
NM_CONTROLLED="yes"
ONBOOT="yes"
ifcfg-eth2文件内容为:
DEVICE="eth2"
HWADDR="08:00:27:62:F3:88"
NM_CONTROLLED="yes"
ONBOOT="yes"
3.创建另一个虚拟pc机,系统为win7系统,创建成功后,为其分配ip地址
10.60.52.49,,默认网关为:10.60.10.252
win7pc的网卡设置信息为:上图网卡2所示
4.搭建虚拟防火墙
配置两个接口,将两个接口放入vlan 1中,然后两个接口就可以通信了

Ⅷ Linux中,创建一个网卡的子接口和配置一个虚拟网卡是一个意思吗

对的
第一块网卡的 子接口 可以是eht0:1 可以将第一块网卡的配置文件复制一下 重命名 但是 文件里的设备名 不能一样 要不然 会出错的

Ⅸ linux虚拟机 xshell端口怎么设置

1 打开虚拟机,设置linux虚拟机为 仅主机 模式。
2 编辑linux的网卡配置文件 /etc/sysconfig/network-scripts/ifcfg-eth0(redhat6和7版本配置文件不一样,以6为例)
3 为虚拟机配置一个ip(ip不做固定要求)(注意重启网卡服务:service network restart)

1 打开真实机的网络配置
2 找到vmnet1的连接,右键-属性
3 双击 版本协议4 (tcp/ipv4)
4 设置静态ip地址 ,地址要和虚拟机的ip地址为同一网段

1 打开xshell客户端
2 右上角 文件-新建
3 主机栏里填入linux虚拟机的ip地址,其他按需求填写
4 右上角 文件-打开-选择我们创建的会话。点击 连接 。

1 等待弹出对话框,用户名中填入linux虚拟机中创建的用户(可以选保存用户名,方便下次使用) 点击 确定
2 在密码栏里输入你选择用户的密码(同样可以选择保存)
3 点击确定,等待连接。

5
也可以通过命令连接:ssh (要连接的虚拟机ip地址)

阅读全文

与linux虚拟接口相关的资料

热点内容
编译iso 浏览:940
照片生成pdf格式 浏览:194
病历转pdf 浏览:835
云服务器配硬件 浏览:978
服务器10k什么意思 浏览:21
pdfeditor汉化 浏览:884
新科学pdf 浏览:746
现在还有c语言编译吗 浏览:674
哪里买到单片机 浏览:480
linux文件打开数量 浏览:510
编译原理中什么是l属性文法 浏览:371
硬盘加密时出现的问题 浏览:61
如何退域命令 浏览:108
看书的app哪里看 浏览:291
服务器怎么调大 浏览:3
android天气apijson 浏览:984
为什么创建id会出现服务器错误 浏览:837
代码中有不必编译的单词吗 浏览:563
钩子与数据库编程 浏览:563
安卓光遇录歌怎么设置 浏览:485