块设备、网络设备以及TPM(Trusted Platform Module可信平台模块)的xen驱动都是可分离的驱动,都在特权操作系统的一部分来处理从物理设备-->后端- ->非特权操作系统的前端,就像后端设备的一个代理。后端驱动与前端驱动通过在这个架构中成为xenbus的共享事件通道和缓存区进行通信。
具体来说,这一节讨论块设备驱动与网络设备驱动的区别是特别的必要。块设备在不同的地方用到了不同的缩写“blk”或者“vbd”。也会涉及 到特权域即dom0和非特权域domU。
基本的架构是由四个部分组成的一个链,一对设备通过Xenbus通信,然后一对设备使用这个总线处理特定设备与内核设备层的交互。
priv. unpriv. domain Xenbus interdomain Xenbus domain kernel -- blkback -- backend -------------- frontend -- blkfront -- kernel device instance instance interconnect instance instance device layer layer 为了创建贯穿整个链条的通信,需要大量的参数在dom0和domU之间传递,同样,在blkback/blkfront之间也需要很多的参数传递。这些参数通过xen stroe进行传递。
设备初始化
Xend通过向xenstore写fontend和backend的信息来创建一个设备连接。xenbus的设备实例可以看到这些信息,并开始初始化。
/local/domain/0/backend/vbd/U/<deviceID>/... frontend /local/domain/U/device/vbd/<deviceID> frontend-id U state XenbusStateInitialising ... <device-specific details> /local/domain/U/device/vbd/<deviceID>/... backend /local/domain/0/backend/vbd/U/<deviceID> backend-id 0 state XenbusStateInitialising ... <device-specific details> xenbus的后端实例监视着/local/domain/0/backend/vbd,前端实例监视着/local/domain/U/device/vbd。当设备的内容被写到了这两个位置后,这两个监视的相关事件被触发, xenbus的实例开始初始化。 后端读取前端和前端ID的对应节点的信息,然后设置一个监视函数到对应状态信息(也就是xenstore的对应设备的state字段)。 前段也一样读取后端和后端ID的对应节点的信息,然后设置一个监视函数到对应状态信息(也就是xenstore的对应设备的state字段)。 这两个监视函数在xenbus_probe:read_otherend_details中对称的设置还有一些可参考的信息xenbus_device.otherend, xenbus_device.otherend_id, and xenbus_device.otherend_watch这三个结构中。 通过调用blkfront/blkback的引导函数可以触发初始化过程,为了能够演示特定设备的初始化,和当初始化完成时各个设备转换到不同的状态,blkback在xenstore中创建一个监视 器等待处理热插拔设备的脚本的结束,然后转换到XenbusStateInitWait 状态,blkfront为前段创建出与backend共享的一个缓存和事件通道,然后转换状态为Connected状态。 当blkfront发现已经切换到Connected状态后,然后可以读取物理设备信息,连接内核设备层,同时将自己的状态也设置为Connected。 事件机制图: Xenbus Xenbus Hotplug Backend Frontend ------- ------- -------- Initialising Initialising | | |<---start----+ | | | | | InitWait | | | write | | ring/ write | channel physdets-------->| details | | |<---------------------Initialised | | write | physdets | | | Connected---------------------->| | | | Connected | | 网络驱动的前段不需要等待后端的信息,而可以直接调到Connected状态。 设备关闭 设备关闭可以有用户发起,如果热插拔设备驱动发生错误热插拔设备会请求xend或者其他工具来关闭设备。 通过改变后端设备状态为Closing完成关闭操作。这回触发前端丢弃他的内核联系(kernel connection),刷新没有被应答的请求,然后改变状态为Close,后端会 通过撤销自己并改变为closed状态来通知前段也改变为Closed。前段也可以不需要后端状态先变为Closing而因为错误立即断开设备。 Xenbus Xenbus Hotplug Backend Frontend ------- ------- -------- (Written by control | tools, e.g. Xend, | or by backend on | error) | | | Closing-------------------->Closing | | | | | flush | | | | Closed<--------------------Closed | | |<--------unregister | | device | | | | remove store directories | 或者通过以下模型 Xenbus Xenbus Hotplug Backend Frontend ------- ------- -------- | (Written by frontend | on error) | | Closing<--------------------Closing | +----------------------->| | | | flush | | | | Closed<--------------------Closed | | <---------unregister | | device | | | | remove store directories | 迁移 迁移与关闭时不同的,迁移过程中前端驱动与内核设备层的关系没有影响,仅仅是Xenbus的连接断掉了。当这样的disconnedted发生,驱动会得到一个底层的调用。继而会读取到 新的后端信息和建立新的监视程序。 设备重新配置 如果需要前段后端之间的实时重新配置,这会由在xen-stroe中的监视程序处理,整个过程中驱动始终为Connected状态。
d状态。