MoreRSS

site iconJiaJe | 杰哥修改

清华大学计算机系博士生。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

JiaJe | 杰哥的 RSS 预览

升级 Ceph 集群到 20 Tentacle 版本

2026-11-07 08:00:00

升级 Ceph 集群到 20 Tentacle 版本

背景

之前一直用 Cephadm 维护了一个 Ceph 集群,作为一个 K8s 集群的存储,通过 Rook External Ceph Cluster 来维护。Ceph 出了一个比较严重的 CVE-2025-30156,需要把已有的 key 都 rotate 一遍,这里把这个过程记录一下。

升级过程

最开始的时候,Ceph 版本是 19.2.3,Rook 版本是 1.18.11,此时这个 Ceph 版本是有安全问题的,需要升级,核心就是上面的那个 CVE:原来的认证用的是 aes 算法,无论是客户端还是 Ceph 自己的各服务。但是,这个算法的实现有安全问题,居然用固定的 IV,还是 AES-128-CBC,所以需要换到新的 aes256k 上,然后把原来的 key 都淘汰掉。Ceph 的各服务和 Rook 自己的客户端都好说,升级版本以后,就可以替换为新的 key,麻烦的是,很多 CephFS 是通过 Linux 内核挂载的,而 Linux 内核直到 7.0 才支持 aes256k。旧版本内核,如果指定 aes256k 的 secret,会说 secret length 错误,无法挂载。

所以第一步,就是给各虚拟机都升级到了 7.0 的内核:trixie 和 trixie-security 都不够新,所以就用了 trixie-backports 的 7.2 内核。

升级完 Linux 内核后,就可以开始动手升级 Ceph 了,首先用 cephadm 升级 Ceph 到 20.2.5:

ceph orch upgrade start --image quay.io/ceph/ceph:v20.2.5

经过一段时间的等待,Ceph 的各服务都升级到了 20.2.5,并且 Cephadm 自动把服务用到的各种 key 都替换成了 aes256k。但是,还是有一些 key 需要手动操作,比如 client.admin。参考 Upgrading and Rotating CephX Keys,把 client.admin 的 key 给 rotate 掉:

ceph mon set auth_allowed_ciphers aes,aes256k
ceph mon set auth_preferred_cipher aes256k
ceph auth get-or-create client.admin-backup mon "allow *" | tee ./client.admin-backup.keyring
ceph -n client.admin-backup -k ./client.admin-backup.keyring auth ls
ceph auth rotate --key-type=aes256k client.admin | tee ./client.admin.keyring

对于 Cephadm,修改一台机器上的 /etc/ceph/ceph.client.admin.keyring,把里面的 admin key 换了,然后分发到其他机器上:

ceph orch client-keyring set client.admin "label:_admin"

剩下的需要 Rotate 的 key,就都是 Rook 需要的了:

  • client.csi-cephfs-node
  • client.csi-cephfs-provisioner
  • client.csi-rbd-node
  • client.csi-rbd-provisioner
  • client.healthchecker

这些 Key 都保存在 rook ceph 用于 external cluster 的 namespace 里的各 secret,根据名字很容易找到。我把 Rook 升级到 v1.21.2 后,直接在 Headlamp 里手动做的替换,虽然官方也给了脚本,但是脚本有一些依赖装起来比较麻烦,有 APT 的依赖问题。以 client.csi-cephfs-node 为例,其实就是:

ceph auth rotate --key-type=aes256k client.csi-cephfs-node

然后把新的 key,替换掉 rook-csi-cephfs-node Secret 里面的 adminKey。其他几个也是类似的。

把所有的 key 都 rotate 成 aes256k 后(通过看 key 的长度能看出是 aes 还是 aes256k),确认旧的 key 没有继续在使用(特别注意有没有正在用旧 key 挂载的 CephFS),禁用旧的 aes key 的使用:

ceph config set mon 'mon auth allow insecure key' false
ceph mon set auth_service_cipher aes256k
ceph auth wipe-rotating-service-keys
ceph mon set auth_allowed_ciphers aes256k

最后,ceph health 没有任何关于 insecure key 的 warning,就算迁移完成。

参考文档

用 XRDP + X11 转发实现带音频的图形界面转发

2026-11-03 08:00:00

用 XRDP + X11 转发实现带音频的图形界面转发

背景

