高通平台KVM虚拟化踩坑:绕开QHEE把EL2还给Linux内核
事情要从一次不起眼的“板子到了”说起。我拿到手一块 Arduino 生态里的高通平台板卡计划在上面跑几个 KVM 虚拟机用来做内核调试和网络实验。刷完官方推荐的 Ubuntu 镜像我按常规操作把内核 KVM 相关的配置全部打开然后重启。结果/dev/kvm始终不存在qemu 直接报Could not access KVM kernel module: No such file or directory。第一反应是内核配置少了东西于是重新编译、重新刷折腾了一晚上KVM 依然“凭空消失”。直到我翻出串口日志看到 ABL 阶段那个不起眼的hyp镜像加载打印才想起高通平台上一件关键的事KVM 要的是 EL2而 EL2 可能已经被 Qualcomm QHEE 占掉了。这篇文章就围绕这条排查线展开。我会从 ARM 异常级别讲起说清楚 QHEE 和 KVM 的冲突到底出在哪里再给出操作链路如何让 ABL 跳过 QHEE 加载、如何把 EL2 交还给 Linux 内核、以及 KVM 起来之后如何验证。最终目标是让这块板子上的 KVM 真正跑起来而不是只停留在“理论上支持”。1. 现象入手板子到了KVM 却没到1.1 复现一下这个“灵异事件”刚刷好系统的时候我从dmesg里根本找不到任何 KVM 相关打印/dev/kvm也不存在。最开始我以为是应该把 KVM 相关模块拉起来但执行lsmod | grep kvm结果什么都没有。查看内核配置确认所有 KVM 选项已经编进去CONFIG_KVMy CONFIG_KVM_ARM64y按理说内核启动时应该自动完成 hypervisor 初始化并创建/dev/kvm设备节点怎么可能连日志都没有当时我还用了一个特别 x86 习惯的命令egrep -o (vmx|svm) /proc/cpuinfo在 ARM 上这个命令没有任何意义。后来我用lscpu看 CPU 的虚拟化特性显示硬件层面是支持虚拟化扩展的。这就更矛盾了CPU 支持内核支持但在 Linux 侧却完全没有 KVM 的痕迹。1.2 第一层猜测内核配置驱动冲突怀疑过是不是内核配置里存在 Kconfig 依赖问题。某些 ARM64 内核会把CONFIG_CAVIUM_ERRATUM_22375这类 CPU 缺陷修补选项跟虚拟化绑在一起如果你把CONFIG_ARM64_NVIDIA_TEGRA210_ERRATUM关了KVM 可能直接无法初始化。我也试过换成 BSP 自带的旧内核结果还是一样。1.3 串口日志暴露的线索最后让我确信是固件层问题的是串口日志。板子启动过程中会有一段 ABLApplication Bootloader打印里面有一行类似Load Hyp...甚至还有对应的基地址和大小。也就是说在 Linux 内核启动之前已经有一个叫hyp的固件镜像被加载进去了。这个hyp镜像就是 Qualcomm 的 hypervisor 固件也就是 QHEE。QHEE 先入为主地占据了 EL2Linux 内核启动后就只能待在 EL1。KVM 没有 EL2 根本没法工作。2. 根因分析QHEE 是怎么把 EL2“霸占”掉的2.1 ARM 异常级别到底是怎么回事要理解这个问题得先把 ARMv8-A 的异常级别弄清楚。ARM64 下有四层特权级别EL0用户态应用程序。没有硬件特权访问外设要委托内核。EL1操作系统内核。管理内存映射、进程调度、中断。EL2虚拟机监控器也就是 hypervisor 所在的层级。EL3安全监控器管理安全世界与普通世界切换。你可以把这四层想象成一栋写字楼EL0 是普通租户EL1 是每层楼的物业管理员EL2 是整个大楼的安保中心EL3 是物业总控。KVM 想做的是“整栋楼安保中心”的活也就是运行在 EL2对运行在 EL1 的 Guest OS 做隔离和管理。如果安保中心已经有 QHEE 在里面值班KVM 这些后来的团队连门都进不去。KVM 在 ARM64 上需要 EL2 的原因很具体它要操作HCR_EL2、VTCR_EL2、VTTBR_EL2这些虚拟化控制寄存器要配置 Stage-2 地址转换来实现 Guest 物理内存隔离还要在 EL2 处理各类 VM Entry/Exit。Linux 如果只能待在 EL1这些操作全部没有权限KVM 自然无法初始化。2.2 高通为什么要在开发板上放一个 QHEEQualcomm QHEE 全称 Qualcomm Hypervisor Execution Environment是高通安全固件体系的一部分。它在 EL2 运行提供多个执行环境之间的隔离能力。在高通手机上QHEE 是 DRM、安全支付、TEE 隔离等功能的基础在商业设备上它还承担防调试、防篡改的角色。对消费级手机来说QHEE 有价值但对我们这些想把板卡当虚拟化实验平台的人QHEE 就成了一个“占着茅坑不拉屎”的拦路虎。高通的正规启动链路通常是这样PBL - SBL/XBL - ABL - QHEE(hyp) - HLOS(Linux)ABL 加载完 QHEE 之后才把控制权交给 Linux。Linux 启动后看到的自己已经在 EL1 了KVM 只能向用户态报错。2.3 如何确认自己的板子确实被 QHEE 占用了如果你也遇到类似问题想确认是不是 QHEE 在捣乱有几个思路看串口日志里有没有Load Hyp或HypImage相关打印。在 Linux 启动早期日志里搜索CPU: All CPU(s) started at EL1或类似字段。如果显示内核启动在 EL1说明 EL2 已经被别人占用正常 KVM 可用时内核应该能从 EL2 启动。尝试加载 KVM 模块如果modprobe kvm直接返回Operation not permitted或者没有任何日志通常也是 EL2 不可用的表现。3. 动手前先拆明白高通启动链与固件分发3.1 高通平台常见的分区与固件镜像高通 QCS 系列、骁龙系列平台的分区里和启动相关的关键镜像通常有这些分区/镜像名作用xbl一级启动引导负责硬件初始化、DDR training 等ablApplication Bootloader基于 UEFI负责加载 Linux、fastboot、AVB 验证hyp存放 QHEE 固件也就是 EL2 hypervisortzTrustZone 固件运行在 EL3devcfg设备安全配置包含各类硬件安全开关bootLinux 内核镜像及其 ramdiskvendor_boot / dtbo厂商内核模块与设备树覆盖层ABL 是这条链路上最关键的“分岔口”之一。它决定加载哪些固件、用什么顺序加载、最终怎么跳转。高通的开发者分支 BSP 里ABL 和 lkLittle Kernel通常有开放源码而 xbl、hyp、tz 多数是闭源预编译镜像。3.2 “Patching QHEE”的真实操作对象是什么很多人看到“Patching Qualcomm QHEE”第一反应是拿十六进制编辑器去改hyp.mbn里的字节码。但对绝大多数板卡来说这条路根本走不通QHEE 是经过签名的固件镜像ABL/SBL 在加载时会做完整性校验你改一个字节设备可能就直接拒绝启动、进紧急下载模式。所以实际项目中所谓的“patch QHEE”通常不是改 QHEE 的二进制而是改加载决策。也就是让 ABL 不去加载 QHEE或者加载一个空的、无害的 hyp 分区从而让 Linux 拿到 EL2。这个思路在嵌入式圈子里很常见本质上是“跳过”而不是“篡改”。3.3 在 ABL 代码里找关键路径ABL 源码里跟 hypervisor 加载相关的模块常见命名有HypDxe、HypLaunch、LoadHyp等。不同型号、不同 BSP 版本差异很大但核心逻辑一般就是读某个分区做一个存在性判断然后调固件接口把镜像传到内存、设置跳转参数。你可以通过串口打印日志反向定位。如果日志里出现Load Hyp at 0x...就在源码里搜索这个字符串往上一路找调用链基本就能看到加载条件。常见的判断因素包括hyp 分区是否存在且非空设备是否符合开发者解锁状态某个配置项里是否允许 hypervisor 加载启动命令行里是否传入了特定参数4. 修补实操让 ABL 跳过 QHEE把 EL2 交还给 Linux4.1 动手之前的安全措施这部分操作会改动板子的启动固件变砖概率是实打实存在的。我强烈建议按这个顺序做准备准备 USB 转 TTL 串口模块接到板子调试串口上。没有串口日志做固件调试跟闭着眼开车没什么区别。确认板卡支持进入 ED LEmergency Download模式高通平台通常就是连接 USB 后按住特定按键或短接主板触点电脑端会出现Qualcomm HS-USB QDLoader 9008。备份一切能备份的分区。用fastboot能导出的分区全部导出不需要额外工具fastboot fetch 分区名在很多新版本 ABL 上都支持。4.2 源码编译路线修改 ABL 跳过 hyp 加载我自己走的是源码编译路线。拿到对应板卡的 ABL 源码后搜索 hyp 加载相关调用。以某个 BSP 为例代码里类似这样的路径if (is_hyp_present() !is_hyp_disabled()) { load_and_launch_hyp(); }最干净的做法是把条件改成if (0 is_hyp_present() !is_hyp_disabled()) { load_and_launch_hyp(); }或者直接删掉调用分支。编译 ABL 需要对应的交叉工具链和构建脚本。高通系 ABL 一般用 AArch64 GNU 工具链构建系统有的是 UEFI EDK2 风格有的是老的 Android make 风格。编译完成后会产出abl.elf或abl.img。4.3 二进制 patch 路线直接改 ABL 镜像如果你的 BSP 没有开放 ABL 源码就只能走二进制 patch。步骤大致是下载原厂 ABL 镜像用binwalk或者 QCom 的解析工具拆出代码段。在反汇编中定位 hyp 加载函数通常是字符串引用的交叉引用。找到分支指令把B.NE改成B或者相反让加载函数直接返回。重新打包调整签名位置。这条路风险更大因为 ABL 通常也有签名校验机制哪怕只是配置头校验过不了板子也可能直接不启动。我的建议是优先找板卡官方提供的开发者解锁固件不要自己硬搞二进制 patch。4.4 刷写与验证无论走哪条路最终刷写流程都类似。先进入 fastboot 模式fastboot devices备份原分区命名仅供参考具体以fastboot getvar all输出为准fastboot fetch hyp hyp.img fastboot fetch abl abl_backup.img刷入修改后的 ABLfastboot flash abl abl.img再刷入空 hyp用 1MB 全零文件即可具体大小对齐到原分区大小dd if/dev/zero ofempty_hyp.img bs1M count1 fastboot flash hyp empty_hyp.img然后重启看串口日志。正常情况下Load Hyp相关打印会消失Linux 启动早期日志会出现 CPU 从 EL2 启动的字段。5. 内核侧配置让 KVM 模块顺利初始化5.1 内核编译选项当 EL2 真正交还给 Linux 后KVM 才有机会初始化。内核编译选项需要满足几个关键项CONFIG_KVMy CONFIG_KVM_ARM64y CONFIG_VIRTUALIZATIONy CONFIG_ARM64_VHEy这里有个容易踩的细节CONFIG_ARM64_VHE是新版本内核的默认选项但如果你的板卡固件比较老VHE 相关行为可能和你预期不一样。启动日志里看到kvm: VHE mode detected或者类似字样才说明 KVM 确实拿到了 EL2。如果内核把 KVM 编成模块CONFIG_KVMm CONFIG_KVM_ARM64m需要在 initramfs 阶段预先加载模块否则根文件系统挂载后模块加载顺序可能出问题。推荐直接编进内核省事。5.2 设备树与 PSCI 的配合KVM 初始化还有一个隐藏依赖CPU 热插拔和 CPU idle 要走 PSCI 接口。高通平台通常把 PSCI 放到 EL3/TZ 里设备树必须包含正确的psci节点比如psci { compatible arm,psci-1.0; method smc; };如果method指定的是hvc但你的 QHEE 被跳过后没有对应处理程序内核启动早期可能报 PSCI 相关错误。这个节点值需要对照原厂设备树确认不要乱改。5.3 启动验证刷完新内核后检查以下几处dmesg | grep -i kvm ls -l /dev/kvm正常情况下 dmesg 里应该有 KVM 初始化成功的打印。如果没有/dev/kvm节点但内核日志正常可以手动创建mknod /dev/kvm c 10 232 sudo chmod 666 /dev/kvm在 systemd 较新的系统上最好确认/dev/kvm是不是被95-kvm.rules之类的规则漏掉了如果规则缺失上述手动创建只是临时手段。6. 用 KVM 拉起第一台 aarch64 虚拟机6.1 安装用户态工具板子上需要安装 qemu 和 libvirt 相关组件apt install qemu-system-arm libvirt-daemon-system virtinst如果你是极简主义者也可以不装 libvirt只用 qemu-system-aarch64 命令行。6.2 准备 Guest 镜像选一个 ARM64 的 Ubuntu/Debian cloud image或者直接下载官方提供的 arm64 安装器 ISO。Cloud image 更省事直接拿来就能当系统盘启动。如果下载的是 qcow2 格式可以先用qemu-img扩容qemu-img create -f qcow2 -b ubuntu-cloud.qcow2 -F qcow2 cloud-run.qcow2 20G6.3 命令行启动虚拟机一个能启动并验证 KVM 生效的最小命令大概是qemu-system-aarch64 \ -machine virt,gic-version3 \ -cpu host \ -enable-kvm \ -smp 2 \ -m 2048 \ -kernel vmlinuz \ -initrd initrd.img \ -append root/dev/vda1 consolettyAMA0 \ -drive filecloud-run.qcow2,formatqcow2,ifvirtio \ -netdev user,idnet0 \ -device virtio-net-pci,netdevnet0 \ -nographic注意-cpu host只有在 KVM 可用时才能正常工作。如果 KVM 没起来qemu 会回退到 TCG 纯模拟此时需要把-cpu host改成-cpu cortex-a72等具体型号。但那样性能会差一个量级。6.4 怎么确认虚拟机真的被 KVM 加速进入 Guest 后看系统里的 CPU 型号和时钟频率如果显示和 Host 一样基本可以确定 KVM 生效。也可以回到宿主机上看 kvm 统计cat /sys/kvm/mmu/stat_* 2/dev/null | head有持续的页表统计增加说明真的有虚拟化在这边工作。更直观的办法是跑一个轻微计算负载对比 TCG 模拟和 KVM 加速的耗时差异。我实测过类似场景KVM 加速后性能能接近原生TCG 模拟则慢到难以接受。7. 踩坑记录从串口黑屏到 QDLoader 90087.1 最惊险的一次刷完 ABL 后直接黑屏我第一次刷入修改过的 ABL 后板子重启直接没有任何输出串口完全安静。当时第一反应是 ABL 编译版本不对或者跳过了某个必要初始化步骤。由于板子连 fastboot 都进不去常规救砖手段全部失效。只能长按进入 EDL 模式电脑端识别出Qualcomm HS-USB QDLoader 9008 (COMxx)然后用 QFIL 加载原始的 rawprogram0.xml 和 patch0.xml才把板子救回来。这个经历让我意识到两件事第一改动启动固件前必须先确认 EDL 通道可用第二ABL 源码编译不是“编译过就等于能启动”ABL 里有大量跟平台硬件初始化相关的项改错一个宏定义可能连串口初始化都跑不到。7.2 hyp 分区不能随便全零化有人以为直接刷一个全零的 hyp 分区就能禁用 QHEE。实测中某些 ABL 版本会在加载 hyp 前检查分区头部的魔法数不是“非空就行”而是“必须是合法 header”。如果只是全零ABL 可能直接判定固件损坏拒绝进入 HLOS。所以正确顺序是先改 ABL 让它跳过加载逻辑再刷空 hyp 作为兜底而不是反过来。7.3 内核 panic 在 psci 相关代码上跳过 QHEE 后第一次进 Linux 加载 KVM 倒是正常但一执行 CPU hotplug 就 panic。排查下来是设备树里psci节点的method是smc而 QHEE 提供的服务被跳过之后某些 EL3 接口依然存在但返回值和之前完全不同导致内核的 CPU 开启流程卡死。解决办法是选择内核配置里CONFIG_ARM64_PSCI保持开启并且优先用 BSP 自带的设备树不要自己从零改。7.4 别在“必须稳定运行”的设备上做实验这段经验几乎是废话但确实有人会忽略如果你只有这一块板子而且后续还要靠它输出成果不要上来就动 ABL。先用一份普通镜像把 fastboot 和 EDL 恢复路径练熟再考虑 QHEE 的修补。我自己后来备了一块同型号板子专门做固件实验才敢放手改。最后再分享一点个人体会在高通平台上让 KVM 跑起来真正的难点不在内核、也不在 qemu而在于启动链上 EL2 的归属权。搞懂 ARM 异常级别和 ABL 加载逻辑之后整个问题就从一个“玄学问题”变成了一个可控的工程问题。如果你也想在这类板卡上玩虚拟化我建议从这篇文章里的思路入手先别追求什么高级特性就盯着 EL2 从固件手里拿回来这件事拿回来 KVM 自然就醒了。

