树莓派Linux 4.19.y内核源码编译与设备树overlay实战指南
简介这是一份树莓派 Linux 内核 4.19.y 分支的完整源码包面向嵌入式开发者、树莓派爱好者和内核学习人员可满足内核定制、驱动编写、系统调优、交叉编译和底层原理研究等需求。压缩包为 zip 格式共包含约 2000 个文件整体大小约 193.93MB文件类型以 C 语言源码、头文件为主同时涵盖 Makefile 构建脚本、DTS 设备树文件、Kconfig 配置选项以及少量文档和辅助脚本共同构成了一套完整的 Linux 内核开发支持体系。目前已有 597 人浏览学习。通过研读这套源码读者能够理解树莓派硬件与内核各子系统的对应关系掌握设备树对板级硬件配置的作用并参考其中的驱动实现来编写自定义驱动或根据实际需求配置裁剪内核功能。对于希望深入 Linux 内核底层、开展嵌入式系统开发实践的人来说这是一份兼具理论深度和实用价值的基础资料。1. 树莓派linux源码4.19.y为什么这个老内核分支到今天还有人在追“树莓派linux源码版本4.19.y”光看这个名字很容易把它和 Linux 主线仓库里那个 4.19.y 的 tag 混为一谈。真正做产品的人知道区别在哪树莓派官方在主线 4.19.y 之上叠了一层自己的补丁集GPU 显示栈、DWC2 USB、设备树 overlay、GPIO 复用逻辑全在这层补丁里。很多在 4.19.y 上稳定跑了好几年的老驱动升到 5.x 之后反而没人维护了反过来不少第三方传感器和板级驱动只在 4.19.y 上验证过。所以做内核编译、驱动适配、镜像定制和老设备维护的人手上必须有一条拿来就能用的 4.19.y 官方分支。这篇我从拿对源码讲起一路到配置、编译、设备树最后把最容易踩的坑按现象列给你。2. 拿对分支与源码树莓派官方不是直接用 linus 的 4.19.y第一次动手前我一般会先讲清楚为什么不能拿主线源码来凑合。树莓派的 4.19.y 分支不是简单改了版本号它带着一套独立维护的补丁基线。主线 Linux 的 4.19.y tag 里只有通用驱动没有树莓派那套 BCM2835/2836/2837/2711 的外设支持也没有 VC4 GPU 开源驱动的后续修复。最直接的例子主线 4.19.y 里 ARCH_BCM2835 的菜单组织和树莓派分支完全不同用主线的 defconfig 编出来的 zImage放到树莓派上就算能启动USB、SD 卡、GPIO 的行为也会和官方固件预期不一致。所以只有两条路要么直接拉官方维护的源码要么把官方补丁手工合进主线树。后者工作量巨大而且每次主线更新都要重合一遍我试过两次就放弃了。常见做法是直接拉官方分支成本最低后面改设备树、编驱动模块都在同一棵树上做不会出现版本错位的问题。2.1 两棵树不能混官方 rpi 分支与 vanilla 主线的关系树莓派官方会同时维护多条内核分支4.19.y 是其中一个长期维护线。它现在看起来老但在工控设备和定制产品里生命周期非常长原因是它把稳定性和新驱动放在一个相对平衡的位置上。官方分支里有很多主线没有或不完整的驱动目录比如 VC4 GPU、V3D、DWC2 的树莓派定制部分这些在主线里往往只到“能编译”的程度距离“在板子上稳定工作”还有距离。我见过有人拿 vanilla 主线的 4.19.y tag 编出来启动后网络不通、USB 识别异常查了半天发现是驱动差异不是配置问题。对外设驱动开发来说必须在官方 rpi-4.19.y 上开自己的开发分支否则后面合并补丁会合到怀疑人生。官方分支的提交历史里能明显看到“bcm2711”“bcm2835”“vc4”这些关键词这是判断你拉对树的一个信号。2.2 拉源码的最小命令git clone 的三个参数坑# 拉取官方 4.19.y 分支仓库地址换成团队内能访问的镜像即可 RASPI_REPO你的镜像地址/linux.git git clone --depth1 --branch rpi-4.19.y ${RASPI_REPO} raspberrypi-linux cd raspberrypi-linux git log --oneline -1--depth1只拉最浅历史好处是省带宽代价是后面想切换其他 tag 或者用git describe做版本判断时会缺少必要的提交信息。我一般首次拉取不加深度的限制日常同步增量更新时才用--depth1。--branch rpi-4.19.y是最关键的参数很多第一次拉的人写成4.19.y结果拉到的是主线 tag目录结构和驱动补丁对不上编到一半才发觉。仓库地址替换成你团队内能访问的官方源码镜像只要带rpi-4.19.y分支就行。拉完以后先确认分支状态git branch -a | grep 4.19 git log --oneline -1注意官方仓库当前默认分支不是 4.19.y直接git clone不带--branch会拉到更新的维护分支那个分支的补丁基线和 4.19.y 不同不适合复现 4.19.y 环境。所以分支名必须写全。2.3 源码树里值得先看的四个目录目录看什么arch/arm/configs板级 defconfigbcmrpi_defconfig、bcm2709_defconfig、bcm2711_defconfigarch/arm/boot/dts/overlays所有 overlay 的 dts 源文件和编译产物 dtbodrivers/gpu/drm/vc4GPU 显示相关驱动4.19.y 上比较稳定Documentation/devicetree/bindings写新 overlay 时对照属性名和节点格式这四个目录基本划出了整棵树的边界。看到一个设备树属性不确定对不对去 bindings 里查看到一个外设没反应去 overlays 里找有没有对应 dtbo。4.19.y 的 overlay 机制在文档里写得比较完整新内核反而把 overlay helper 重构过老资料不一定能对上新写法。3. 配置与编译全流程从 defconfig 到能跑的内核镜像源码拿到后下一步是配置和编译。这一步失误率最高因为很多人沿用主线内核的习惯直接make defconfig编出来的东西放到树莓派上经常起不来。4.19.y 的官方源码里给每一代板子都准备了独立 defconfig选对板型配置比后续手调参数重要得多。3.1 配置三选一板级 defconfig、menuconfig 与自定义 configcd raspberrypi-linux make ARCHarm bcm2711_defconfig make ARCHarm menuconfig第一行根据板型选择树莓派 1 用bcmrpi_defconfig树莓派 2/3 用bcm2709_defconfig树莓派 4 用bcm2711_defconfig。第二行是打开交互式配置界面在板级配置之上做微调比如加文件系统支持、去掉用不到的驱动。menuconfig 保存后生成的是全量.config不是增量补丁但建议用savedefconfig把缩略配置单独存一份方便以后重新生成make ARCHarm savedefconfig cp defconfig arch/arm/configs/raspberrypi_my_defconfig这样以后直接make ARCHarm raspberrypi_my_defconfig就能回到当前状态不用再手动点一遍菜单。我自己的习惯是每调完一组配置就存一次相当于给内核配置做版本备份。3.2 交叉编译还是板端编译先算时间账在树莓派 4 上全量编译 4.19.y快则四五十分钟慢则一个多小时交叉编译一般十几分钟就能出 zImage。常见做法是准备一台 Linux 开发机装 armhf 工具链。Ubuntu/Debian 系可以用包管理器直接装装完先验证arm-linux-gnueabihf-gcc --version aarch64-linux-gnu-gcc --version有版本输出说明工具链可用。一个容易忽略的点是工具链的 glibc 版本不能太新部分发行版自带的工具链在编老内核时会出现隐式函数声明之类的错误后面排错章节会细说。我先给推荐的最小环境变量export ARCHarm export CROSS_COMPILEarm-linux-gnueabihf- export KERNELkernel7ARCHarm表示编 32 位内核对应 32 位用户空间如果做 64 位改成ARCHarm64、CROSS_COMPILEaarch64-linux-gnu-镜像名对应kernel8。KERNEL变量在最后打包时用提前设好省得每次敲。3.3 最小编译命令与输出物落盘make -j4 zImage modules dtbs mkdir -p /tmp/pi-modules make INSTALL_MOD_PATH/tmp/pi-modules modules_install ls /tmp/pi-modules/lib/modules/zImage是内核本体modules是外设驱动模块dtbs是设备树二进制。INSTALL_MOD_PATH指定模块安装目录这是我一直推荐的做法不要把模块直接装到开发机的/lib/modules既不污染本机拷到板子也方便。编译完成后确认产物ls arch/arm/boot/zImage ls arch/arm/boot/dts/bcm2711-rpi-4-b.dtb ls arch/arm/boot/dts/overlays/*.dtbo把这几个文件同步到 SD 卡时要注意zImage 通常要经过一个打包步骤变成kernel7.img常见做法是用树莓派固件里的mkknlimg处理如果你的固件版本支持直接从/boot加载 zImage也可以跳过这个步骤。设备树文件建议整目录覆盖不要只拷一个 dtb因为启动时固件会按 config.txt 的配置读取对应 dtbo新旧版本混用会导致外设行为异常。注意很多人只换内核不换 overlay新旧 dtbo 和内核里的设备树解析接口不匹配系统起来后 USB 或 GPIO 表现得很奇怪这不是驱动问题是设备树版本不一致。4. 设备树与 overlay4.19.y 上最容易出事的两个大头编译通过只算走完一半。树莓派体系里最特殊的是设备树 overlay 机制4.19.y 上要驱动某个外设三分靠内核配置七分靠设备树。很多新手改完 config.txt 发现没生效回头查代码其实是 overlay 没对上或没被正确加载。4.1 overlay 的编译与装载config.txt 一行背后的机制overlay 的源文件在arch/arm/boot/dts/overlays/目录下命名一般是xxx-overlay.dts编译后生成xxx.dtbo放到板子的/boot/overlays/目录。启动时固件读取/boot/config.txt遇到dtoverlayxxx就加载对应的 dtbo 并合并进系统设备树。make ARCHarm dtbs sudo cp arch/arm/boot/dts/overlays/*.dtbo /boot/overlays/config.txt 里的写法# 启用自定义 overlay不带 .dtbo 后缀 dtoverlaymy-overlay拷贝时别只拷单个文件因为一个外设的 overlay 经常依赖其他基础 overlay只拷一部分会导致依赖缺失启动日志里只留一条含糊的“failed to apply”消息。dtbo 文件名不带后缀config.txt 里不能写成my-overlay.dtbo多写个后缀反而找不到文件。4.2 验证驱动是否加载三件套设备树和内核有没有真正配合上用下面三条命令查最快cat /proc/device-tree/model dmesg | grep -E overlay|dwc2|vc4|bcm ls /sys/bus/platform/devices/第一条看系统识别的板型如果显示的内容和你手里的板子对得上说明基础设备树没问题第二条看驱动 probe 日志能直接看到哪个驱动加载失败、失败原因是找不到中断号还是地址冲突第三条看平台设备节点有没有生成节点存在但驱动没 probe问题在内核配置节点本身不存在问题在 overlay 没合入。这个排查顺序能帮你把问题快速定位到设备树层还是驱动层。4.3 在 4.19.y 上二次开发三个边界第一个边界是设备树语法。4.19.y 的 overlay 写法和主线基本一致但 fragment 的组织方式有一套固定套路建议从现有 overlay 复制后修改而不是从零手写能省掉大量语法错误。第二个边界是驱动模块必须在同一棵源码树编译把主线 Linux 源码编出来的 .ko 塞到树莓派 4.19.y 系统里多半会报 version magic mismatch模块直接被拒绝加载。第三个边界是新增节点一定要在编译阶段验证语法make dtbs 报错时不要跳过否则启动时 overlay 会静默失败。单独编一个模块的标准做法make ARCHarm Mdrivers/net/ethernet/some-driver modulesM指向驱动子目录编出来的.ko拷贝到板子的/lib/modules/$(uname -r)/extra/下执行depmod -a再加载。4.19.y 分支对M的 Kbuild 支持很完整这个流程比改整个内核快得多。5. 树莓派 4.19.y 编译路上最常翻的 5 个车这章写几个我实际遇到过的现象每条按“现象 → 原因 → 解决”列出你在自己机器上对号入座就行。5.1 menuconfig 保存后行为没变现象改了内核配置并保存重新编译烧录跑起来的行为和之前一模一样好像配置没生效。 原因编译目录里有旧的.config残留或者make clean把配置清了但菜单里保存的是默认值。更隐蔽的情况是改了内核选项但没重新编 modules旧模块还在 rootfs 里驱动照样加载老版本。 解决先彻底清理再重新走一遍make mrproper make ARCHarm bcm2711_defconfig make ARCHarm menuconfig make -j4 zImage modules dtbs改配置前先备份一份.configcp .config .config.bak这是最保险的后悔药。5.2 启动卡在 VFS: Unable to mount root fs现象内核启动到一半控制台输出VFS: Unable to mount root fs然后直接 panic。 原因rootfs 里没有对应内核版本的/lib/modules或者根文件系统驱动被编成了模块而不是编进内核。4.19.y 默认配置里 EXT4 通常是编进内核的但如果你在 menuconfig 里改过文件系统选项容易把它改成m。 解决确认.config里CONFIG_EXT4_FSy而不是m。如果是模块方式就必须准备 initramfs 来加载模块否则内核根本找不到根文件系统。5.3 设备树 overlay 改了没反应现象在 config.txt 里加了dtoverlayxxx重启后设备节点不存在外设没被驱动。 原因dtbo 没拷到/boot/overlays/config.txt 里拼写带了.dtbo后缀或者文件拷完没有 sync 就直接拔卡。boot 分区是 vfat拷贝后缓存没落盘重启就丢。 解决ls /boot/overlays/ | grep my-overlay cat /boot/config.txt确认文件名和后缀之后重新拷贝并执行sync再重启验证。5.4 insmod 报 invalid module format 或 version magic mismatch现象模块编译成功后拷到板子insmod直接拒绝加载提示 version magic mismatch。 原因系统跑的是 64 位内核编译环境却用ARCHarm编了 32 位模块或者板子系统内核版本和编译源码树版本不一致。 解决先看系统内核版本和模块的 vermagic 是否一致uname -r modinfo xxx.ko | grep vermagic两者必须完全对应。模块一定要在跑着 4.19.y 的那同一个源码分支上编译不能拿主线 4.19.y tag 的源码树来编。5.5 编译到 drivers/gpu/drm/vc4 附近报错现象编译进度走到drivers/gpu/drm/vc4或drivers/staging/vc04_services时报错错误信息看着像语法问题但代码本身没改过。 原因源码树不完整之前中断的 clone 或 fetch 留下了缺失文件或者工作目录里混入了之前 make 产生的中间产物。 解决先检查目录状态再干净重编git status git fetch make clean make -j4 zImage modules dtbs如果git status显示大量修改文件说明编译产物污染了源码目录先make clean再继续。6. 验证与反哺把 4.19.y 用顺手的几个小习惯6.1 用 make savedefconfig 管好内核配置make ARCHarm savedefconfig cp defconfig arch/arm/configs/某一板型_defconfig这个命令把当前.config缩成一个最小可读配置以后直接make 某一板型_defconfig就能回到当时的状态。它比备份整个.config文件更干净也更容易用 diff 工具对比配置差异。我在 4.19.y 上改配置前一定会先跑一次这个命令。6.2 升级内核前备份模块目录sudo cp -r /lib/modules/$(uname -r) /lib/modules/$(uname -r).bak把自编译模块放到/lib/modules/$(uname -r)/extra/然后执行depmod -a。系统起不来时切回备份模块目录比重新编译快得多。这个习惯在很多内核版本上都通用但在 4.19.y 这种需要长期维护的分支上尤其有用。6.3 交叉编译的验证节奏交叉编译十几分钟就能出一版板端编一次够交叉编三轮。我的一般节奏是改一批配置或驱动就编一次先看 zImage 和 dtbs 是否通过再编 modules最后统一拷到 SD 卡。验证时先看启动日志里的 probe 消息再看/sys/bus/platform/devices/里有没有新设备节点而不是直接测外设功能能节省大量排查时间。在我自己的习惯里4.19.y 这类分支最怕的不是内核老而是你对它不够熟。老内核的资料多、踩过坑的人也多几乎每个报错都能找到对应记录。真正让我吃过亏的反而是改 menuconfig 没存盘就重启编出来的内核行为跟预期差很远最后只能重新来。从那以后每次动配置前的第一件事就是跑一遍make savedefconfig。这个方法也分享给你希望帮到你。本文还有配套的精品资源点击获取