最近遇到一个需求,在机器 A 上跑一个图形界面程序,但因为是远程访问,所以传统的办法就是开个 X11 Forwarding,或者跑个 VNC/RDP Server。但我有音频转发的需求,本地是 macOS,又不好在机器 A 上装 XRDP+桌面环境,于是在机器 B 上跑 XRDP Server,在机器 A 上通过 X11 Forwarding + Unix Socket Forwarding 实现图形界面和音频在机器 B 上的播放,再通过 RDP 客户端在 macOS 上实现带音频的图形界面浏览。

具体实现方法

具体实现方法不难,主要是在机器 B 上做一些配置:

  1. 安装 XRDP,配置桌面环境,我用的是 Xfce4
  2. 安装 pipewire-module-xrdp,关闭 pulseaudio 服务,改为 pipewire + pipewire-pulse + wireplumber
  3. 带 X11 Forwarding 连接到机器 A,同时通过 Unix Socket 转发 pulseaudio 的 Unix Socket:DISPLAY=XRDP_DESKTOP_HERE ssh -X -Y -R /run/user/UID_A_HERE/pulse/native:/run/user/UID_B_HERE/pulse/native host_a

然后在 SSH Session 里跑带图形界面的程序即可,它就会通过 ssh 转发的 X11 在 XRDP 的 DISPLAY 上显示,再通过 pulse/native 的 Unix Socket 播放音频。

最后,通过 RDP Client(Windows App)连接到机器 B,就可以在看到图形界面的同时,也有正确的音频了。

用 Files API 减少图片体积导致的 TTFT 膨胀

2026-10-12 08:00:00

用 Files API 减少图片体积导致的 TTFT 膨胀

背景

最近我经常用 DeepSeek-V4.1-Flash 模型读图。由于每次请求都要传完整上下文,随着上下文里的图片越来越多,上传图片所花的时间很快就成了 TTFT 的主要瓶颈;如果走的是 OpenCode Go,甚至动辄要几分钟。为了解决这个问题,可以用 Files API 提前把图片上传到 DeepSeek,然后在上下文里直接用 id 引用文件。为此,我顺手 Vibe 了一个 pi-files-api/opencode-files-api 插件,给 Pi Agent 和 OpenCode 都加上了这个能力。

具体现象

我最近发现一个现象:在一些会话里,TTFT 稳定地偏高,而且越来越高,从 10s、12s 一路上涨,有时甚至到几分钟的量级,而这些会话都包含大量的图片读取。一开始我以为是服务端的问题,后来通过交流和分析才发现,图片在每次请求时都会被重新发送给后端;随着读取的图片不断累积,TTFT 里的大部分时间都耗在了上传图片上。

一开始,我还寄希望于有状态的 OpenAI Responses API:每次只发送相对上一次请求的增量,从而避免图片的重复上传。然而 DeepSeek 目前还没有实现这个功能,所以只能用 Files API 了。

Files API

可以把 Files API 理解为一个临时的网盘,它支持上传、列举、删除和查询,有 OpenAI 和 Anthropic 两个版本,不过功能大同小异。在这个临时网盘里,每个文件都有唯一的 id,可以出现在 chat completions/responses/anthropic messages 请求体中,用来代替实际的图片内容。

因此,如果 Agent 懂得使用 Files API,先上传图片,再用 file id 填充请求体,就可以解决上述 TTFT 暴增的问题。DeepSeek Harness 是支持的,但前提是使用第一方 API;像我这样通过 AxonHub 统一管理 API key 的情况,它就没法用上这个 Files API 了。

另外,我日常使用的 Pi Agent 也没有做这个优化。不过在 AI 时代,做这样一个优化,也就是写几句 Prompt、写个插件的事情。

pi-files-api

最终,我快速 Vibe 出了一个插件 pi-files-api:它从 models.json 读取配置,替换上下文里的图片 base64,上传到指定的 Files API Endpoint,然后用 file id 替代图片内容;插件内部还维护了一份 sha256 到 file id 的映射。后续又把它移植到了 OpenCode 上:opencode-files-api。

