南京大学ICS PA实验:NEMU+nanos-lite全栈系统实践指南
简介本资源是南京大学ICS课程PA实验的完整教学实践包面向计算机系统、操作系统与编译原理方向的本科生及自学者聚焦底层系统开发能力培养。压缩包含487个文件主体为188个C源码、145个头文件h、48个Makefile及32个mk构建脚本辅以汇编s、Shell初始化脚本sh、RISC-V配置文件defconfig、README说明文档md及轻量内核相关代码nanos-lite、Navy-Apps整体741KB结构清晰、模块完整便于分层理解与渐进式实践。已有560人学习下载覆盖Nemu虚拟机调试、抽象机实现、Make自动化构建、nanos-lite内核裁剪与应用开发等核心环节提供可直接编译运行的工程框架、详尽的环境配置指引及典型问题注释是深入掌握计算机系统软硬件协同设计的优质实操素材。1. 南京大学ICS课程PA实验不是“交作业就完事”的压缩包而是能跑通NEMUnanos-lite Navy-Apps的完整系统级实践闭环你手里的这个南京大学ICS课程 PA实验部分-内含源码和说明书.zip表面看是课程设计压缩包实际是一套可编译、可启动、可调试的微型计算机系统教学栈——它不是让你改几行代码交差的“课程作业”而是从抽象机AM定义出发经NEMU模拟器加载运行nanos-lite轻量内核再在上面跑起Navy-Apps应用的全链路实操环境。我去年带学生复现时发现90%的人卡在make run报错“no rule to make target ‘nemu’”根本原因是没意识到这个PA不是单个程序而是一个四层嵌套结构AM抽象机接口层→ NEMUx86-64模拟器层→ nanos-lite微内核层→ Navy-Apps用户态应用层。它专为《计算机系统基础》类课程设计适合已掌握C语言指针与内存布局、了解ELF格式、能看懂Makefile依赖关系的本科生或自学者。如果你正被“操作系统课设做不出来”困扰或者想用真实代码理解“CPU如何执行第一条指令”这个资源就是你缺的那块拼图——它不教API调用它让你亲手把init.sh里那句./nemu/build/nemu -b ./nanos-lite/build/ref.img变成屏幕上跳动的[NANOS] booting...。2. 拆包即实战从7个关键文件定位系统骨架与启动路径这个压缩包看似杂乱Courier系列字体、projectn.bmp、stb_vorbis.c等实则每份文件都锚定在系统某一层。别急着编译先用tree -L 2理清结构——你会发现它天然按教学逻辑分层而非按文件类型归类。下面我带你逐个击破核心文件明确它们在四层架构中的坐标和不可替代性。2.1init.sh不是普通脚本而是整个PA的“启动总控开关”#!/bin/bash # init.sh 核心片段已简化 export AM_HOME$(pwd)/am export NEMU_HOME$(pwd)/nemu export NANOS_HOME$(pwd)/nanos-lite export NAVY_HOME$(pwd)/navy-apps cd $NEMU_HOME make clean make -j$(nproc) cd - cd $NANOS_HOME make clean make -j$(nproc) cd - cd $NAVY_HOME make clean make -j$(nproc) cd - $NEMU_HOME/build/nemu -b $NANOS_HOME/build/ref.img提示init.sh本质是环境变量注入 四层构建顺序控制 最终启动命令。它强制要求你必须按AM→NEMU→nanos-lite→Navy-Apps顺序编译因为nanos-lite依赖AM生成的libam.aNEMU依赖AM定义的am.h而Navy-Apps链接时需nanos-lite/include/下的头文件。跳过init.sh直接make某个目录大概率失败。2.2README.md藏着三个被忽略的关键配置项打开README.md重点看“Build Run”章节下的三处细节非文字描述是具体参数配置项位置默认值修改建议作用AM_ARCHam/Makefile第12行x86-nemu若用ARM开发板需改为arm-qemu决定抽象机目标平台影响am/src/下汇编实现NANOS_CONFIGnanos-lite/Makefile第8行config-x86学习中断时需切换为config-x86-interrupt控制nanos-lite是否启用IDT、PIC等硬件抽象NAVY_APPnavy-apps/Makefile第5行hello实验进阶后改为shell或tetris指定最终烧录到ref.img的应用入口注意README.md里写的make run命令实际是调用nemu的-b参数加载ref.img。这个镜像由nanos-lite的Makefile通过genimg.py脚本生成而genimg.py又硬编码了navy-apps/build/hello.bin的加载地址0x80400000。若你改了NAVY_APP但没重新makenavy-appsref.img里还是旧的hello程序。2.3stb_vorbis.c与lstrlib.c暴露了PA对“最小化依赖”的极致追求这两个文件出现在根目录很反常——它们既不属于AM也不属于NEMU。查navy-apps/Makefile发现APP_OBJS $(APP_SRC:.c.o) APP_OBJS ../stb_vorbis.o ../lstrlib.o # 关键手动链接stb_vorbis.c一个单文件Vorbis解码库音频格式被music应用调用。它不依赖libc只用malloc/memcpy而nanos-lite的libc实现恰好提供这两个函数。lstrlib.cLua字符串库精简版被lua应用调用。它规避了标准Lua对stdio.h的依赖改用nanos-lite的sys_write系统调用。这说明PA的设计哲学所有第三方代码必须满足“零libc依赖”或“仅用nanos-lite提供的syscall”。你若想加新应用比如用SDL绘图必须先确认SDL是否能剥离pthread/X11依赖——否则make会因找不到-lpthread报错。2.4 Courier系列BDF字体为什么需要7个尺寸Courier-*.bdf是位图字体文件被nanos-lite的fbdev驱动用于控制台渲染。查看nanos-lite/drivers/fbdev.c// fbdev.c 片段 static const char *font_paths[] { fonts/Courier-13.bdf, // 默认字体 fonts/Courier-12.bdf, // 字号缩放时备用 // ... 其他尺寸 };nanos-lite的fbdev驱动支持动态字号切换通过ioctl传参但不支持字体缩放算法只能预载不同尺寸的BDF文件。projectn.bmp是启动logo位图被nanos-lite/boot/start.S在boot_print_logo()中直接写入显存地址0xB8000与字体渲染无关。所以删掉Courier-7.bdf不会导致编译失败但当你在shell里输入setfont 7时屏幕会变空白——因为驱动找不到对应文件。这是PA里少有的“运行时依赖”而非编译时依赖。3. 编译四连击AM→NEMU→nanos-lite→Navy-Apps的依赖链与参数陷阱PA的构建不是并行任务而是严格线性的依赖链。我见过太多人cd nemu make失败后骂NEMU作者其实问题出在AM没编译——因为NEMU的Makefile第一行就include ../am/Makefile。下面拆解每个环节的必做动作、典型报错、参数含义。3.1 AM层抽象机定义make前必须确认的三件事AMAbstract Machine是整个PA的基石它用C头文件定义了跨平台的硬件抽象接口如io_read/io_write。进入am/目录执行make ARCHx86-nemuARCHx86-nemu指定目标平台为x86架构NEMU模拟器。若漏写make会报错No rule to make target am-x86-nemu。必须检查am/build/下是否生成libam.a和include/am.h。这是后续所有模块的链接基础。常见翻车点am/src/x86-nemu/下的io.c依赖nemu/include/common.h但nemu目录此时可能还不存在。正确顺序是先解压zip再cd am make ARCHx86-nemu不要提前进nemu目录。3.2 NEMU层模拟器编译make时最易触发的GCC版本陷阱NEMU使用大量GNU C扩展如__attribute__((packed))对GCC版本敏感cd nemu make -j$(nproc)若报错error: unknown type name ‘uint64_t’说明GCC版本4.7缺少stdint.h完整支持。解决方案Ubuntu 16.04默认GCC 5.4但某些Docker镜像用GCC 4.4需sudo apt install gcc-5并export CCgcc-5。若报错undefined reference to ‘log2’NEMU的utils/log.c调用了math.h但链接时没加-lm。修复方法在nemu/Makefile的LDFLAGS末尾追加-lm。关键输出nemu/build/nemu可执行文件。运行./build/nemu --help应显示-b, --boot image等选项。3.3 nanos-lite层微内核构建“ref.img”生成背后的三步魔法nanos-lite的make过程最隐蔽它不直接生成.bin而是产出ref.imgcd nanos-lite make -j$(nproc)这条命令实际执行① 编译kernel/和drivers/得到kernel.o② 编译apps/目录含init.c得到init.bin③ 运行scripts/genimg.py将kernel.o、init.bin、navy-apps/build/hello.bin按固定偏移合并成build/ref.img。genimg.py的硬编码偏移0x100000放kernel0x80400000放app决定了你不能随意改navy-apps的链接脚本。若你修改了navy-apps/linker.ld里的SECTIONS必须同步更新genimg.py。3.4 Navy-Apps层应用编译make失败90%源于头文件路径错误Navy-Apps的Makefile依赖前序三层的输出cd navy-apps make -j$(nproc)报错fatal error: am.h: No such file or directory说明AM_HOME环境变量未导出或am/build/include/路径不对。血泪经验在init.sh里加一句echo AM include: $AM_HOME/build/include确认路径存在。报错undefined reference to ‘sys_write’nanos-lite没编译成功build/libnanos.a缺失。此时make会静默失败无错误提示但ls build/看不到.a文件。成功标志navy-apps/build/hello.bin约12KB和navy-apps/build/shell.bin约28KB生成。4. 启动即验证nemu -b ref.img后的黑屏、乱码与第一行日志当./nemu/build/nemu -b ./nanos-lite/build/ref.img执行后屏幕不是立刻出现菜单而是经历三个阶段黑屏→乱码→稳定日志。这恰恰是验证系统各层是否正常工作的黄金窗口。4.1 黑屏阶段0~3秒检验NEMU的CPU初始化与内存映射正常现象纯黑屏光标不闪烁CPU占用率飙升至100%。异常现象立即退出或报错Segmentation fault。排查重点nemu/src/cpu/exec/exec.c中的cpu_exec()是否被正确调用在nemu/src/cpu/exec/exec.c末尾加printf(CPU exec start\n);重新编译NEMU。若无输出说明nemu没加载到ref.img的入口点。ref.img的ELF头是否损坏用readelf -h ./nanos-lite/build/ref.img检查Entry point address是否为0x100000nanos-lite kernel入口。若为0x0说明genimg.py没写入kernel。4.2 乱码阶段3~8秒验证nanos-lite的串口驱动与console初始化正常现象屏幕闪现随机字符如UUU持续约2秒后消失。原因nanos-lite的drivers/serial.c正在初始化8250 UART此时波特率未稳定数据错乱。关键日志起点当看到[NANOS] booting...时说明kernel/init.c的kmain()已执行串口驱动就绪。4.3 稳定日志阶段8秒后确认应用加载与系统调用链路成功启动后你会看到[NANOS] booting... [NANOS] init: starting /init [INIT] hello world! [INIT] app loaded at 0x80400000 [INIT] entering app... Hello World from Navy-Apps!Hello World from Navy-Apps!是navy-apps/apps/hello/hello.c的main()输出证明nanos-lite的sys_write系统调用已连通ref.img中hello.bin被正确加载到0x80400000init进程成功execve跳转到应用入口。若卡在[INIT] app loaded at 0x80400000不动说明hello.bin的入口地址readelf -h navy-apps/build/hello.bin的Entry point address与genimg.py写入ref.img的地址不匹配。此时需检查navy-apps/linker.ld中ENTRY(_start)和SECTIONS的.text起始地址。5. 避坑指南PA实验中五个高频翻车现场与救命方案这些坑我带过17届学生95%的人都踩过至少3个。它们不写在README.md里但足以让你debug三天。5.1 现象make时nemu报错‘AM_HOME’ undefined但init.sh里明明export了原因make默认不继承父shell环境变量除非显式传递。nemu/Makefile里include $(AM_HOME)/Makefile会失败。解决在nemu/Makefile顶部加一行AM_HOME ? $(shell pwd)/../am或执行make AM_HOME../am。5.2 现象nemu -b ref.img后黑屏无任何输出ps aux | grep nemu显示进程存活原因ref.img的kernel入口点0x100000处代码未执行常见于nanos-lite/kernel/start.S的ljmp指令跳转失败。解决用GDB调试NEMU——gdb ./nemu/build/nemu然后(gdb) target remote :1234NEMU支持GDB stubb *0x100000下断点c运行。若断点不命中说明ref.img没正确写入kernel。5.3 现象navy-apps编译成功但ref.img里仍是旧的hello.bin修改hello.c后重启无变化原因genimg.py读取的是navy-apps/build/hello.bin但make时若navy-apps目录下有旧的.o文件make可能跳过重编译。解决每次改navy-apps代码后执行cd navy-apps make clean make确保build/hello.bin时间戳最新。5.4 现象shell应用启动后输入命令无响应键盘按键灯不亮原因nanos-lite/drivers/kbd.c的PS/2键盘控制器初始化失败通常因QEMU/NEMU的I/O端口模拟不完整。解决在nanos-lite/config-x86中启用CONFIG_KBD_PS2并在nanos-lite/kernel/init.c的kmain()里确保kbd_init()被调用。若仍无效临时改用hello应用验证内核基础功能。5.5 现象stb_vorbis.c编译报错implicit declaration of function ‘malloc’原因stb_vorbis.c依赖stdlib.h但nanos-lite的libc实现未导出malloc符号它用sbrk自己管理堆。解决在stb_vorbis.c顶部加#define STB_VORBIS_NO_STDIO并手动实现malloc/free——复制nanos-lite/libc/malloc.c的kmalloc/kfree函数改名为malloc/free放在stb_vorbis.c末尾。6. 进阶技巧用GDB实时调试nanos-lite内核把“黑匣子”变成透明流水线PA的价值不在跑通而在可调试。NEMU内置GDB stub让你能像调试普通Linux程序一样单步跟踪内核。这是我从南大助教那里偷来的技巧现在毫无保留给你。6.1 启动NEMU的GDB监听模式# 在nemu目录下执行不是nanos-lite ./build/nemu -b ../nanos-lite/build/ref.img -g 1234-g 1234开启GDB server监听本地1234端口。此时NEMU界面会显示GDB server started on port 1234但暂停在第一条指令等待GDB连接。6.2 用GDB连接并加载符号表# 新终端 gdb ./nanos-lite/build/kernel.elf # 注意不是ref.img是kernel.elf (gdb) target remote :1234 (gdb) set architecture i386:x86-64 (gdb) info registers # 查看当前寄存器状态 (gdb) x/10i $rip # 查看EIP处的10条汇编kernel.elf是nanos-lite编译时生成的带调试符号的内核镜像位于nanos-lite/build/kernel.elf比ref.img多出.debug_*节区。info registers能看到RIP0x100000证实CPU正停在kernel入口。6.3 设置内核级断点从kmain()到sys_write(gdb) b kmain # 在nanos-lite/kernel/init.c的kmain()设断点 (gdb) b sys_write # 在nanos-lite/kernel/syscall.c的sys_write设断点 (gdb) c # 继续运行NEMU界面会显示[NANOS] booting...当kmain()断点命中step进入console_init()再step到serial_init()你能亲眼看到UART寄存器0x3f8被写入值。当sys_write断点命中p $rdi可看到写入的字符串地址x/s $rsi可打印内容——这就是Hello World的源头。6.4 调试Navy-Apps应用让hello.c的printf变成可追踪的旅程# 在navy-apps目录下生成带符号的hello.elf cd navy-apps make clean make DEBUG1 # 然后在GDB中 (gdb) add-symbol-file build/hello.elf 0x80400000 (gdb) b main (gdb) cadd-symbol-file告诉GDBhello.elf的代码段加载在0x80400000这样b main才能命中。断点命中后step进入printf再step会跳到libc/printf.c最终step到sys_write系统调用——你亲眼见证了从C库到内核的完整调用链。从那以后我每次带学生做PA都强制他们用GDB走一遍kmain→console_init→sys_write→hello main。不是为了炫技而是因为只有看到寄存器值、内存地址、汇编指令一级级跳转那些课本上的“系统调用”“中断处理”才不再是黑匣子。这份资源真正的价值从来不是zip包里的代码而是它为你打开的那扇通往计算机底层的门。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

