南京大学ICS课程PA实验:从源码到说明书,一套能跑通的计算机系统实践路径
简介这份资源是南京大学ICS课程PA实验部分的完整配套材料面向正在修读计算机系统基础课程或希望深入理解计算机底层原理的学生与自学者。内容围绕NEMU模拟器、抽象机、Makefile构建、nanos-lite轻量级内核及Navy-Apps应用等模块展开帮助读者在源码层面实践指令集、内存管理、中断处理与操作系统接口设计。压缩包共487个文件约741KB以C源码188个与头文件145个为主体辅以Makefile、汇编、C及Kconfig、链接脚本等构建配置另含README说明与初始化脚本结构完整便于按模块检索。目前已有560人学习下载。通过阅读源码与说明书读者可掌握从抽象机到微型操作系统的实现脉络理解编译、链接与系统启动流程并借助示例应用与脚本完成环境配置与调试是理论结合实践、提升系统编程能力的优质课程作业参考。1. 南京大学ICS课程PA实验从源码到说明书一套能跑通的计算机系统实践路径如果你正在搜“南京大学ICS课程PA实验部分-内含源码和说明书.zip”大概率你手里已经拿到了这个压缩包或者正在犹豫要不要花时间啃它。PAProgramming Assignment是南京大学《计算机系统基础》课程的核心实践环节目标是用C语言从零实现一个简化版NEMU模拟器再在其上跑通AM裸机程序和Nanos-lite操作系统。它不像普通课程作业那样填几个函数就完事而是要求你真正理解指令执行、内存管理、中断异常、系统调用这条完整链路。适合谁适合已经学过C语言和数字逻辑、想补上“程序怎么在硬件上跑起来”这一环的本科生或转行工程师。源码和说明书的价值在于你不需要从零猜框架但必须自己填核心逻辑否则调试时连日志都看不懂。2. 先搞清楚PA到底在造什么NEMU、AM与Nanos-lite三层结构2.1 三层各自负责什么别一上来就改错文件PA实验的代码框架通常分为三个目录层级NEMU模拟器、AM抽象机器、Nanos-lite操作系统。NEMU负责取指、译码、执行是硬件行为的软件替身AM提供裸机运行时环境包括TRM运行时环境、IOEIO扩展、CTE上下文扩展等模块Nanos-lite则实现系统调用、文件系统和进程调度。很多新手翻车是因为在NEMU里调系统调用或者在Nanos-lite里改指令译码——这两层之间隔着AM和系统调用接口改错位置会浪费大量时间。常见做法是先让NEMU跑通内置的测试指令再让AM的hello world输出字符最后才碰Nanos-lite。说明书里一般会给出每个阶段的验收命令比如make run后看到HIT GOOD TRAP才算通过。如果你拿到的源码里已经有部分实现先别急着覆盖用git diff或文件对比工具看清楚哪些是框架代码、哪些是待填的TODO。2.2 源码目录的典型布局与阅读顺序拿到压缩包后解压出来的目录结构通常类似这样ics-pa/ ├── nemu/ # 模拟器主体 │ ├── src/ │ │ ├── cpu/ # 指令译码与执行 │ │ ├── memory/# 物理内存与MMIO │ │ └── monitor/ # 调试器与命令解析 │ └── Makefile ├── abstract-machine/ # AM裸机环境 │ ├── am/ │ ├── klib/ # 内核基础库 │ └── scripts/ ├── nanos-lite/ # 操作系统 │ ├── src/ │ └── Makefile └── README.md # 说明书入口阅读顺序建议先看README.md里的实验阶段划分再打开nemu/src/cpu/exec下的指令实现文件对照RISC-V或x86手册看每条指令的语义。说明书通常会列出每个阶段要实现的函数名和预期行为比如exec_once()、isa_exec()、vaddr_read()等。不要跳过Makefile里面藏着编译选项和链接脚本改错一个-march参数就会导致模拟器行为异常。2.3 说明书怎么用才不白读说明书不是小说不要从头读到尾。正确用法是每开始一个阶段先读该阶段的“实验要求”和“验收标准”然后带着问题去翻“实现提示”。比如PA1要求实现指令执行你就重点看exec_once的调用链和decode_exec的译码逻辑。说明书里出现的代码片段通常是伪代码或关键片段不能直接复制需要结合框架里的宏定义和结构体补全。提示说明书里提到的“必做”和“选做”要分清。必做部分不做后续阶段跑不起来选做部分可以最后补不影响主线验收。3. 用源码跑通第一个阶段NEMU指令执行的最小闭环3.1 环境准备与编译命令PA实验对工具链有要求通常需要gcc、make、gdb、readline库。在Ubuntu 20.04或22.04上先装依赖sudo apt update sudo apt install build-essential gdb libreadline-dev libsdl2-dev然后进入nemu目录编译cd ics-pa/nemu make clean make如果编译报错先看是不是缺少libreadline-dev或libsdl2-dev。有些版本的框架会默认开启SDL显示如果不需要图形界面可以在Makefile里把CONFIG_SDL关掉减少依赖。编译成功后运行make run如果看到Welcome to NEMU!和调试器提示符(nemu)说明框架已经跑起来了。但此时执行指令可能会报“未实现”或直接HIT BAD TRAP因为核心译码逻辑还没填。3.2 指令译码与执行的关键代码位置以RISC-V为例nemu/src/isa/riscv32/instr/decode.c里通常有一个decode_exec()函数框架会给出操作码匹配的骨架你需要补全INSTPAT宏里的模式匹配。比如// 示例补全add指令的译码与执行 INSTPAT(0000000 ????? ????? 000 ????? 01100 11, add, R, { // s0 src1, s1 src2, d dest R(d) R(s0) R(s1); });这段代码的逻辑是根据指令的二进制模式提取源寄存器src1、src2和目的寄存器dest然后执行加法并写回。参数说明?????是通配符匹配任意5位寄存器编号0000000和01100是固定的funct7和opcode。如果你把funct3写错比如把000写成001就会导致add被译码成sub程序行为完全错乱。3.3 用内置测试验证指令实现NEMU通常自带一套指令测试集放在nemu/src/isa/riscv32/instr/或nemu/tests/下。运行方式make test或者手动加载镜像(nemu) c如果所有指令测试通过会输出类似All tests passed!的提示。如果某个测试失败调试器会停在出错指令处用info r查看寄存器值用x/10i $pc反汇编当前指令流对比预期结果。常见错误包括符号扩展没做、立即数拼接顺序反了、寄存器写回用了错误的索引。注意不要跳过测试直接跑AM或Nanos-lite。指令层有bug上层所有程序都会以奇怪的方式崩溃到时候排查成本翻倍。4. 从AM到Nanos-lite把裸机程序和操作系统跑起来4.1 AM的TRM与IOE让hello world输出字符AM层的目标是让一个裸机程序能在NEMU上运行。以abstract-machine/am/src/riscv/nemu/为例你需要实现putch()和halt()。putch()通常通过写MMIO地址实现// 示例NEMU的串口MMIO地址 #define SERIAL_PORT 0xa00003f8 void putch(char ch) { outb(SERIAL_PORT, ch); }outb是AM提供的IO端口写函数最终会调用NEMU里实现的mmio_write。参数说明SERIAL_PORT是NEMU约定的串口地址写进去的字节会被NEMU捕获并输出到终端。如果你把地址写错字符不会显示但程序也不会报错——这种“静默失败”是PA里最折磨人的坑之一。验证方式cd abstract-machine/am-kernels/hello make ARCHriscv32-nemu run看到Hello, World!输出即通过。4.2 Nanos-lite的系统调用与文件系统Nanos-lite阶段要求实现syscall分发、fs文件系统和proc进程管理。以sys_write为例// 示例Nanos-lite的sys_write实现 int sys_write(int fd, void *buf, size_t count) { if (fd 1 || fd 2) { for (size_t i 0; i count; i) { putch(((char *)buf)[i]); } return count; } return -1; }逻辑说明标准输出和标准错误直接走putch其他文件描述符需要查文件表。参数fd是文件描述符buf是用户态缓冲区指针count是字节数。注意用户态指针不能直接解引用需要通过copy_from_user或类似机制转换否则在启用分页后会触发页错误。4.3 跑通第一个用户程序从加载到退出Nanos-lite通常内置一个简单的用户程序比如/bin/hello。运行流程cd nanos-lite make ISAriscv32 make run如果看到用户程序输出并正常退出说明系统调用、文件加载、进程切换这条链路基本通了。如果卡住不动先用NEMU的调试器(nemu)按c继续然后CtrlC中断看$pc停在哪里。常见问题加载地址算错、栈指针没设置、sys_exit没实现导致进程无法终止。提示Nanos-lite的调试信息通常通过Log()宏输出可以在Makefile里调整LOG_LEVEL但不要开太多否则串口输出会淹没真正的错误。5. 避坑与排查PA实验里最容易翻车的5个地方5.1 现象NEMU启动后直接HIT BAD TRAP没有任何输出原因通常是复位向量或第一条指令的地址设错或者init_monitor()里没有正确加载镜像。解决检查CONFIG_MBASE和CONFIG_PC_RESET_OFFSET是否与链接脚本一致用x/10i $pc看第一条指令是不是预期的启动代码。5.2 现象指令测试通过但AM的hello world输出乱码原因putch的MMIO地址写错或者NEMU的串口设备没有正确注册。解决确认SERIAL_PORT与NEMU里serial_io_handler的映射地址一致检查outb的端序处理是否正确。5.3 现象Nanos-lite加载用户程序后卡死无任何输出原因用户程序的入口地址或栈指针设置错误或者syscall分发时参数传递错位。解决在do_syscall里打印系统调用号确认a7寄存器的值是否符合预期检查trap上下文保存与恢复是否完整。5.4 现象启用分页后用户程序访问合法地址却触发页错误原因页表项权限位设置错误或者map()时虚拟地址与物理地址的偏移算错。解决用vaddr_read和paddr_read分别读同一地址对比值是否一致检查页表项的V、R、W、X位。5.5 现象编译通过但链接报错“undefined reference to ...”原因框架里某些函数声明了但没实现或者Makefile里的源文件列表没包含你新增的.c文件。解决用grep -r 函数名找到声明位置确认实现文件是否在编译目标里检查SRCS变量是否用了通配符。6. 进阶技巧用差分测试和日志分级把调试效率提上来PA实验做到后期最耗时的不是写代码而是定位“为什么这条指令行为不对”。我自己的习惯是在NEMU里加一个差分测试模式用同一段指令序列分别跑你的实现和参考实现比如QEMU或 Spike逐条对比寄存器状态。具体做法是在exec_once后加一个钩子把pc、gpr[]、csr[]写进环形缓冲区出错时dump最后N条。这个技巧在PA2和PA3阶段能省下大量单步调试的时间。另一个实用习惯是日志分级。NEMU的Log()宏支持DEBUG、INFO、WARN、ERROR等级别我一般把指令译码的详细日志设为DEBUG只在需要时用logctl打开系统调用和异常入口设为INFO默认输出。这样正常运行时不会刷屏出问题时又能快速定位。说明书里通常不会写这些但源码里的utils/log.h已经提供了机制花十分钟改一下Makefile里的CFLAGS就能生效。最后说一个验证方法每通过一个阶段用git tag打一个快照。PA的框架代码和你的实现混在一起一旦改崩了没有版本控制就只能重新解压压缩包。我见过太多人因为没打tag在PA3阶段想回退到PA2的可用状态却回不去最后从头重做。源码和说明书是死的怎么用活取决于你愿不愿意在工程习惯上多花一点心思。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

