事情是这样的,一开始是随便看的 Intel Atom Z3735F,后面咸鱼推给我一个 Wyse 3040,不是一个 U,是个 Z8350,2G 内存,8G 存储,然后突然注意到,这玩意供电是 5V !这不就可以从主板插的 ATX 电源的 5Vsb 偷电吗?然后开始就去查这 CPU 的资料,结果搜到了一份 datasheet,看到上面写着居然支持 USB3.0 OTG,就开始猛猛逛咸鱼,结果又冒出一个东西截胡,这玩意是 HP T240,配置一样,似乎还便宜点,然后我就一时冲动买了。
理论支持
首先,得确定这玩意真能跑 OTG 好吧,然后还是在那份 datasheet 里面,看到 USB 部分,有个 USB_OTG_ID 的针脚,心想,这下稳了,这机器百分百有个 USB OTG 功能,然后就是看看在 x86 环境下有没有人搞过 OTG,然后就发现有个哥们干得比我还猛,他是直接把两个 thinkpad 连起来了,这个也是我后续的一个重要的操作指导。
机器开箱
就一个瘦客户机加一个欧陆通的电源,不确定是不是后配的电源。
机器正面有极为先进的 3.5mm 耳机和麦克风接口,一个 USB3.0 接口,一个 USB2.0 接口,还有一个电源按钮。
机器后面有一个 5.5mm 圆头的电源接口,一个千兆网口,一个 VGA 接口,一个 HDMI 接口和两个 USB2.0 接口,以及还有一个你永远不用用上的肯斯顿锁孔。
底部是两个脚垫还有一个 VESA 100mm 的安装支架,对的,完整是 4 个脚垫,但是支架的安装方式是拆掉两个脚垫露出螺丝孔固定的,所以只剩下两个脚垫了。
根据 SN 号信息查询,显示还有 8 个月的保修期,真是意外之喜,但好像又没有什么用。
上电后是进入到自带的 ThinPro 系统,很可惜我没有做任何备份就直接覆盖了它,我后面试图自己重新安装这个系统,但好像没找到正确的安装方式,所以这里没有仔细评测这个系统了。
系统安装
拿个 U 盘,直接用 Rufus 刷入 Debian 12 的 ISO 镜像,插上机器,开机按 F9 选择 U 盘启动,直接安装就行了。
真那么简单吗?只是到这里是的,但是后面就不那么简单了。
找到支持 OTG 的 USB 口
我不是很确定这块的接口是不是默认有的,你可以先 ls /sys/class/usb_role/
看看有没有 intel_xhci_usb_sw-role-switch
这个文件夹,如果没有,可能要到后面 BIOS 里面改选项后才能看到了。
我们把那个 USB OTG 接口的模式改成 device 模式,命令如下
1 | echo device > /sys/class/usb_role/intel_xhci_usb_sw-role-switch/role |
如果你想要切回 host 模式的命令是
1 | echo host > /sys/class/usb_role/intel_xhci_usb_sw-role-switch/role |
在 device 模式下,我们拿个 U 盘怼上去,然后 lsusb
看看有没有显示出来,那个口就是我们要找的 OTG 口了。
修改 BIOS 隐藏选项
进去系统之后,我们 ls /sys/class/
可以看到设备上的设备类型,但是,偏偏没有 udc
,这个 udc
是什么东西呢?是 USB Device Controller 的缩写,有这个你才有机会跑 OTG。
但我们前面已经提到这个 CPU 明明是支持 OTG 的,为什么没有呢?根据文章提示,要去 BIOS 里面改选项,然而,,,这个 HP 的 BIOS 似乎被极端精简了,很多选项都消失了,也完全没看到与 USB OTG 相关的选项,什么 OTG Support
什么 xDCI
通通没有。
这时候有些人可能就放弃,但我想了想,要不试试干 BIOS,反正别人也试着干了,于是我就去 hp 的支持页面找 BIOS,幸好,恰巧有一个 BIOS 下载,于是我就拉了下来,然后尝试了一下刷 BIOS,你猜怎么着,刷不上!(乐
不过,既然都下载下来了,也不是完全没有研究价值,至少先看看能不能有没有相关的选项好吧。
我们请出了 UEFITool , IFRExtractor-RS , UEFI-Editor 还有 AMIBCP 试图修改 BIOS,经过一番翻找啊,他确实有那么一堆隐藏选项,但是不知道怎么解锁,其中有一项叫做 USB OTG Support
这似乎有戏,但又没戏,毕竟你还得小心人家 BIOS 有什么签名验证之类的。
最后我还是放弃了,毕竟我没这个能耐,我也不想把它搞坏。
翻了翻几个工具的文档,发现 UEFI-Editor 底下的文档里面有一项 How to change hidden settings without flashing a modded BIOS
哦吼,翻译过来就是 如何在不刷修改过的BIOS的情况下修改隐藏设置
,(后面翻看开头那位 thinkpad 互联大佬也是走的这招),这不正合我意,反正主板上的 BIOS 和我现在下载到的这个 BIOS 是一样的也不是不行嘛。
首先前提是你的 BIOS 得是 AMI 家的出品或者变种,如果不是的话,你就没戏了。
首先是到 UEFITool NE 这里下载一个最新的 UEFITool_NE_A**_win64.zip
如果没看到这个文件,你需要点一下 show all ** assets
,这里星号代表任意数字,请仔细注意名字,如果你是其他系统,可以把 win64 换成相应的,但一般是 win64,下载解压后,我们得到一个 UEFITool.exe
的文件,我们打开,把前面拿到的 BIOS 文件拽进去,按下Ctrl+F
选 Text 输入above 4g
搜索。
然后可能有多个结果,双击点开,大概应该都是指向同一块的且是在Setup
底下的
我这里是 Setup/LzmaCustomDecomprressGuid/PE32 image section
。
对着PE32 image section
右键,选择 Extract as is
,得到一个文件 Section_PE32_image_Setup_Setup.sct
。
然后我们再掏出另一个工具 IFRExtractor-RS,我们选择ifrextractor_1.6.0_win32.zip
下载,其他操作系统的自行选择合适的,解压后得到ifrextractor.exe
。
(此处我偷了两步可能用不到结果的步骤)
我们在ifrextractor.exe
所在文件夹按住 shift+右键,选择在此处打开 Powershell 窗口
,然后输入
1 | .\ifrextractor.exe "Section_PE32_image_Setup_Setup.sct" verbose |
然后我们打开这个文件,搜索 USB OTG Support
,你会找到
1 | 0x19B6F: OneOf Prompt: "USB OTG Support", Help: "Enable/Disable USB OTG Support", QuestionFlags: 0x10, QuestionId: 0x1B2, VarStoreId: 0x1, VarOffset: 0x1BF, Flags: 0x10, Size: 8, Min: 0x0, Max: 0x3, Step: 0x0 { 05 91 3A 04 3B 04 B2 01 01 00 BF 01 10 10 00 03 00 } |
然后我们可以看到这个选项的 VarOffset
是 0x1BF
,而且 VarStoreId
是 0x1
。
然后搜 VarStoreId: 0x1
,找到类似这样的一行
1 | 0x129F9: VarStore Guid: EC87D643-EBA4-4BB5-A1E5-3F3E36B20DA9, VarStoreId: 0x1, Size: 0x27A, Name: "Setup" { 24 1C 43 D6 87 EC A4 EB B5 4B A1 E5 3F 3E 36 B2 0D A9 01 00 7A 02 53 65 74 75 70 00 } |
然后我们可以看到这个 VarStore 是叫做 Setup
的,接下来我们就可以用 datasone’s modded shell
我们下载 modGRUBShell.efi
并将其重命名为 BOOTX64.EFI
。
将一个 U 盘格式化为 FAT32
,并将 BOOTX64.EFI
移动到 USB:\EFI\BOOT\
(手动创建文件夹 EFI
和 BOOT
)。最终的 shell 路径应为 USB:\EFI\BOOT\BOOTX64.EFI
。
把这个 U 盘插入机器,开机按 F9 选择这个 U 盘启动,进入 grub 命令行界面。
1 | setup_var_3 0x1BF |
输入这个命令,这个命令应该会找到一个 0x3
为什么是 0x3
呢?因为我们在前面看到的 OneOfOption
里面有一个 Auto
的选项,而且是默认选项,我们可以大致推测这个 0x3
是代表 Auto
的。
于是我们就可以把它改成 0x1
,也就是 PCI mode
。
1 | setup_var_3 0x1BF 0x1 |
然后 Ctrl+Alt+Del 重启机器,进入系统。
到这里我们在 BIOS 里面已经开启了 USB OTG 的选项,
我们进入系统后,执行lspci
,可以看到有一个 Intel Corporation Device 22b7
的设备,搜索 8086:22b7
可以看到这个设备是 Intel USB Synopsys Controller 需要的驱动是 dwc3_pci
,但这个驱动系统默认是不带的,由此引出了下一步。
修改内核构建参数
从这里 我们可以知道需要打开的配置项是 CONFIG_USB_DWC3
。
构建的时候,建议使用虚拟机或其他机器来编译内核,本机编译实在太慢了。
这里我建议参考 Debian 官方内核构建手册,我这里感觉自己还是有些问题的,所以就仅给出我使用的命令,不作详细解释。
先说我的步骤目前遇到的问题:
- 破坏了依赖关系,导致无法正常使用 apt 安装各种库之类的
- 每次升级内核都需要重新编译一次,太麻烦了
命令:
1 | apt-get install build-essential libncurses-dev |
在 nconfig 这一步时,找到 Device Drivers -> USB Support -> USB Gadget Support
选中 USB Gadget Support
、 DesignWare USB3 DRD Core Support
构建完成后在debian/build
下会生成一个 linux-image-6.1.133_6.1.133-1_amd64.deb
的文件,复制到 t240 上,用 dpkg -i linux-image-6.1.133_6.1.133-1_amd64.deb
安装然后重启。
如果卡住了,你可以强制重启,在 grub 中进入高级选项,选择其他版本内核进入系统,卸载删除自己构建的内核并安装原版内核,命令没记错的话 apt --fix-broken install
。
如果你成功进入了你自己构建的内核,那么我们可以用下面的命令快速检查下是否成功
1 | ls /sys/class/udc |
如果你看到 udc
这个文件夹,那么恭喜你,你的 OTG 功能已经开启了。
运行 One-KVM
我这里采用的是 Docker 方式运行的 One-KVM。
首先是安装 Docker 这里和其他机器没有区别,正常安装就行,建议在安装自己构建的内核前完成安装。
然后我们把那个 USB OTG 接口的模式改成 device 模式,命令如下
1 | echo device > /sys/class/usb_role/intel_xhci_usb_sw-role-switch/role |
然后是安装 One-KVM,直接用下面的命令就行了
1 | docker run --name kvmd -itd --privileged=true \ |
(其实就是官方给出的命令)
参考及工具
https://github.com/datasone/grub-mod-setup_var
https://github.com/LongSoft/IFRExtractor-RS
https://github.com/BoringBoredom/UEFI-Editor
https://xairy.io/articles/thinkpad-xdci#-enabling-xdci-via-nvram
https://linux-hardware.org/?id=pci:8086-22b7-8086-7270
https://kernel-team.pages.debian.net/kernel-handbook/ch-common-tasks.html#s-common-official