我正在尝试将原始数据写入连接到我的计算机的 USB 设备。我使用的是 Kali Linux,并且找到了正确的文件路径: "/dev/usb/003/013" 。但是,当我尝试向其中写入数据时,出现错误。
root@kali:~/usb# printf "test" > /dev/bus/usb/003/013
bash: printf: write error: Invalid argument
我也尝试过使用猫:
root@kali:~/usb# cat test > /dev/bus/usb/003/013
cat: write error: Invalid argument
在前一种情况下,文件“test”确实存在并且其中包含数据。系统似乎无法写入文件描述符,即使它在那里。
经过研究,我得出的结论是:
A. 需要一个与设备连接的 USB 驱动程序。
B. 使用 SCSI 直通将数据直接写入设备上的端点。
我是 USB 编程的新手,虽然我很愿意尝试,但我以前从未编写过驱动程序。任何建议或帮助将不胜感激。
是否可以像我最初尝试的那样将原始数据写入设备?如果没有,您能解释一下我可以使用的一些选项吗?
答案1
USB 设备比简单的读写管道复杂得多。您必须编写代码来操作它们。您(可能)不需要编写内核驱动程序。看http://libusb.info(née libusb.org)和http://libusb.sourceforge.net/api-1.0。它声称可以与 Linux、OSX、Windows、Android、OpenBSD 等一起使用。在 Mac OS X 下,有用户级函数输入/输出套件这将让您访问 USB。在Windows下,您也许可以使用WinUSB,但它很复杂。
这是我曾经画过的一个小图,用来帮助我理解 USB 的架构:
╭────────────────────────────────────╮
┌──────┐ │ device ┌─────┐ ┌─────────┐ │
│ Port ├──┐ │ ┌─┤ EP0 ├──┤ control │ │
└──────┘ │ │ ┌────────┐ │ └─────┘ ├─────────┤ │
├────┤addr = 2├─┤ ┌─────┐ │ │ │
│ │ └────────┘ ├─┤ EP1 ├──┤interface│ │
│ │ │ └─────┘ │ #0 │ │
│ │ │ ┌─────┐ ├─────────┤ │
│ │ ├─┤ EP2 ├──┤ │ │
│ │ │ └─────┘ │interface│ │
│ │ │ ┌─────┐ │ #1 │ │
│ │ └─┤ EP3 ├──┤ │ │
│ │ └─────┘ └─────────┘ │
│ ╰────────────────────────────────────╯
│
│
:
执行摘要:每个设备都有一个地址(由操作系统分配并可能会更改),以及最多(我认为)32 个端点。
设备内有一个或多个“接口”。例如,网络摄像头可能提供“相机”接口和“麦克风”接口。多功能打印机将提供多个接口。
端点0用于设备的控制和配置,其他端点用于访问各种接口。每个接口都有零个或多个(通常更多)端点。
端点可以是以下几种传输类型之一:
- 控制传输用于查询和配置设备。每个设备都需要支持最少的控制语句集。我相信控制传输仅用于端点 0。
- 批量传输以全带宽发送或接收数据
- 中断传输(我不太确定这与批量传输有何不同;USB 没有中断)。示例包括键盘和鼠标
- 等时传输以全带宽发送或接收数据,具有实时性要求,但缺乏可靠性。用于音频/视频应用。
另外值得注意的是:USB 设备可以有多种配置,这些配置控制可用的接口等等。更改设备配置几乎就像拔掉设备插头并在其位置插入不同的设备。
所有这些信息都放在设备描述符、配置描述符、接口描述符、端点描述符等中,可以通过端点零查询。
(在内部,数据不是字节流,它被打包成数据包,其确切格式是 USB 规范的一部分。在大多数情况下,您无需担心这一点,因为控制器和驱动程序将管理这部分你。)
在实践中,根据您的 API 库和操作系统,您需要检测设备,读取各种描述符以找出您正在处理的内容,可选择设置其配置(如果操作系统允许),打开界面,并打开端点。
对于批量端点,您可以向其中读取和写入原始数据。对于控制传输,API库将提供函数调用。我从未使用过中断或同步传输;我确信您的 API 库会有相关文档。
更多信息:“函数”是协同工作的接口的集合。它最初并不是 USB 规范的一部分,由设备驱动程序决定哪些接口应该分组在一起。 USB 工作组定义了支持功能的设备类。这是通过接口关联描述符 (IAD) 完成的。