相关新闻

信用卡风控为何首选梯度提升树与XGBoost实现

信用卡风控为何首选梯度提升树与XGBoost实现

1. 项目概述:为什么风控模型非得用梯度提升树不可?“信用卡风控——梯度提升树方法Python实现”这个标题,乍看是教你怎么写几行代码跑个模型,但实际背后是一整套银行级风险决策逻辑的微型复刻。我带过不少刚入行的数据分析岗新人&…

2026/10/14 18:17:42 阅读更多 →
mcp-server 快速开始教程:从构建 JAR 到加载扩展,5 步让 Claude 与 Burp 对话

mcp-server 快速开始教程:从构建 JAR 到加载扩展,5 步让 Claude 与 Burp 对话

【免费下载链接】mcp-server MCP Server for Burp 项目地址: https://gitcode.com/gh_mirrors/mcpserver1/mcp-server 点击查看 免费下载 mcp-server(MCP Server for Burp)是 PortSwigger 官方出品的 Burp Suite 扩展,它通过 Mod…

2026/10/14 18:17:42 阅读更多 →
种植体耐久性怎么判断更稳

种植体耐久性怎么判断更稳

种植体耐久性直接关系到种植牙的远期使用表现。判断耐久性是否稳定,不能只看单一指标,而应从材料强度、骨结合效率与长期疲劳性能三个维度综合评估。近年来,纳米晶钛种植体在材料层面的升级,为耐久性判断提供了新的参考坐标。材料…