中文酒店评论情感分类实战:Python与SVM从文本清洗到模型部署

中文酒店评论情感分类实战:Python与SVM从文本清洗到模型部署

简介:面向计算机相关专业毕业设计场景的Python实现酒店中文评论情感分析项目资源,采用基于机器学习的情感极性分类路线,通过训练标注语料构建分类模型,对酒店评论文本进行正向/负向情感判别,适合需要完成情感分析类课题…

2026/10/12 16:52:57 阅读更多 →
基于PyQt5与OpenCV的水果识别系统:从HSV阈值到界面实现

基于PyQt5与OpenCV的水果识别系统:从HSV阈值到界面实现

简介:这是一套基于PyQt5、OpenCV与Python实现的水果识别系统源码,带完整GUI界面和详细注释。项目主要面向计算机科学与技术、人工智能、数据科学与大数据等专业的在校学生、教师或企业开发者,适合用于毕业设计、课程设计、大作业以及项目初期…

2026/10/12 16:52:57 阅读更多 →
基于Python的交通流量预测:随机森林模型与数据预处理实战

基于Python的交通流量预测:随机森林模型与数据预处理实战

简介:针对城市交通拥堵预测的Python实践项目包,面向计算机相关专业学生、毕业设计开发者及机器学习初学者,用于解决道路时间段内车辆流量与拥堵状态预测问题。项目基于GCM走廊真实主干道传感器数据,每5分钟记录一次交通流特征&…