相关新闻

嵌入式C语言四大关键字:static、const、volatile、extern原理剖析

嵌入式C语言四大关键字:static、const、volatile、extern原理剖析

1. 面试场上,这四个关键字到底在考什么做嵌入式开发这些年,我面试过不少候选人,也被人面试过。每次C语言相关的题目里,static、const、volatile、extern这四个关键字几乎是必考题。很多简历上写着“精通C语言”的候选人&#xff0…

2026/10/18 8:59:36 阅读更多 →
校园物联网边缘网关实战:协议适配、断网续传与本地联动

校园物联网边缘网关实战:协议适配、断网续传与本地联动

在校园这类场景里做物联网落地,最大的感受就是:设备比想象中杂,网络比想象中差,而需求方永远希望“断网了也要能用”。前两年我给校区做过一套环境监测与设备联动系统,教室、实验室、图书馆加起来一百多个点位&#xf…

2026/10/19 1:12:58 阅读更多 →
百元档降噪耳机实测:熙彼儿WS200Pro的降噪深度与LDAC音质全解析

百元档降噪耳机实测:熙彼儿WS200Pro的降噪深度与LDAC音质全解析

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

2026/10/19 1:13:03 阅读更多 →

最新新闻

OpenProject 上手指南:免费开源自托管项目管理

