MIT 6.S081 xv6 lazy page allocation 实验篇(lab5):Lazy allocation (moderate)
Lazy allocation (moderate)实验目标这是 Lab5Lazy page allocation的第二步也是真正让惰性分配落地的核心关。上一步Eliminate allocation from sbrk我们删掉了sbrk里的实际分配只记账、不建映射结果访问新地址就panic。本步的目标在缺页发生时由内核当场补上这块内存。练习目标在usertrap()里识别用户态缺页异常scause 13或15为其现场分配一页物理内存并建好映射让进程从缺页指令处无缝继续。修改uvmunmap()让它在解除映射时遇到未映射的页不再 panic而是直接跳过否则上一步埋下的账记了、页没给在进程退出时仍会炸。最终让echo hi这类简单命令跑通理解 lazy allocation 的完整闭环申请时只记账 → 访问时缺页 → 内核补分配 → 继续运行。官方 lab 原文把这一步描述为Modify the code intrap.cto respond to a page fault from user space by mapping a newly-allocated page of physical memory at the faulting address, and then returning back to user space to let the process continue executing. You should add your code just before theprintfcall that produced the “usertrap(): …” message.前置知识1. 缺页异常落在usertrap承接上一步进程访问sbrk新记大的、却没映射的地址 → MMU 发现 PTE 无效 → CPU 触发页错误异常经uservec陷入内核、进入usertrap()。所以在usertrap里插桩正是处理它的正确位置。scause编码xv6kernel/riscv.hscause含义8(0x8)系统调用ecall13(0xd)读访问缺页load page fault15(0xf)写访问缺页store/AMO page faultr_stval()返回触发缺页的虚拟地址r_sepc()返回缺页指令地址处理完从这里重执行。2. lazy handler 的三板斧为缺页地址补一页本质是照抄uvmalloc()的核心逻辑官方 hint 就是Steal code from uvmalloc()kalloc()从空闲链表抠出一页物理内存。memset(pa, 0, PGSIZE)必须清零。xv6 的物理页可能此前装过内核/其他进程数据不清零会把残留内容甚至内核机密暴露给用户进程——这是安全与正确性的硬要求。mappages()在页表里把缺页虚拟地址页对齐↔ 这块物理页建好映射并赋予正确权限。3. PTE 权限位kernel/riscv.h里定义的页表项标志位位含义PTE_VValid映射有效PTE_R可读PTE_W可写PTE_X可执行PTE_U用户态可访问U-mode 能访问用户进程的堆页必须带PTE_U才能被用户态访问R|W是读写所需。4. 为什么必须改uvmunmap上一步我们讲透过panic发生在进程退出、内核uvmunmap(pagetable, 0, sz, 1)解映射时——它走到sbrk记大却从未建映射的那段发现 PTE 无效就panic(uvmunmap: not mapped)。现在惰性分配下[0, sz)里有空洞未分配页是常态而非错误。所以要让uvmunmap遇到无效 PTE 时跳过而非 panic——这是本步必须的配套改动。5. 本步改动文件文件改动kernel/trap.cusertrap()新增缺页分支lazy handlerkernel/vm.cuvmunmap()遇无效 PTE 改continue跳过实现思路整体闭环进程访问未映射地址 ──(MMU 缺页)── usertrap(scause13/15) │ ├─ 取 fault_va r_stval() ├─ 校验合法性fault_va 在栈顶之上、sz 之下属于合法堆区 ├─ kalloc() 拿一页物理内存 ├─ memset(pa, 0, PGSIZE) 清零 ├─ mappages() 建映射R|W|X|U └─ usertrapret() 返回用户态从缺页指令处重新执行 ── 这次访问成功关键设计点插入位置在usertrap原有if(scause8)系统调用、else if(devintr)设备中断之后原elseunexpected之前新增else if(r_scause()13 || r_scause()15)分支。这样缺页会被优先识别、不再落进unexpected兜底。合法性判断PGROUNDUP(p-trapframe-sp) - 1 fault_va fault_va p-sz。含义缺页地址必须高于用户栈顶sp之上才是堆区、且低于进程大小sz在sbrk记账的范围内。这一步把合法惰性分配请求和真正非法的访问区分开。分配 清零 映射三板斧一气呵成mappages失败极少见如页表满则释放刚拿到的物理页并标记进程killed。uvmunmap配套两处panic改为continue让解映射对空洞鲁棒。注这一步是官方定义的moderate阶段目标是让echo hi工作。判断条件用的是栈顶之上、sz 之下的简化版更严格的边界越界kill、栈下方 Guard 页、fork 复制、系统调用传参、OOM在后续lazytests阶段补齐见复盘·前瞻。代码实现kernel/trap.c——usertrap新增缺页分支/* * kernel/trap.c */voidusertrap(void){intwhich_dev0;if((r_sstatus()SSTATUS_SPP)!0)panic(usertrap: not from user mode);// send interrupts and exceptions to kerneltrap(),// since were now in the kernel.w_stvec((uint64)kernelvec);structproc*pmyproc();// save user program counter.p-trapframe-epcr_sepc();if(r_scause()8){// system callif(p-killed)exit(-1);// sepc points to the ecall instruction,// but we want to return to the next instruction.p-trapframe-epc4;// an interrupt will change sstatus c registers,// so dont enable until done with those registers.intr_on();syscall();}elseif((which_devdevintr())!0){// ok}elseif((r_scause()13||r_scause()15)){// 惰性分配导致的缺页异常uint64 fault_var_stval();// 获取引发缺页异常的虚拟地址char*pa0;// 虚拟地址对应的物理地址(待映射)// 判断虚拟地址 fault_va 是否在进程栈空间之中if(PGROUNDUP(p-trapframe-sp)-1fault_vafault_vap-sz){// 分配一页物理内存if((pakalloc())0)panic(usertrap: kalloc\n);memset(pa,0,PGSIZE);// 将 fault_va 映射到 paif(mappages(p-pagetable,PGROUNDDOWN(fault_va),PGSIZE,(uint64)pa,PTE_R|PTE_W|PTE_X|PTE_U)!0){printf(lazy alloc: failed to map page\n);kfree(pa);p-killed1;}}}else{printf(usertrap(): unexpected scause %p pid%d\n,r_scause(),p-pid);printf( sepc%p stval%p\n,r_sepc(),r_stval());p-killed1;}if(p-killed)exit(-1);// give up the CPU if this is a timer interrupt.if(which_dev2)yield();usertrapret();}逐行理解else if ((r_scause() 13 || r_scause() 15))识别读/写缺页lazy 触发的页面错误。fault_va r_stval();拿到触发缺页的虚拟地址。PGROUNDUP(p-trapframe-sp) - 1 fault_va fault_va p-sz合法性闸门——只在栈顶之上、进程大小sz之下的堆区才补分配。kalloc()拿物理页memset(pa, 0, PGSIZE)清零安全必需mappages(..., PTE_R|PTE_W|PTE_X|PTE_U)建映射R/W/X/U 全给教学代码图省事。mappages失败则kfree(pa)回收物理页并p-killed 1。注意成功时什么也没改、也没 return——usertrap会自然走到末尾的usertrapret()带着新映射返回用户态CPU 重新执行那条缺页指令这次地址已映射访问成功。kernel/vm.c——uvmunmap不再为缺页 panic/* * kernel/vm.c */voiduvmunmap(pagetable_tpagetable,uint64 va,uint64 npages,intdo_free){uint64 a;pte_t*pte;if((va%PGSIZE)!0)panic(uvmunmap: not aligned);for(ava;avanpages*PGSIZE;aPGSIZE){if((ptewalk(pagetable,a,0))0)// panic(uvmunmap: walk);continue;// 惰性分配遇到不存在的 pte 就跳过if((*ptePTE_V)0)// panic(uvmunmap: not mapped);continue;// 同上if(PTE_FLAGS(*pte)PTE_V)panic(uvmunmap: not a leaf);if(do_free){uint64 paPTE2PA(*pte);kfree((void*)pa);}*pte0;}}改动极小但关键walk()返回 0页表中间层都还没建或PTE_V 0叶子 PTE 无效→ 原代码panic现改为continue跳过。这样惰性分配留下的空洞在进程退出/exec 解映射时安静跳过上一步的panic: uvmunmap: not mapped彻底消失。其余逻辑释放物理页、*pte 0不变——确实映射过的页照常回收。验证按官方步骤启动 xv6执行最简单命令$makeqemu$echohi hi应正常打印hi而不再 panic。这说明shell 经sbrk申请的堆只记账在被访问时由usertrap的 lazy handler 当场补了一页物理内存并映射进程得以继续。为确认确实发生了惰性分配可借助 Lab3pgtbl的vmprint若已在该分支或临时printf缺页分支观察echo hi期间至少触发了一次甚至两次缺页——这正是 lazy 的实证。提示本步只要求echo hi工作。更严苛的lazytests/usertests还会测越界、fork、系统调用传参等边界当前实现在这些场景可能仍不过——它们是下一个阶段要补的见复盘·前瞻。复盘本实验解决了什么lazy allocation 真正闭环了sbrk记账第一步→ 访问缺页CPU→usertrap补分配本步→ 重执行成功。三步走完内存从申请即分配变成了用到才给。亲手实现了一次缺页处理把 Lab4 学的异常 →usertrap框架第一次用于真正修复一个问题而非打印/报警。scause/stval/sepc三个寄存器从概念变成了手里的工具。uvmunmap的鲁棒化理解了解映射遇到空洞是惰性分配的固有常态配套改成跳过——这一步让整个机制自洽。与真实操作系统Linux的对比demand paging 是现代 OS 的标配本步就是它的极简版Linux 的堆brk/mmap、文件映射、共享库默认都是访问时才分配物理页minor fault若还需从磁盘读则是 major fault。Linux 的缺页处理在do_page_fault()里同样要区分合法匿名页/文件页/非法访问非法访问会发SIGSEGV杀进程——对应我们下一步要加的越界kill。xv6 这里kalloc失败直接panic而 Linux 会走 OOM killer 选进程牺牲——复杂度差异巨大但骨架一致。收获demand paging / lazy allocation能讲清为什么不在申请时分配快、省、支持稀疏/超额是 OS 内存管理章节高频题。page fault 全流程scause13/15 区分读写缺页、stval给地址、sepc用于重执行缺页不是错误而是正常的中断信号handler 补完映射后从原指令重试。kalloc后必须memset 0信息安全视角的硬要求不清零会泄露内核/其他进程数据也是面试加分点。uvmunmap的空洞容忍理解映射空间与实际分配解耦后所有解映射/回收路径都必须对空洞鲁棒。前瞻lazytests 阶段还要补的边界当前实现能跑echo hi但官方lazytests/usertests会测更多场景需要继续加固越界要kill若fault_va p-sz超过sbrk分配的上界应p-killed 1而非默默分配——否则会无限缺页死循环注意当前else if已匹配scause13/15越界地址不会落进原else会静默无操作 → 回用户态又缺页 → busy loop。栈下方 Guard 页fault_va落在栈正下方那页非法也要kill。fork 复制uvmcopy要能处理父进程有惰性空洞的情况空洞子进程也记为空洞不能试图复制不存在的页。系统调用传参read/write等传入sbrk地址但内存未分配时内核copyin/copyout也要能触发分配。OOMkalloc()失败时不应panic整个内核而应kill当前进程用p-killed 1。建议把前置知识里的 PTE 权限表和实现思路里的 lazy 闭环图存下——Lab6 的 Copy-on-Write fork 会复用同一套缺页处理框架只不过 handler 从分配新页变成复制父页思维模型一脉相承。

相关新闻

四层防御解决LLM输出JSON解析难题:从提示词到后处理的工程实践

四层防御解决LLM输出JSON解析难题:从提示词到后处理的工程实践

在调用大语言模型(LLM)生成结构化数据时,你是否也遇到过这样的场景:你明确要求模型输出一个干净的 JSON 对象,但得到的回复却总是夹杂着“好的,这是您要的 JSON:”这样的前言,或者“…

2026/8/14 4:19:42 阅读更多 →
XHTTP 和 HTTP 到底有什么区别?从协议原理到 VLESS + XHTTP + REALITY 一次讲透

XHTTP 和 HTTP 到底有什么区别?从协议原理到 VLESS + XHTTP + REALITY 一次讲透

一、先给结论:HTTP 和 XHTTP 不是一个层级把整个链路拆开,会清楚很多。 普通 Web 访问通常可以抽象为: Browser / App↓ HTTP/1.1 / HTTP/2 / HTTP/3↓ TLS↓ TCP / QUIC↓ IP而 Xray 中常见的: VLESS XHTTP REALITY更准确的分层…

2026/8/12 16:44:10 阅读更多 →
企业媒体发稿怎么做好AI收录沉淀?传播易智能投放解决方案

企业媒体发稿怎么做好AI收录沉淀?传播易智能投放解决方案

进入2026年,企业新闻发稿的行业核心痛点已经完成迭代。当下品牌传播的核心难题,早已不是找不到发稿渠道、无法完成稿件发布,而是普遍面临稿件投放去向不明、受众触达模糊、搜索收录留存不稳定、传播效果无法核验溯源等一系列行业顽疾。传统中…

2026/8/12 16:42:43 阅读更多 →

最新新闻

拒绝模板化套路!深度解析龙潭古镇网站建设如何讲好千年故事并实现本地流量变现

拒绝模板化套路!深度解析龙潭古镇网站建设如何讲好千年故事并实现本地流量变现

做网站这行干了十几年,我见过太多让人叹气的项目。尤其是当我们聊到像龙潭古镇这样的文化IP时,很多甲方或者项目负责人脑子里蹦出来的第一个念头往往是:“赶紧弄个好看的页面,把照片放上去,能搜到就行。”这种想法太危险了,也太廉价了。龙潭古镇,这座有着深厚历史底蕴的…

2026/8/14 4:19:04 阅读更多 →
LeetCode刷题 day38

LeetCode刷题 day38

目录1.打家劫舍 III2.扁平化嵌套列表迭代器3.整数拆分1.打家劫舍 III 小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为root。 除了root之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这…

2026/8/14 4:19:04 阅读更多 →
唐朔飞计算机组成原理核心难点解析:Cache、CPU与总线系统

唐朔飞计算机组成原理核心难点解析:Cache、CPU与总线系统

1. 项目概述:为什么我们需要一份“唐版”计组总结?如果你正在学习计算机组成原理,尤其是手头捧着唐朔飞老师那本经典的《计算机组成原理(第3版)》,那你大概率正经历着和我当年一样的“甜蜜烦恼”。这本书内…

2026/8/14 4:19:04 阅读更多 →
GetQzonehistory:QQ空间历史说说备份工具完整指南,把青春记忆轻松搬进本地

GetQzonehistory:QQ空间历史说说备份工具完整指南,把青春记忆轻松搬进本地

GetQzonehistory:QQ空间历史说说备份工具完整指南,把青春记忆轻松搬进本地 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 想把QQ空间的历史说说完整备份到本地&…

2026/8/14 4:19:04 阅读更多 →
探索银川市建设局网站如何助力城市腾飞与民生改善

探索银川市建设局网站如何助力城市腾飞与民生改善

在这座被黄沙与黄河共同雕琢的塞上明珠里,日子总是过得慢条斯理却又充满生机。作为一名在这个城市扎根多年的老银川人,我时常喜欢骑着那辆斑驳的自行车,沿着南熏大道缓缓骑行。清晨的空气中弥漫着羊杂碎汤的香气,傍晚的贺兰山轮廓在夕阳下显得格外温柔。这里的一切变化,都…

2026/8/14 4:19:04 阅读更多 →
德阳中恒网站建设怎么做才能既省钱又专业?揭秘企业官网升级的五大关键步骤

德阳中恒网站建设怎么做才能既省钱又专业?揭秘企业官网升级的五大关键步骤

在这个数字化浪潮席卷全球的今天,如果你还觉得企业官网只是一个放几张图片、挂几个联系方式的“电子名片”,那恐怕真的要落后时代了。对于德阳地区的中小企业主来说,尤其是那些正在考虑或已经开始着手德阳中恒网站建设的老板们,大家心中最纠结的问题往往不是“要不要做”,…

2026/8/14 4:18:03 阅读更多 →

日新闻

临沂网站建设铭镇:深耕本土数字生态,以匠心铸就企业品牌核心竞争力

临沂网站建设铭镇:深耕本土数字生态,以匠心铸就企业品牌核心竞争力

在这个流量为王、视觉至上的互联网时代,对于临沂乃至整个山东乃至全国的传统中小企业来说,拥有一张精美的“数字名片”早已不再是可选项,而是生存的必答题。每当夜幕降临,沂河两岸灯火辉煌,物流之都的喧嚣逐渐沉淀为对未来的思考。我们常常听到老板们在茶余饭后探讨:为什…

2026/8/14 0:00:26 阅读更多 →
Flutter与OpenHarmony实现剧本杀组队表单开发实战

Flutter与OpenHarmony实现剧本杀组队表单开发实战

1. 项目概述在移动应用开发领域,跨平台框架Flutter因其高效的开发体验和出色的性能表现,已经成为众多开发者的首选。而OpenHarmony作为新兴的操作系统平台,其开放性和灵活性为开发者提供了全新的可能性。本文将聚焦于一个实际应用场景——剧本…

2026/8/14 0:00:26 阅读更多 →
大连网站建设找简维科技:为您打造懂业务更懂用户的数字化转型引擎

大连网站建设找简维科技:为您打造懂业务更懂用户的数字化转型引擎

在这个数字化浪潮席卷全球的今天,企业想要在激烈的市场竞争中站稳脚跟,拥有一张好看的“数字名片”已经远远不够了。很多老板在刚开始接触互联网业务时,都有一个共同的困惑:为什么我花了钱建的网站,就像是在真空中自嗨?访客进来转了两圈就跑了,线索石沉大海,甚至连客服…

2026/8/14 0:01:27 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/13 2:38:34 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/13 10:41:52 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/13 10:41:51 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/13 10:41:50 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/13 10:41:49 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/13 10:41:49 阅读更多 →