BMC开发之虚拟媒体vMedia框架
1. 基础知识
① 研究背景
a.基于之前的vMedia专题研究,已经对AMI LTS12.0 vMedia的实现逻辑以及数据拆分包流程有了较深层次的了解。
b.而LTS13.0在实现方式上进行了一些重要的调整:USB(iusb ->usbgadget) 数据内部转发(socket - > nbd)
② 对比知识点
在ASPEED BMC芯片linux平台中,对芯片支持的两个USB2.0端口,端口A:既可以作为主机端也可以作为设备端, 端口B仅可以当作主机端
AST2500支持5个子设备包括15个端点,设备驱动实现在usb1_hw
AST2600相对于AST2500最多支持7个下游设备一共21个端点
iusb:USB虚拟设备接口,对SCSI进行了封装
usbe:实现USB协议设备端部分,对USB device IC接口做了封装
usb1_hw:提供USB device控制器硬件接口
2. LTS13.0架构vMedia框图
1.前端与BMC之前的跨机通信不变,仍然是以WebSocket方式实现
2.Lighttpd插件内创建了NBD-Server以及NBD-Client线程,实现前端与HOST之间的联通
3.NBD-Client作为HOST端的代理,通过usbgadget进行数据的转发
逻辑框图如下图所示:
3. 代码梳理
- H5Viewer与lighttpd建立Websocket连接:WebSockCtx[Instance].sockfd
- Lighttpd与cdserver建立socket连接:WebSockCtx[Instance].targetfd
- 创建数据转发线程:WebSocketProxy()
4. 转发线程接收到SCSI=0x25(Read Capacity):nbd_init()
–创建nbd-server线程:NBD_CTX.c_fd
–创建nbd-client线程: NBD_CTX.s_fd
- 同时创建mod_ChildID线程:WebSCSIHndlr()
- 子线程中进行usbgadget与nbd设备的绑定:cdrom_start() | lun.x/file = /dev/nbdx
- 与前端H5Viewer建联成功后:vmedia_cd_connect()
#使能UDC控制器
#cd /sys/kernel/config/usb_gadget/cdrom
#echo 1e6a0000.usb-vhub:p2 >UDC
7. 至此,整个数据通路建立成功: (控制命令和数据对应两条通路如下图所示)
–子线程接收Host端的USB_REQ: nbd_read_req(ctx),并转发至H5Viewer{sendSCSICmd(&req)}
–插件线程接收H5Viewer的镜像数据封装成nbd块数据并发送:nbd_write_res()
8. 总结,总体流图如下所示
4. 知识进阶 – NBD Client&Server In BMC
如下图所示:
1.nbd-server和nbd-client均运行在BMC内部,分别充当H5Viewer与Host的代理
2.nbd-server和nbd-client之间通过UDS通讯,接近与内存传输速率
3.USB请求包:Host通过nbd-client传送到nbd-server,然后,mod_child子线程读取后,发送给H5Viewer
4.USB响应数据:H5Viewer将镜像数据通过WebSocket发送给插件主线程,然后通过nbd-server发送到nbd-client,进而通过usb最终发送到Host
思考:
这里nbd-client其实是可以放在Host端运行的,但这样就略过了usb,选用了网路传输方式,有如下缺点:
1.网路传输方式容易受网路环境影响,稳定性会差一点
2.需要Host端有相应的驱动配合,适配性和通用性会差一点(你不能要求为了用这个功能,客户需要在OS装一些服务)
5. 知识进阶 – usbgadget与nbd是如何关联起来的?
- 我们在BMC上进行的usbgadget的相关配置,均是为了将CDROM或者HDDISK模拟成一个USB Mass Storage设备
- 将NBD-Sever上的数据块以文件的形式保存在虚拟磁盘中,lun.0/file=/dev/nbd0
- 然后通过usbgadget框架将这个虚拟磁盘挂载到Host上,映射后的设备为/dev/srx或者/dev/sdx
- 因为BMC端模拟的USB Mass Storage是连接在USB总线上的,且Host无法区分真实还是模拟的,因此,当Host扫描到该设备时,会将其当作真实的设备使用。
- 在整个过程中,nbd-client通过GadgetFS与BMC进行通讯,而BMC则通过usbgadget驱动将请求转发到nbd-server。nbd-server和nbd-client之间的通讯则是通过UDS协议完成的。
- 对于 USB Gadget 驱动,它将本地 USB 接口的访问接口暴露给连接到设备的主机端,主机可以通过 USB 接口来访问设备。USB Gadget 驱动将本地 USB 接口的数据封装在 USB 协议帧中,通过 USB 接口传输给主机。在主机接收到数据后,将数据解封装并进行处理,然后将响应数据封装成 USB 协议帧,并通过 USB 接口返回给设备。
最后,我这里以Host的视角梳理整个通讯逻辑:
Step1:在OS上,打开/dev/sdx设备并读取数据,读取请求会通过usb被nbd-client捕获
Step2:nbd-client将读取请求发送到BMC上的nbd-server
Step3:nbd-server将请求转发至前端,前端从镜像数据中读取请求的数据并返回给nbd-server
Step4:nbd-server将数据发送回nbd-client
Step5:nbd-client将数据通过USB返回给OS
因此,通过usbgadget、nbd-client和nbd-server,可以实现将前端镜像数据映射到OS中,使得OS可以访问和操作前端镜像数据。