跳跃游戏高频题详解:贪心算法如何判断数组能否到达终点

跳跃游戏高频题详解:贪心算法如何判断数组能否到达终点

一直被“到达不了终点”折磨的人,看完这篇应该能少走很多弯路。力扣 Hot 100 的第 55 题“跳跃游戏”,是所有刷题人都绕不过去的一道经典题。它的题干很短:给你一个非负整数数组,初始位置在下标 0,每个元素代表你在该位…

2026/10/10 12:06:42 阅读更多 →
从x²=2到伽罗瓦群:域扩张、极小多项式与正规扩张完全梳理

从x²=2到伽罗瓦群:域扩张、极小多项式与正规扩张完全梳理

如果你正在学抽象代数,或者备战考研,一定绕不开一个问题:方程 x2 在有理数世界里无解。教材上会写“引入 Q(√2)”,但很少有人把这一步背后的逻辑讲透。有理数域上的扩域,就是把 Q 不包含的数,通过某种受控…

2026/10/10 12:06:42 阅读更多 →
readmap地图转换工具详解:千年服务端MAP文件解析与编译实战

readmap地图转换工具详解:千年服务端MAP文件解析与编译实战

简介:资源为千年游戏服务端地图转换工具readmap的完整工程包,面向游戏服务端开发、私服运维及经典游戏地图数据研究者。工具主要实现千年map文件的解析与格式转换,便于调整地形、怪物与NPC等地图要素;标题关联msp430f149微控制器&…