2026/10/14 18:16:41 阅读更多 →

最新新闻

48V输入LDO稳压芯片方案:PW8600 80V耐压/70V宽压/1.8μA低功耗电路详解

48V输入LDO稳压芯片方案:PW8600 80V耐压/70V宽压/1.8μA低功耗电路详解

LDO 稳压芯片 选型助手 面向硬件工程师与电子研发人员,通过输入电压 / 输出电压快速匹配合适的 LDO 型号, 并提供完整参数查阅、外围器件建议与型号清单,让选型一步到位。 传统 LDO 耐压不足 5V/6V LDO 无法直连 24V/36V/48V 总线&#xff0c…

2026/10/14 21:37:29 阅读更多 →
零依赖单测:用Node内置测试运行器替代Mocha、Chai与Sinon

零依赖单测:用Node内置测试运行器替代Mocha、Chai与Sinon

我最近接手一个老服务,第一件事不是看业务代码,而是先摸一遍它的测试链路:Mocha 负责跑,Chai 管断言,Sinon 做 mock,再加一个 nyc 统计覆盖率。功能倒是都能满足,但每次新同事 clone 项目光装依…

2026/10/14 21:37:29 阅读更多 →
UE4塔防开发实战:士兵AI、塔防调度与伤害结算管线

UE4塔防开发实战:士兵AI、塔防调度与伤害结算管线

