You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

内核模块自动读取USB内容异常:仅获36字节设备名称求助

内核模块读取USB文件数据问题解决方案
  • 你当前用URB只能拿到36字节设备描述符数据,是因为URB操作的是USB总线原始通信数据,而非文件系统层面的文件内容。内核层直接处理USB大容量存储的文件,必须走块设备+VFS文件系统的路径,而非直接读取URB。

核心解决步骤:

  1. 过滤USB大容量存储设备
    在USB插入事件的notifier回调中,通过usb_interface结构体判断设备类型:

    struct usb_interface *intf = to_usb_interface(dev);
    if (intf->cur_altsetting->desc.bInterfaceClass != 0x08) {
        // 不是大容量存储设备,直接返回
        return NOTIFY_DONE;
    }
    

    0x08是USB大容量存储设备的接口类标识,只有这类设备才需要后续处理。

  2. 获取块设备节点并挂载文件系统
    USB大容量存储设备会被识别为块设备(如/dev/sdb),其分区(如/dev/sdb1)需要挂载到内核可访问的路径:

    struct vfsmount *mnt;
    struct path path;
    int ret;
    
    // 挂载分区,以vfat为例,需根据实际文件系统调整
    mnt = vfs_kern_mount(&fat_fs_type, 0, "/dev/sdb1", NULL);
    if (IS_ERR(mnt)) {
        pr_err("Mount failed\n");
        return PTR_ERR(mnt);
    }
    path.mnt = mnt;
    path.dentry = mnt->mnt_root;
    

    注意:需提前导入对应文件系统的驱动(如CONFIG_FAT_FS),且内核版本不同,vfs_kern_mount的参数可能有差异,需适配Ubuntu 23.10的内核版本。

  3. 通过VFS接口读取文件
    挂载完成后,使用内核VFS接口操作文件,这才是获取实际文件数据的正确方式:

    struct file *file;
    char buf[4096];
    loff_t pos = 0;
    ssize_t read_len;
    
    file = filp_open("/mnt/usb/test.txt", O_RDONLY, 0);
    if (IS_ERR(file)) {
        pr_err("Open file failed\n");
        goto unmount;
    }
    
    // 切换地址空间,避免内核/用户空间访问冲突
    mm_segment_t old_fs = get_fs();
    set_fs(KERNEL_DS);
    
    read_len = vfs_read(file, buf, sizeof(buf), &pos);
    if (read_len > 0) {
        pr_info("Read %zd bytes: %s\n", read_len, buf);
        // 这里可以添加文件复制逻辑
    }
    
    set_fs(old_fs);
    filp_close(file, NULL);
    
    

unmount:
vfs_kern_unmount(mnt, 0);

### 关键注意事项
- 内核层操作VFS必须严格管理资源,所有打开的文件、挂载点都要正确释放,否则会导致内存泄漏或系统崩溃。
- Ubuntu 23.10内核版本较高,部分旧API已废弃,需参考对应内核版本的官方文档调整代码。
- 该操作仅适合学习实验,生产环境绝对禁止在内核层处理文件复制逻辑。

内容的提问来源于stack exchange,提问作者W. N
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 15:52:20