OpenProject 上手指南:免费开源自托管项目管理

OpenProject 上手指南:免费开源自托管项目管理 【免费下载链接】openproject OpenProject is the leading open source project management software for product, project and portfolio management. A powerful Jira alternative with agile planning, issue trac…

2026/10/20 10:53:45 阅读更多 →
Android 安全校验下沉到原生层:防 patch 与构建期自动化

Android 安全校验下沉到原生层:防 patch 与构建期自动化

把判断写进机器码,再把指纹维护交给构建流程,让 patch 无利可图。前言 签名校验落地后,很多团队会松一口气:重打包必然重签名,重签名必然改指纹,运行时比对一下就能发现。逻辑没错,问题出在校验…

2026/10/20 10:53:45 阅读更多 →
三步装好 meta-overlayfs 元模块:让 KernelSU 模块真正改到 /system

三步装好 meta-overlayfs 元模块:让 KernelSU 模块真正改到 /system

三步装好 meta-overlayfs 元模块:让 KernelSU 模块真正改到 /system 【免费下载链接】KernelSU A Kernel based root solution for Android 项目地址: https://gitcode.com/GitHub_Trending/ke/KernelSU KernelSU 模块对 /system 的修改,要靠元模…

2026/10/20 10:53:45 阅读更多 →
LSTM与Transformer时间序列预测实战对比:源码解析与调参避坑指南