简介:这是一份基于Unreal Engine 4.22开发的3D塔防游戏完整工程,面向希望学习UE4游戏开发、塔防玩法实现与C编程的开发者,尤其适合具备一定引擎基础、想通过实战项目理解RTS与塔防机制的中级学习者。资源以zip压缩包形式提供,整体…

2026/10/14 21:37:29 阅读更多 →
dig_cli鸿蒙化适配:从DNS报文到内网域名治理的完整实践

dig_cli鸿蒙化适配:从DNS报文到内网域名治理的完整实践

1. 先说结论:为什么我要做 dig_cli 的鸿蒙化适配今年有一个项目,要在鸿蒙生态里做一个面向内部网络管理场景的域名解析诊断工具。需求本身很朴素:管理员输入一个域名,工具能快速给出权威解析结果、响应延迟分布、不同记录类型的查…

2026/10/14 21:37:29 阅读更多 →
SpringBoot+Redis+硬件项目启动报错排查与避坑指南

SpringBoot+Redis+硬件项目启动报错排查与避坑指南

接手带硬件对接的SpringBoot项目,启动时报错,这大概是后端开发里最磨人的场景之一。尤其是应用里同时压着Redis、网关路由、硬件设备初始化三块内容的时候,启动失败的原因往往不是某个单点组件坏了,而是链路耦合出的连锁问题&…

2026/10/14 21:37:29 阅读更多 →
基于Flutter与OpenHarmony的油耗追踪App开发实践

基于Flutter与OpenHarmony的油耗追踪App开发实践

最近在整理加油小票的时候我突然意识到一个问题:我根本不知道自己这台车的真实油耗是多少。仪表盘上那个瞬时油耗和表显平均油耗,短期看看还行,时间一长就会发现它跟实际开销对不上——特别是冬天冷启动、夏天开空调、周末跑高速这几类场景混…

2026/10/14 21:36:28 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 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/13 22:01:27 阅读更多 →
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/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练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/14 7:53:34 阅读更多 →