当然,目前 AxonHub 还不支持代理 Files API,所以我只能被迫在本地给 Pi 配置 DeepSeek 的 API key:先通过 api.deepseek.com 上传图片,再通过 AxonHub 发送实际的请求体,非常不优雅。希望 AxonHub 后续能增加对 Files API 的支持,不过这也带来一个问题:切换 API 上游时,Files 不会跟着迁移,换了一个供应商以后,原来的 file id 就失效了。这个问题我还没想好怎么办,只能先曲线救国一下。

替换自制服务器上的 48V 直流电源

2026-10-09 08:00:00

替换自制服务器上的 48V 直流电源

背景

又到了新学期,计算机组成原理的实验又轰轰烈烈地开始了,但实验平台背后的 FPGA 集群,却出现了一台自制服务器不工作的问题,通过替换 48V 直流电源解决了。

自制服务器

说是服务器,但实际上,这个服务器是借用了机架式服务器的外壳,把里面改造成了一个 FPGA 集群。它通过一个电源把 220V 市电转成 48V 直流电源,然后给三个 10 口 PoE 交换机供电,然后每个 PoE 交换机再通过 PoE 给 8 个 FPGA 开发板供电。此外,再通过一个 48V 到 12V 的 DCDC 直流电源,给几个风扇供电。这样,一个自制服务器里,就可以承载 24 个 FPGA 开发板,再通过多个自制服务器组成 FPGA 集群。

交换机之间,采用菊花链的方式连接,最后连一根网线到机柜上的交换机。

问题定位

问题出在,其中一台自制服务器通电后没有反应。把自制服务器从机柜上拆下来,用万用表测试,最终的结论是:48V 电源坏了,输出的两个直流端子之间的电压为零,电源上的灯也没有亮。后续把电源拆出来看了看,没找到特别明显的出问题的部件。

修复

修复也很简单:找到了一个同型号的备用电源,一通拆卸,再按照原来的方式装回来就可以。由于这个 48V 电源的输出就是两个带有螺丝的端子,所以要把各路电源(三个交换机、一路 DCDC)的电源线的正和负分别压紧到对应的端子上,防止虚接发热。

探究一个 USB Type-C 拓展坞的硬件实现

2026-10-02 08:00:00

探究一个 USB Type-C 拓展坞的硬件实现

背景

最近在高强度使用 HDMI 和 DP 做视频输出,但在使用的时候遇到了各种细节问题,所以就研究整个链路上到底发生了哪些事情,在这个过程中,研究了一下手上的 Biaze KZ11 这款 Type-C 拓展坞,看看它内部有哪些芯片,又是怎样实现拓展坞的功能的。

拓展坞基本信息

首先介绍一下这款拓展坞的基本信息,从购买页面可以看到:

  • 接口上,有三个 USB 3.0(5 Gbps),一个 TF/SD 读卡槽,一个 HDMI,一个 VGA,一个 3.5mm TRS 音频输出,一个千兆以太网口,还有一个 Type-C PD 供电
  • 采用了 RTL8153、GL3224、VL103、VL817、AG6320 芯片
  • HDMI 最高支持 4K 30Hz,VGA 最高支持 1080P 60Hz

当然,本博客并不是购物推荐,只是因为恰好手上有这么一个拓展坞,并且把它用的芯片给了出来,所以才方便了我做分析。

初步分析

既然给出了芯片型号,我就去调查了一下,这些芯片都是做什么的:

  • RTL8153:USB 3.0 的千兆以太网控制器
  • GL3224:USB 3.2 Gen 1 的读卡器,用于 TF/SD 卡读取
  • VL103:Type-C DP Alt-Mode 和 PD 3.0 控制器
  • VL817:USB 3.1 Gen 1 (5Gbps) 的 Hub,最多接四个下游设备
  • AG6320:把 DP 转化为 HDMI 或者 VGA 信号,同时音频通过 I2S 接口输出,DP 运行在 5.40 Gbps HBR2 速率下,两个 lane 带宽一共是 10.80 Gbps,考虑编码损失还有 10.80*8/10=8.64 Gbps,所以最高 4K 30Hz 4:4:4 8bpc,它需要的带宽是 3840*2160*30*24=5.97 Gbps,算上消隐区就是 4400*2250*30*24=7.13 Gbps

于是我就想,既然 Type-C 拓展坞连电脑只有一个 Type-C,这个 Type-C 只能连一个设备,而下游有这么多设备:RTL8153,GL3224、VL103,都需要接到 USB 总线上,需要 VL817 来拓展,此外还有三个额外的 USB 口,那就至少有六个设备了,一个 VL817 不够,那就得级联一下:

