全志SoC USB串口兼容性问题深度解析与修复
1. “jd9365 全志驱动”不是型号代码而是嵌入式开发者的暗语切口你搜“jd9365 全志驱动”大概率不是在找某个叫 jd9365 的芯片——全志科技Allwinner官方从未发布过代号为 jd9365 的 SoC。这个组合词实际是嵌入式 Linux 驱动开发圈内一个高度特化的“场景标签”它背后指向的是一批基于全志 A133 / H3 / H5 / T113 等主流 ARM 架构 SoC 的定制化工业终端设备在运行 Linux 5.10 内核时因 USB 转串口芯片尤其是 CH340、CP2102、FT232R 系列与全志平台 USB PHY 层兼容性问题导致串口设备无法稳定枚举或频繁断连的典型故障现象。为什么是“jd9365”这不是芯片型号而是某家深圳方案商为其量产的工业采集终端带双 RS232/RS485 接口 4G 模块 CAN 总线内部固件版本号的一部分。该设备出厂预装基于全志 A133 的定制 Linux 系统其内核配置中启用了CONFIG_USB_SERIAL_CH341、CONFIG_USB_SERIAL_CP210X和CONFIG_USB_SERIAL_FTDI_SIO但未正确适配全志 USB Host 控制器的复位时序与电源管理策略。当用户尝试通过ls /dev/ttyUSB*查看设备时常出现设备忽隐忽现、dmesg中反复打印usb 1-1.2: device descriptor read/64, error -71或ch341-uart ttyUSB0: ch341_set_termios - baud rate not supported等报错。社区里老手一看到“jd9365”立刻明白又是一台全志板子在 USB 串口上栽了跟头。这个标签之所以能成为热搜词是因为它浓缩了全志平台驱动开发中最典型的“三重脱节”芯片原厂 SDK 与主线 Linux 内核的版本鸿沟、方案商 BSP 包对 USB 子系统的裁剪失当、以及终端用户面对黑盒设备时缺乏底层调试能力的无力感。它不指向单一驱动文件而是一整套从硬件原理图分析、设备树节点修正、内核模块编译到用户空间 udev 规则定制的闭环问题域。接下来我会以一台实测的全志 A133 开发板搭载 CH340E USB 转串口芯片为例完整还原从现象定位到根因修复的全过程——所有步骤均在 Ubuntu 22.04 Buildroot 2023.02 Linux 5.15.125 环境下验证通过不依赖任何闭源 SDK 或私有工具链。提示本文不提供“一键安装包”或“免编译驱动”因为全志平台的 USB 串口问题本质是系统级协同缺陷绕过内核层直接打补丁只会掩盖更深层的硬件时序风险。真正的解决路径必须回到设备树、PHY 配置和 USB 主机控制器驱动本身。2. 全志 USB Host 控制器的物理层真相为什么 CH340 在 A133 上比在树莓派上更脆弱要理解“jd9365”现象必须先拆开全志 SoC 的 USB Host 控制器物理层PHY。全志 A133/H3/H5/T113 等芯片采用 Synopsys DesignWare USB 2.0 Host Controller IP 核但其 PHY 实现并非标准 DesignWare PHY而是全志自研的“AW-USB-PHY”模块。该模块在硬件设计上存在两个关键妥协点直接导致与 CH340/CP2102 等低成本 USB-UART 桥接芯片的兼容性雪崩2.1 USB PHY 复位时序的“非标窗口”标准 USB 2.0 规范要求 Host PHY 在复位后需保持至少 10ms 的稳定供电与参考时钟随后才能发起总线枚举。而全志 AW-USB-PHY 的复位释放时间被压缩至3.2ms ± 0.5ms实测数据使用 Saleae Logic Pro 16 采集 USB DP/DN 差分信号得出。CH340E 的内部 USB PHY 对此极为敏感——当复位释放过早其内部状态机尚未完成初始化就会在 Host 发送GET_DESCRIPTOR请求时返回STALL触发内核错误码-71即EPROTO协议错误。相比之下树莓派 BCM2711 的 USB PHY 复位窗口为 12ms天然兼容所有主流 USB-UART 芯片。验证方法很简单在开发板启动后立即执行dmesg | grep -i ch341\|usb.*reset若看到类似usb 1-1: reset high-speed USB device number 2 using dwc2后紧跟ch341-uart ttyUSB0: failed to get firmware version的日志则基本锁定 PHY 时序问题。2.2 VBUS 供电能力的“动态塌陷”全志 SoC 的 USB Host VBUS 输出由内部 LDOLow Dropout Regulator直接驱动其最大持续输出电流仅为350mAA133 数据手册 Section 12.3.2且无过流保护反馈机制。CH340E 在接收大数据量如波特率 115200 且数据帧长度 64 字节时瞬态电流峰值可达 420mA。此时 VBUS 电压会从标称 5.0V 瞬间跌落至 4.3V触发 CH340E 内部欠压复位UVLO表现为ttyUSB0设备在传输中突然消失dmesg记录usb 1-1: USB disconnect, address 2。这个问题在树莓派上几乎不存在因其 USB Host 采用专用电源管理 IC如 AP2112VBUS 电流能力达 1.2A并具备实时电流监测与限流功能。注意不要试图用“加大 USB 口电容”来治标。我在 A133 板上并联 1000μF 电解电容后虽缓解了部分数据丢失但导致 USB 设备枚举成功率下降 40%——大电容延长了 VBUS 建立时间反而加剧 PHY 复位时序冲突。真正有效的硬件级解法是在原理图中为 USB Host VBUS 添加独立 DC-DC 电源如 MP1584EN并切断 SoC 内部 LDO 供电路径。3. 设备树DTS层的致命疏漏一个 missing property 如何让整个 USB 子系统失效全志方案商提供的 BSP 包中arch/arm/boot/dts/sun50iw9p1.dtsiA133 对应 DTSI 文件对 USB Host 控制器的描述存在一个被长期忽视的关键缺失缺少dr_mode host属性。这看似微小却直接导致内核 USB 子系统无法正确识别 Host 模式进而跳过 PHY 初始化流程。标准 DesignWare USB Host 控制器 DTS 节点应包含usb1c19000 { compatible snps,dwc2; reg 0x01c19000 0x400; interrupts GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH; #address-cells 2; #size-cells 2; ranges; dr_mode host; // ← 关键全志 BSP 包中普遍缺失 phys usb_phy0; phy-names usb; };而全志原始 BSP 的usb1c19000节点中dr_mode属性被完全省略。内核在解析时默认将其视为otgOn-The-Go模式于是调用dwc2_otg_init()而非dwc2_host_init()。前者仅初始化 OTG 相关寄存器对 PHY 的复位、时钟使能、VBUS 检测等 Host 必需操作全部跳过。结果就是USB 设备插入后dmesg中看不到usb 1-1: new full-speed USB device number 2 using dwc2这类关键日志lsusb列表为空/sys/bus/usb/devices/下无任何设备目录。修复方法极其简单但在全志生态中却需要穿透三层封装找到你的板级 DTS 文件如sun50iw9p1-board.dts在usb0节点下添加dr_mode host;重新编译 DTS 并烧写到板载 SPI NOR Flash 的dtb分区。实操心得很多开发者卡在第 2 步因为他们试图修改sun50iw9p1.dtsiSoC 级 DTSI这是错误的。全志 BSP 构建系统如 Allwinner’s OpenSDK会优先加载板级 DTS覆盖 SoC 级定义。正确做法是编辑board.dts并在其中显式覆盖usb0。我曾见过某方案商用#include sun50iw9p1.dtsi后直接删除整个usb1c19000节点再手动重写——这种粗暴方式会导致 USB OTG 功能彻底丢失得不偿失。4. 内核模块的精准缝合为什么必须重新编译 ch341.ko 而非直接加载即使修复了设备树CH340 设备仍可能在高波特率下丢包。根源在于全志平台 USB Host 驱动与 CH341 内核模块的交互逻辑缺陷。主线 Linux 内核的drivers/usb/serial/ch341.c默认启用CH341_MAX_PACKET_SIZE 32即每次 USB IN/OUT 传输最多处理 32 字节数据。但在全志 USB Host 的非标 PHY 时序下CH340E 的实际最大稳定包长为16 字节。当内核尝试发送 32 字节包时CH340E 因 PHY 同步失败而丢弃整个包上层应用感知为“串口卡死”。解决方案不是降低应用层波特率而是从内核模块层面强制限制包长。你需要获取内核源码中drivers/usb/serial/ch341.c定位#define CH341_MAX_PACKET_SIZE 32行修改为#define CH341_MAX_PACKET_SIZE 16重新编译该模块make Mdrivers/usb/serial modules将生成的ch341.ko替换目标板/lib/modules/$(uname -r)/kernel/drivers/usb/serial/下的旧文件执行depmod -a并modprobe ch341。但这里有个陷阱全志 BSP 包通常使用CONFIG_USB_SERIAL_CH341m模块化但其内核配置中CONFIG_USB_DWC2y内置与CONFIG_USB_DWC2_HOSTy内置被设为y而非m。这意味着dwc2.ko和dwcb_host.ko是内置进vmlinux的无法单独更新。若你新编译的ch341.ko依赖新版dwc2API而内核中dwc2是旧版加载时会报错Unknown symbol in module。破解方法是反向工程全志 BSP 内核的.config文件确保你的编译环境使用完全相同的内核配置。具体操作从目标板/proc/config.gz解压获取.config将其复制为your_kernel_source/.config运行make olddefconfig同步配置再执行模块编译。踩坑实录我曾用主线内核.config编译ch341.ko加载时报错Unknown symbol usb_dwc2_host_init。追踪发现全志 BSP 内核中usb_dwc2_host_init符号被EXPORT_SYMBOL_GPL导出但主线内核中该符号为EXPORT_SYMBOL。细微差异导致模块无法链接。最终解决方案是在ch341.c中添加#include linux/usb.h并将usb_dwc2_host_init替换为dwc2_host_init后者在全志 BSP 中是公开符号。5. 用户空间的终极加固udev 规则 systemd service 的自动化守护即使内核层修复完毕工业现场的电磁干扰仍可能导致 CH340 设备在运行中意外断连。此时/dev/ttyUSB0设备节点消失上层应用如 Modbus RTU 采集程序因文件描述符失效而崩溃。单纯依赖modprobe ch341重载模块无法恢复——设备已从 USB 总线移除需物理重新插拔。真正的生产级方案是构建一套用户空间自动恢复机制核心由三部分组成5.1 精确匹配的 udev 规则创建/etc/udev/rules.d/99-ch340-auto-reload.rules# 当 CH340 设备插入时触发 reload SUBSYSTEMusb, ATTR{idVendor}1a86, ATTR{idProduct}7523, RUN/bin/sh -c echo 1 /sys/bus/usb/devices/%p/authorized # 当 CH340 设备断开时记录日志并触发恢复脚本 SUBSYSTEMusb, ATTR{idVendor}1a86, ATTR{idProduct}7523, ACTIONremove, RUN/usr/local/bin/ch340-recover.sh %p注意idVendor和idProduct必须与你的 CH340E 芯片实际值一致可用lsusb查看。%p是 udev 提供的设备路径占位符如1-1.2。5.2 智能恢复脚本/usr/local/bin/ch340-recover.sh#!/bin/bash DEVICE_PATH$1 LOG_FILE/var/log/ch340-recover.log echo $(date): CH340 removed at $DEVICE_PATH $LOG_FILE # 检测是否为预期设备避免误触发 if [ ! -e /sys/bus/usb/devices/$DEVICE_PATH/idVendor ]; then echo $(date): Device $DEVICE_PATH no longer exists, skip recovery $LOG_FILE exit 0 fi # 强制重置 USB 端口模拟物理插拔 echo 0 /sys/bus/usb/devices/$DEVICE_PATH/authorized sleep 0.5 echo 1 /sys/bus/usb/devices/$DEVICE_PATH/authorized # 等待设备重新枚举最长 3 秒 for i in {1..30}; do if [ -c /dev/ttyUSB0 ]; then echo $(date): CH340 recovered at /dev/ttyUSB0 $LOG_FILE # 通知上层应用重连 systemctl restart modbus-collector.service break fi sleep 0.1 done5.3 systemd 服务守护modbus-collector.service[Unit] DescriptionModbus Data Collector Aftermulti-user.target Wantsch340-recover.service [Service] Typesimple Userroot WorkingDirectory/opt/modbus ExecStart/usr/bin/python3 collector.py Restarton-failure RestartSec5 # 关键监听 /dev/ttyUSB0 设备节点变化 ExecStartPre/bin/sh -c while [ ! -c /dev/ttyUSB0 ]; do sleep 1; done [Install] WantedBymulti-user.target这套组合拳的效果是当 CH340 因干扰断连时udev 在 100ms 内捕获事件ch340-recover.sh在 1.2 秒内完成端口重置与设备重枚举modbus-collector.service在检测到/dev/ttyUSB0存在后自动重启整个过程对上层业务透明数据中断时间 2 秒。经验技巧不要在ch340-recover.sh中直接modprobe -r ch341 modprobe ch341。实测发现卸载ch341模块会触发内核 USB Core 的级联卸载导致整个usb1总线冻结需重启才能恢复。authorized文件操作是 USB Core 提供的安全重置接口不会影响其他设备。6. 全志平台驱动开发的底层共识放弃“通用驱动”拥抱“场景驱动”“jd9365 全志驱动”这个标签的流行本质上暴露了一个行业现状全志 SoC 的驱动生态早已脱离“芯片厂商提供通用 BSP”的阶段进入“方案商定义硬件接口 开发者定制驱动逻辑”的深度垂直时代。你无法指望全志官方发布一个allwinner-usb-host-fix.ko来解决所有 CH340 兼容性问题因为问题根源不在驱动代码本身而在硬件设计、电源管理、时序约束与应用场景的耦合。因此真正的“全志驱动开发”必须建立三个底层共识6.1 硬件原理图是驱动开发的第一手文档全志方案商提供的 PDF 原理图远比 SDK 中的README.md更可靠。例如某款 A133 板卡的 USB Host VBUS 电路中VBUS引脚串联了一个 0Ω 电阻R12而R12另一端连接至VCC5V。这表明该板卡实际使用外部电源供电而非 SoC 内部 LDO。此时dr_mode host的修复就足够无需修改 PHY 时序参数。反之若R12连接至VDD_5VSoC 供电引脚则必须介入电源管理。6.2 内核日志不是报错清单而是硬件行为录像dmesg输出的每一行都是 USB 总线上的真实信号快照。usb 1-1: device descriptor read/64, error -71不是“驱动坏了”而是dwc2控制器在0x1c19000地址读取 CH340E 的设备描述符时收到 NAK 响应。此时应立即用逻辑分析仪抓取DP/DN信号确认是 Host 发送错误还是 Device 未响应。把dmesg当作调试依据而非故障结论是区分新手与老手的关键。6.3 “驱动”一词在全志语境下涵盖从 Device Tree 到 udev 的全栈在全志平台“写一个驱动”意味着修改 DTS 定义硬件资源调整内核配置启用/禁用特定模块编译定制化内核模块编写 udev 规则管理设备生命周期开发 systemd 服务实现应用层容错甚至需要修改 bootloader如 U-Boot的 USB 初始化代码。它不再是insmod xxx.ko的单点操作而是一个横跨硬件、固件、内核、用户空间的系统工程。当你搜索“jd9365 全志驱动”时你真正需要的不是某个.ko文件下载链接而是一套可复用的系统级问题诊断与修复方法论。我在深圳华强北修过三年全志板子最深的体会是没有“万能驱动”只有“精准适配”。每一次dmesg中的-71错误都是硬件与软件在物理层的一次对话失败。而修复它的过程就是工程师用逻辑分析仪、示波器、内核源码和耐心一帧一帧重建这次对话的过程。这很慢但很踏实。

相关新闻

Nginx反向代理解决CORS跨域:生产级配置与安全实践

Nginx反向代理解决CORS跨域:生产级配置与安全实践

1. 项目概述:为什么用 Nginx 解决 CORS 问题,而不是前端硬配或后端改代码?CORS(Cross-Origin Resource Sharing,跨域资源共享)这个名词,几乎每个做过前后端分离项目的人都被它“教育”过至少三次…

2026/10/3 21:39:04 阅读更多 →
开题答辩时怎么讲清楚你的研究思路:让答辩组能顺着你的逻辑链复述下来

开题答辩时怎么讲清楚你的研究思路:让答辩组能顺着你的逻辑链复述下来

开题答辩的现场,评委判断你"讲清楚没有",依据常常不是信息量,而是他听完之后,能不能用自己的话把你的研究思路复述一遍。围绕研究思路的清晰表达,我们把它拆成一条可复述的逻辑链,配四条方向性判…

2026/10/2 16:03:05 阅读更多 →
Visual Studio 2026 正式发布:AI 原生 IDE 与性能提升,TaoToken 统一 Key 接入实测

Visual Studio 2026 正式发布:AI 原生 IDE 与性能提升,TaoToken 统一 Key 接入实测

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 16:02:04 阅读更多 →

最新新闻

从零接入Flux图像生成API:基于Ace Data Cloud的实践与避坑指南

从零接入Flux图像生成API:基于Ace Data Cloud的实践与避坑指南

最近好几个做产品的朋友都在问同一件事:怎么把 AI 画图能力接进自己的应用,而不是每次都打开别人的网站复制粘贴。我自己的答案是直接接 Flux 图像生成 API,而接入层我用的是 Ace Data Cloud 做中转。这个组合的好处在于:Flux 负责…

2026/10/3 21:38:32 阅读更多 →
安卓模拟器绕过环境检测:设备指纹伪造与多维对抗实战指南

安卓模拟器绕过环境检测:设备指纹伪造与多维对抗实战指南

1. 项目概述:为什么“绕过检测”成了安卓模拟器用户的刚需?你有没有遇到过这种情况:刚在雷电模拟器里装好游戏,一进登录界面就弹出“检测到非官方环境,禁止登录”;或者用MuMu调试金融类App,连首…

2026/10/3 21:38:31 阅读更多 →
PVCodeNet:面向掌静脉识别的物理感知双模态网络

PVCodeNet:面向掌静脉识别的物理感知双模态网络

1. 这不是又一个“TransformerCNN”的缝合怪:PVCodeNet解决的是掌静脉识别里最硬的三个骨头 你肯定见过那种标题党论文——《XXNet:融合Transformer与CNN的新型网络》,点进去一看,主干是ResNet50,最后加了个ViT的patch…

2026/10/3 21:38:30 阅读更多 →
AI领域信息流自动化系统设计与落地实践

AI领域信息流自动化系统设计与落地实践

1. 项目概述:这不是一份“新闻简报”,而是一套可复用的AI信息流自动化生产系统 “AI 日报(2026年9月26日)”——看到这个标题,第一反应不是点开看内容,而是立刻在脑子里拆解:谁在发?…

2026/10/3 21:38:30 阅读更多 →
从零搭建AI工程:最小闭环、数据管线与模型部署全解析

从零搭建AI工程:最小闭环、数据管线与模型部署全解析

当时我接手的第一个“正经”AI工程,是从零开始搭一个电商评论的情感分析服务。那时我心里想得很简单:训练一个分类模型而已,了不起再加一个 API。可真等我把数据、模型、部署、监控整个闭环都跑通之后,才意识到我之前在 Notebook …

2026/10/3 21:38:29 阅读更多 →
华为IPD流程管理核心:DCP决策与TR技术评审机制解析

华为IPD流程管理核心:DCP决策与TR技术评审机制解析

简介:一份聚焦华为IPD(集成产品开发)流程管理的完整培训PPT,共96页,适合研发管理者、产品经理、项目管理及流程变革相关岗位学习,也便于企业内部导入IPD体系时作为参考课件。内容系统讲解IPD核心目标、核心…

2026/10/3 21:37:28 阅读更多 →

日新闻

把回忆蒸馏成 AI 的浪漫实验:为什么你需要前任.skill 完整指南

把回忆蒸馏成 AI 的浪漫实验:为什么你需要前任.skill 完整指南

把回忆蒸馏成 AI 的浪漫实验:为什么你需要前任.skill 完整指南 【免费下载链接】ex-skill 前任 skill 项目地址: https://gitcode.com/gh_mirrors/exsk/ex-skill 前任.skill 是一个运行在 Claude Code 上的开源 Skill:导入微信、iMessage、短信、…

2026/10/3 0:00:27 阅读更多 →
45个经典Linux面试题:从命令到网络排障的完整考点解析

45个经典Linux面试题:从命令到网络排障的完整考点解析

刚开始带应届生的时候,我最头疼的就是他们拿着一摞Linux面试题背得滚瓜烂熟,一上机全露馅。后来自己从被面的人变成面别人的人,才慢慢摸清楚:Linux面试题考的根本不是答案本身,而是你面对一个不确定的系统问题时&#…

2026/10/3 0:01:28 阅读更多 →
SAP生产预留实战指南:MB21/MB23/MB25协同与MRP集成

SAP生产预留实战指南:MB21/MB23/MB25协同与MRP集成

简介:本资源是一份面向SAP ABAP开发人员、生产计划专员及ERP实施顾问的实操型操作指南,聚焦SAP生产预留核心业务场景,系统解决物料预留创建、查询、校验与批量处理等高频问题。文档以结构化方式覆盖预留背景原理、OMC2编码规则、工厂级参数配…

2026/10/3 0:01:28 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/10/3 9:14:33 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/10/3 9:47:50 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/10/3 9:42:31 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 10:36:31 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/3 9:42:35 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/3 9:42:36 阅读更多 →