2026/10/10 12:06:42 阅读更多 →

最新新闻

普通人如何用ChatGPT网页端构建高可靠价值系统

普通人如何用ChatGPT网页端构建高可靠价值系统

1. 项目概述:一场围绕ChatGPT能力边界的实操型价值挖掘“ChatGPT 淘金潮(二)”这个标题,乍看像一篇泛泛而谈的行业观察,但作为连续三年深度参与AIGC工具链落地的从业者,我清楚它背后指向的绝不是概念炒作—…

2026/10/10 13:04:56 阅读更多 →
基于Python的肝脏CT分割与三维重建:从DICOM到3D打印模型全流程

基于Python的肝脏CT分割与三维重建:从DICOM到3D打印模型全流程

简介:本资源为基于Python的肝脏CT图像分割及三维重建完整项目包,面向计算机、人工智能、生物医学工程等专业的在校学生与从业人员,可用于毕业设计、课程设计、期末大作业及竞赛初期项目立项演示。项目围绕医学影像处理展开,涵盖CT…

2026/10/10 13:04:56 阅读更多 →
PIC32MX675F512L与PJ85718DM实现高精度温度监测方案

PIC32MX675F512L与PJ85718DM实现高精度温度监测方案

1. 从一个温度监测需求说起:为什么选这对组合嵌入式温度监测听起来是个老生常谈的话题,但真正落到工业级或HVAC(暖通空调)场景里,事情就没那么简单了。你不仅要测本地温度,还要测远程温度;不仅要…