2026/10/12 16:52:57 阅读更多 →

最新新闻

选择性搜索算法详解:目标检测候选区域生成的原理与实战

选择性搜索算法详解:目标检测候选区域生成的原理与实战

简介:面向Python与计算机视觉初学者,这份代码包以简洁示例演示选择性搜索算法的核心流程,完整覆盖图像预处理、SLIC超像素分割、相邻区域相似度比较与合并、候选框输出等环节。选择性搜索是目标检测中候选区域生成的重要技术,与传…

2026/10/12 17:47:16 阅读更多 →
综合能源优化调度中MPC与需求响应的工程实践:从预测模型到滚动优化

综合能源优化调度中MPC与需求响应的工程实践:从预测模型到滚动优化

简介:这份资源面向综合能源优化调度与需求响应方向的研究生、科研人员及工程技术人员,聚焦建筑蓄热系统的模型预测控制(MPC)实现。背景设定为纽约市一栋配备被动与主动蓄热的办公楼,费率计划包含三级需求费及系统运营商…

2026/10/12 17:47:16 阅读更多 →
商品评论情感分析实战:中文文本分类与机器学习全流程指南

商品评论情感分析实战:中文文本分类与机器学习全流程指南

简介:面向计算机相关专业毕业设计场景的完整项目包,聚焦商品评论情感分析,覆盖爬虫采集、文本预处理、特征表示、SVM与LSTM建模、结果可视化和简易GUI等环节,适合人工智能、电子信息、物联网等专业学生用于毕设、课设或机器学习入…

2026/10/12 17:47:16 阅读更多 →
收藏这份2025年大模型实践指南:从推理优化到部署落地的全栈经验(TaoToken 统一 Key 篇)

收藏这份2025年大模型实践指南:从推理优化到部署落地的全栈经验(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/12 17:47:16 阅读更多 →
NAS养虾(OpenClaw)对接本地大模型?极空间 Docker 跑通 Ollama 的 TaoToken 配置记录

NAS养虾(OpenClaw)对接本地大模型?极空间 Docker 跑通 Ollama 的 TaoToken 配置记录

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

2026/10/12 17:47:16 阅读更多 →
SD NAND为何用NAND而非NOR?从协议到成本深度解析

SD NAND为何用NAND而非NOR?从协议到成本深度解析

有天午休,同事捏着一颗黑色LGA-8封装的小芯片凑过来问:“BOM表里写着SD NAND,里面装的既然是Flash,为什么偏偏是NAND,不是NOR?我以前学的都是NOR随机读快、字节寻址简单,NAND又要管坏块、又要做…

2026/10/12 17:46:15 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 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/11 10:45:37 阅读更多 →
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/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练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/11 14:36:54 阅读更多 →