LSTM与Transformer时间序列预测实战对比:源码解析与调参避坑指南

简介:面向时间序列预测任务的LSTMTransformer混合模型PyTorch实现,适合需要多特征输入、单变量输出场景的研究者与开发者;可直接迁移到风电、光伏、寿命预测、浓度预测等项目中,也适合作为学习Transformer与LSTM结合的入门范例。压…

2026/10/20 10:53:45 阅读更多 →
如何快速部署EspoCRM开源CRM:从零到能跑生产业务

如何快速部署EspoCRM开源CRM:从零到能跑生产业务

如何快速部署EspoCRM开源CRM:从零到能跑生产业务 【免费下载链接】espocrm EspoCRM – Open Source CRM Application 项目地址: https://gitcode.com/GitHub_Trending/es/espocrm EspoCRM是一款免费开源的客户关系管理系统(CRM)&#…

2026/10/20 10:53:45 阅读更多 →
防误删+高效查单双buff加持!快递批量查询高手轻松搞定物流管理

防误删+高效查单双buff加持!快递批量查询高手轻松搞定物流管理

电商大促过后,面对成百上千条快递单号,手动逐单查询不仅耗时费力,稍不注意手滑点错清空表格,辛苦整理的全部物流数据就会瞬间丢失,后续对账、售后跟进全乱套。今天就给大家带来一套兼顾效率与数据安全的保姆级教程&…

2026/10/20 10:52:44 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

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

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

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

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

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

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 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/20 10:02:08 阅读更多 →
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/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练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/20 9:50:45 阅读更多 →