flowchart LR
    Host -->|Type-C| VL817_1[VL817 #1]
    VL817_1 --> RTL8153 --> ETH
    VL817_1 --> GL3224 --> TF/SD
    VL817_1 --> VL103 --> DP --> AG6320 --> HDMI
    AG6320 --> VGA
    AG6320 --> I2S
    VL103 --> PD[Type-C PD 3.0]
    VL817_1 --> VL817_2[VL817 #2]
    VL817_2 --> Port1[USB 3.0 Port #1]
    VL817_2 --> Port2[USB 3.0 Port #2]
    VL817_2 --> Port3[USB 3.0 Port #3]

这里我觉得,既然 AG6320 输入是 DP,然后 VL103 是 DP Alt-mode 芯片,那就应该 AG6320 的输入来自于 VL103,就画出了上面的拓扑。看起来很合理,但实际上有问题:

  • VL817 是数据的 Hub,它能支持 PD 3.0 的高功率吗?
  • VL817 #2 只有三个下游设备,理论上可以再来一个 USB 3.0 Port,为啥只用了三个?

所以这个拓扑肯定不对,PD 芯片应该是直接接到电脑侧的,其他都是传数据的芯片,不需要也不应该接那么高功率的电源。这就给出了第二版拓扑:

flowchart LR
    Host -->|Type-C| VL103
    VL103 --> USB --> VL817_1[VL817 #1]
    VL817_1 --> RTL8153 --> ETH
    VL817_1 --> GL3224 --> TF/SD
    VL103 --> DP --> AG6320 --> HDMI
    AG6320 --> VGA
    AG6320 --> I2S
    VL103 --> PD[Type-C PD 3.0]
    VL817_1 --> VL817_2[VL817 #2]
    VL817_2 --> Port1[USB 3.0 Port #1]
    VL817_2 --> Port2[USB 3.0 Port #2]
    VL817_2 --> Port3[USB 3.0 Port #3]

但这依然很奇怪:VL817 #1 和 VL817 #2 各有一个 Port 是空的,这不是浪费了吗?说明这个拓扑依然不对。

USB 拓扑分析

上面都是从芯片的功能来硬推,推不出来合理的拓扑,那就说明我对芯片的功能的理解还是有所欠缺。那就从电脑这边来看,USB 总线上是个什么拓扑:

首先,我能看到有一个 USB 3.0 的 Hub(2109:0817),下面出现的设备是:

  • RTL8153 网卡
  • USB 3.0 端口 #1
  • USB 3.0 端口 #2
  • USB 3.0 端口 #3

这意味着,RTL8153 网卡是和三个 USB 3.0 端口挂在同一个 Hub 下的,猜测就是 VL817。此外,还有一个 USB 2.0 的 Hub(2109:2817),下面出现的设备是:

  • 另一个 USB 2.0 的 Hub(Terminus,1a40:0801,推测是 FE8.1 芯片)
  • USB Billboard Device(2109:8888)
  • USB 3.0 端口 #1 的 USB 2.0
  • USB 3.0 端口 #2 的 USB 2.0
  • USB 3.0 端口 #3 的 USB 2.0

这个 Terminus 的 USB 2.0 Hub 下面,又挂载了两个设备:

  • GL3224 读卡器
  • USB C Video Adaptor(9636:9300),另一个 USB Billboard Device

把这个 USB 总线拓扑画出来,就是:

flowchart LR
    Host --> USB3[USB 3.0 Hub 2109:0817]
    USB3 --> RTL8153 --> ETH
    USB3 --> Port1[USB 3.0 Port #1]
    USB3 --> Port2[USB 3.0 Port #2]
    USB3 --> Port3[USB 3.0 Port #3]

    Host --> USB2[USB 2.0 Hub 2109:2817]
    USB2 --> Terminus[Terminus USB 2.0 Hub 1a40:0801]
    USB2 --> Billboard[USB Billboard Device 2109:8888]
    USB2 --> Port1_USB2[USB 3.0 Port #1 USB 2.0]
    USB2 --> Port2_USB2[USB 3.0 Port #2 USB 2.0]
    USB2 --> Port3_USB2[USB 3.0 Port #3 USB 2.0]
    Terminus --> GL3224 --> TFSD[TF/SD Card]
    Terminus --> Adaptor[USB C Video Adaptor 9636:9300]

这个信息量很大,推翻了很多之前的分析:VL817 下游就是三个 USB 3.0,外加一个 RTL8153。然后 GL3224 是通过一个额外的 Terminus USB 2.0 Hub 接进来的,即使 GL3224 本身是一个 USB 3.2 Gen 1 的读卡器。同时为啥这个 USB 2.0 Hub 下面出现了五个设备?这个 USB Billboard Device 和 USB C Video Adaptor 又是哪来的?为啥要多加一个 Terminus USB 2.0 Hub?

推倒重来

这说明一开始认为的“Type-C 只能连到一个芯片上,再分到不同的芯片”的假设是错误的。实际上,Type-C 是可以同时连到多个芯片上的:

  • USB 2.0 的 D+/D-,用于 USB 2.0 总线
  • USB 3.0 Type-C 的四个差分对,可以两个差分对用于 USB 3.0 总线,另外两个差分对用于 DP
  • SBU 信号用于 DP 的 AUX
  • 电源和 CC,用于 USB PD

也就是说,实际上,Host 通过一个 Type-C 端口,同时接到了 VL103、VL817 和 AG6320 上!也就是说,AG6320 并不是接到 VL103,而是直接从 Type-C 取走了两个差分对,来做 DP 输入,只是 SBU(AUX) 信号是先进入 VL103,再接到 AG6320,此外为了实现热插拔,AG6320 给出了 HPD 信号给 VL103;VL103 也不负责 USB 3.0,它只是负责电源、CC 协商和 DP Alt-mode,同时还透传了 USB 2.0;VL817 虽然是 USB 3.0 Hub,但它其实就是一个 USB 3.0 Hub 和一个 USB 2.0 Hub,输出是四个 USB 3.0 和四个 USB 2.0。这已经基本解释了大部分问题,还差最后一点:

VL817 只有四个端口,那么,它 USB 3.0 Hub 下四个设备、USB 2.0 Hub 下五个设备都是怎么来的呢?

注意到外接的 USB 3.0 端口,它也是 3.0 和 2.0 兼具的,而且得是同一个 Port,所以 VL817 前三个 Port 就是 USB 3.0 和 2.0 同时连到外接 USB 端口上。那只剩下一个 Port 了,这个 Port 上又需要接 RTL8153,又需要接 Terminus USB 2.0 Hub,此外还有一个 USB 2.0 的 Billboard 2109:8888 设备,这哪接的下来?

答案是:最后一个 Port,把 3.0 部分和 2.0 部分分开:3.0 接 RTL8153,2.0 接 Terminus USB 2.0 Hub。实际上,从 USB 总线枚举上来看,这两个设备对应的 Port ID 是一样的。而那个 2109:8888 Billboard 设备,只是 VL817 自己枚举出来的设备,并没有实体。

至于 USB C Video Adaptor 9636:9300 是怎么来的,其实就是 DP Alt-mode 的要求:VL103 同时也是一个 USB 2.0 Device,这个 Device 就是这个 USB C Video Adaptor,给 Host 汇报 Alt-mode 的一些信息。因为有这个 USB C Video Adaptor 和 GL3224 都需要接到 VL817 最后一个 USB 2.0 端口上,放不下,才又引入了一个 Terminus USB 2.0 Hub。

至此,完整的硬件拓扑就比较清楚了:

flowchart LR
    Host --> PD --> VL103
    Host --> SBU --> VL103 -->|AUX| AG6320
    AG6320 -->|HPD| VL103
    Host --> USB2[USB 2.0] --> VL103 -->|USB 2.0| VL817
    Host --> USB3[USB 3.0 2 lanes] --> VL817
    Host --> DP[DP 2 lanes] --> AG6320 --> HDMI
    AG6320 --> VGA
    AG6320 --> I2S

    VL817 --> Port1[USB 3.0 Port 1, USB 3.0 + USB 2.0]
    VL817 --> Port2[USB 3.0 Port 2, USB 3.0 + USB 2.0]
    VL817 --> Port3[USB 3.0 Port 3, USB 3.0 + USB 2.0]
    VL817 --> Port4[Port 4]
    Port4 -->|USB 3.0| RTL8153 --> ETH
    Port4 -->|USB 2.0| Terminus[Terminus USB 2.0 Hub]
    VL817 --> Billboard[Virtual Billboard Device 2109:8888]
    Terminus --> GL3224[GL3224 Card Reader 05e3:0749] --> TFSD[TF/SD Card]
    Terminus --> Adaptor[USB C Video Adaptor 9636:9300 Billboard Device of VL103]

这样,VL817 的四个端口,无论是 USB 3.0 还是 USB 2.0,都物尽其用了,刚好把三个 USB 3.0 端口都用满了。多出来的 Terminus USB 2.0 Hub 的用途也解释清楚了。

附录:分析绿联 CM478-15495

顺带也分析了一下 绿联 CM478-15495 拓展坞的配置,它的参数如下:

  • 接口上,支持 USB3.0+USB2.0*2+PD+HDMI
  • HDMI: 4K 30Hz, 1080P 120Hz
  • PD 3.0 100W

分析了一下 USB 拓扑,发现它的 USB 3.0 设备是直接通到电脑上的,没有经过 Hub;而它有一个 Genesys Logic 05e3:0608 的 4 口 USB 2.0 Hub(根据网上信息,猜测是 GL850G),下面连了四个设备:

  • DP Alt-mode 的 Billboard Device 343c:0000
  • USB 2.0 端口 #1
  • USB 2.0 端口 #2
  • USB 3.0 端口的 USB 2.0

那么 DP 则又是直接从 Type-C 拿走了两个差分对,然后 USB 3.0 端口是接了另外两个差分对。可见这又是一个物尽其用的例子。推测 CM478-15495 一种可能的拓扑:

flowchart LR
    Host --> PD --> Unknown
    Host --> USB2[USB 2.0] --> GL850G[GL850G USB 2.0 Hub 05e3:0608]
    GL850G --> Port2[USB 2.0 Port #1]
    GL850G --> Port3[USB 2.0 Port #2]
    GL850G -->|USB 2.0| Port1
    GL850G --> Port5[USB Billboard Device 343c:0000]
    Host --> USB3[USB 3.0 2 lanes] -->|USB 3.0| Port1[USB 3.0 Port]
    Host --> DP[DP 2 lanes] --> Unknown --> HDMI

实际上,因为 CM478-15495 的 USB 3.0 端口是直接接到了电脑上,没有像 KZ11 那样过了一个 USB 3.1 Gen 1 的 VL817 Hub,在 macOS 实测速率可以协商到 10 Gbps,也就是 USB 3.1 Gen 2。同一个设备,插到 KZ11 的 USB 3.0 口上,就只有 5 Gbps 的速率了。

附录:分析飞利浦 SWR1607L/93

参数:

  • 3xUSB 3.0 5Gbps,其中两个是 Type-C,一个是 Type-A
  • USB PD 100W
  • HDMI 4K60Hz

在系统里看到的是两个 Hub:

  • USB 3.1 Hub 05e3:0626 5Gbps
  • USB 2.1 Hub 05e3:0610 480Mbps

目测又是 Genesys Logic 的 4 口 Hub,根据网上信息,猜测是 GL3523,四口 USB 3.1 Gen 1 的 Hub。

考虑到它只有 5Gbps,那么应该又是 Type-C 的两个 lane 通过 4 口 Hub 接出了三个 USB 3.0,剩下一个口有两种可能:一是留给 DP Alt-mode 的 Billboard Device,但实际上无论是否插 HDMI,都没有这个设备出现,或许是因为 DP Alt-mode 协商正常工作,所以 Billboard Device 没有出现,但实际上还是占用了一个口;二是它就是没有接任何设备。Hub 的 Port 4 对应 USB 3.0 Type-C 口,Port 3 对应 Type-C 旁边的 USB 3.0 Type-A 口,Port 2 则是最后一个离 Type-C 口最远的 USB 3.0 Type-C 口。

另外两个 lane 则是给了 DP Alt-mode,这里的 HDMI 能跑到 4K 60Hz 4:4:4 8bpc,说明它的 DP 跑在了更高的速率:在 macOS 里看,它的 DP 运行在 8.10 Gbps (HBR3) 速率上,这样两个 lane 的总带宽就是 16.20 Gbps,考虑编码损失还有 16.2*8/10=12.96 Gbps,足够 4K 60Hz 4:4:4 的 3840*2160*60*24=11.94 Gbps 带宽,算上消隐区(需要消隐区比较少的时序),也就是 4000*2205*60*24=12.70 Gbps。

有意思的是,如果我直接用 Type-C 连显示器,那么它就可以用四个 lane 传 5.40 Gbps (HBR2) 速率,这样总速率达到了 21.60 Gbps,考虑编码损失还有 21.60*8/10=17.28 Gbps,甚至可以 4K 75 Hz 4:4:4 8bpc,毕竟它只需要 3840*2160*75*24=14.9 Gbps 带宽,算上消隐区,也就是 4000*2205*75*24=15.88 Gbps。

所以对于各种 Type-C 拓展坞来说,因为要保留 Type-C Hub 功能,所以最多有两个 lane 用于 DP,此时能跑到 4K 30Hz,还是 4K 60Hz,就取决于能跑到 HBR2 还是 HBR3 上。HBR2 就对应 4K 30Hz 4:4:4 8bpc 或者 4K 60Hz 4:2:0 8bpc,HBR3 就对应 4K 60Hz 4:4:4 8bpc(但需要消隐区比较少的时序,带宽特别紧张)。如果不走拓展坞,直连显示器,四个 lane 都可以用于 DP,此时即使是 HBR2,也能跑到 4K 75Hz 4:4:4 8bpc 上。

也做了一个小实验,如果把显示器通过 Type-C 接到飞利浦 SWR1607L/93 的 USB 3.0 Type-C 口上,显示输出就不工作了,因为这个口过了一个 Hub,这个 Hub 不支持 DP Alt-mode。

附录:分析绿联 CM136-70495

也分析一下 绿联 CM136-70495 拓展坞的配置,它的参数如下:

  • 接口上,支持 USB3.0*3+PD+HDMI
  • USB 3.0 5Gbps
  • HDMI: 4K 60Hz
  • PD 3.0 100W

它的接口和上面的飞利浦 SWR1607L/93 一模一样,唯一的不同就是,绿联 CM136-70495 三个 USB 3.0 都是 Type-A,而飞利浦 SWR1607L/93 把其中一个换成了 Type-C。

在系统里看到的是两个 Hub:

  • USB 3.0 Hub 2109:0817 5Gbps
  • USB 2.0 Hub 2109:2817 480Mbps

看到这个熟悉的 VID/PID,不出意外,它用的和 Biaze KZ11 一样,也是 VL817,USB 3.1 Gen 1 5Gbps 的四口 Hub。然后三个 USB 3.0 Type-A 口都是挂在这个 VL817 四口 Hub 下。离 HDMI 最近的口是 Port 4,次近的是 Port 1,最远的是 Port 2。

与飞利浦 SWR1607L/93 一样,它也能跑到 4K 60Hz 4:4:4 8bpc,在 macOS 里看,果然是 2 lane 的 HBR3。这次也没有 Billboard Device 出现。

附录:同一个显示器,一个拓展坞只能 4K 30Hz,另一个拓展坞可以 4K 60Hz

不过在实践中,也遇到过特殊的情况:同一个 Crestron 420 显示器,连上述两个拓展坞出现了不同的现象:

  • 通过飞利浦 SWR1607L/93 接 Crestron 420,只能输出 4K 30Hz,没有 4K 60Hz 的选项
  • 通过绿联 CM136-70495 接 Crestron 420,则可以输出 4K 60Hz

猜测是 EDID 的问题,由于 Crestron 420 的限制,HDMI 版本只有 1.4b,它的 4K 60Hz 是 4:2:0 的,但实际能否达到,还要看拓展坞这边能否提供正确的 EDID。首先是只能跑到 4K 30Hz 来自飞利浦 SWR1607L/93 的 EDID:

00ffffffffffff000ca9e10700000000041b010380502d800eee91a3544c99260f50542000000101010101010101010101010101010140d10080f0705a8020188a0020c23100001a023a801871382d40582c450020c23100001e000000fd00174c1e4b1e000a202020202020000000fc004372657374726f6e203432300a01fb02032172465f5e5d9004022309070783010000e2004f67030c001000003ce20e61023a801871382d40582c450020c23100001e04740030f2705a80b0588a0020c23100001e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e5

接着是能跑到 4K 60Hz 来自绿联 CM136-70495 的 EDID:

00ffffffffffff000ca9e10700000000041b010380502d800eee91a3544c99260f50542000000101010101010101010101010101010104740030f2705a80b0588a0020c23100001e023a801871382d40582c450020c23100001e000000fc004372657374726f6e203432300a000000fd00174c1e4b1e000a202020202020010e02032970475f5e5d1005040223090707830100006d030c001000003c200060010203e30e6160e2004f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f7

附录:分析 Biaze ZH395

参数:

  • PD 100W
  • HDMI 4K 30Hz
  • 5Gbps USB 3.0 Type-A 口
  • 一个 USB 2.0 Type-A 口
  • 一个 USB 2.0 Type-C 口

看过前面这么多分析,基本可以推断出,它又是 Type-C 的两个 lane 直通 USB 3.0 Type-A 口,另外两个 lane 用于 DP Alt-mode,再来个 USB 2.0 的 Hub 214b:7260。虽然宣传的是 HDMI 4K 30Hz,但实际上能跑到 4K 60Hz,由于是 2 lane 的 HBR2,应该是 4:2:2 或者 4:2:0 而非 4:4:4,看起来有略微的模糊感。

附录:分析绿联 CM511-45031

CM511-45031 参数:

  • PD 3.0 100W
  • HDMI 2.0 4K 60Hz
  • 3x USB 3.2 10 Gbps Type-A 口
  • 1x USB 3.2 10 Gbps Type-C 口

实测 DP 能跑到 2 lane HBR3,因此可以轻松 4K 60Hz 4:4:4。USB 方面,有一个 USB 3.2 Hub GenesysLogic 05e3:0625 和一个 USB 2.1 Hub GenesysLogic 05e3:0610。这里的 USB 3.2 代表的其实是 USB 3.2 Gen 2,所以每个口都是 10Gbps。

附录:同一个显示器,不同拓展坞显示的频率选项不同

同一个 HKC 2755U 显示器,连上述拓展坞出现了不同的现象:

  • 通过飞利浦 SWR1607L/93 接 HKC T2755U,可以输出 4K 60Hz,无 50Hz 选项,同时还有 HDR 选项
  • 通过绿联 CM136-70495 接 HKC T2755U,可以输出 4K 60Hz/50Hz,同时还有 HDR 选项
  • 通过 Biaze ZH395 接 HKC T2755U,可以输出 4K 60Hz,无 50Hz 选项,同时还有 HDR 选项,但界面比较模糊,疑似 4:2:2 或 4:2:0,macOS 设置里显示的是分辨率列表,而不是像其他几个拓展坞那样,显示几种文字大小
  • 通过绿联 CM511-45031 接 HKC T2755U,可以输出 4K 60Hz/50Hz,同时还有 HDR 选项

附录:其他常用拓展坞芯片

  • AX88179: USB 3.0 to 1000M Ethernet Controller
  • VL822: USB 3.1 Gen 2 10Gbps 4-Port Hub Controller
  • SW2505: USB PD Controller

把博客生成器从 Mkdocs 迁移到 Zensical

2026-09-30 08:00:00

把博客生成器从 Mkdocs 迁移到 Zensical

距离上一次 从 Mkdocs 迁移到 Zensical 已经过去了三年,这次 Zensical 终于是补齐了原来 Mkdocs 用到的大部分插件,所以就当小白鼠,把博客从 Mkdocs + Mkdocs-Material 迁移到了 Zensical。

这次迁移的背景,就是 Mkdocs-Material 团队对 Mkdocs 后续的更新计划不满,自己独立出来,RIIR 了一个尽量兼容 Mkdocs 生态的 Zensical。当然这个兼容不是 100% 的,所以我也在逐渐地做一些替换,从 ctf-writeups 开始,到 cpu,再到博客主站,未来等 i18n 插件到位了,再迁移 kb 等等。其实用起来也没啥区别,连配置文件都不用改,然后就是构建速度确实快了很多,之前 mkdocs build 一次要好几十秒,zensical 明显更快。插件方面,我也自己移植了一个 zensical-wavedrom-plugin 用来渲染 wavedrom 波形图。

回顾历史,本博客已经做了好几次迁移:

迁移的基本动力,要么是原来的生成器太慢了,要么就是有一些硬伤。不知道几年后,会不会再迁移到新的技术栈呢。