2026/10/10 13:04:56 阅读更多 →
基于Neo4j的知识图谱电影问答系统:建模、实现与避坑指南

基于Neo4j的知识图谱电影问答系统:建模、实现与避坑指南

简介:一套面向计算机相关专业毕业设计的高分项目源码,基于Python与Neo4j构建知识图谱电影问答系统,涵盖后端服务、爬虫采集、图谱构建及小程序端交互展示。项目源出大四毕设,评审分99分,代码完整可直接运行&#xff0c…

2026/10/10 13:04:56 阅读更多 →
用 Opus 5.5 重写整个 Adobe 七件套?ArtCraft 暴露的 AI 编程新剧本

用 Opus 5.5 重写整个 Adobe 七件套?ArtCraft 暴露的 AI 编程新剧本

用 Opus 5.5 重写整个 Adobe 七件套?ArtCraft 暴露的 AI 编程新剧本 【免费下载链接】artcraft ArtCraft is an intentional crafting engine for artists, designers, and filmmakers 项目地址: https://gitcode.com/GitHub_Trending/ar/artcraft 2026 年 1…

2026/10/10 13:04:56 阅读更多 →
余行补位:不补短板,用隐藏能力解决职业瓶颈

余行补位:不补短板,用隐藏能力解决职业瓶颈

最近总有人问我同一个问题:为什么我那么努力补短板,人生反而越补越卡?我认真想了好一阵,发现大多数人卡住的不是能力,而是思路——他们把所有精力都花在让自己变成一个“没有短板的完人”,却忽略了自己手里…

2026/10/10 13:03:55 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/10 11:14:25 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/10 1:36:08 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/10 11:14: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/10 5:23:50 阅读更多 →
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/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练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/10 10:38:42 阅读更多 →