{"id":64,"date":"2024-03-09T15:12:02","date_gmt":"2024-03-09T07:12:02","guid":{"rendered":"http:\/\/104.46.213.183\/?p=64"},"modified":"2024-03-09T15:12:02","modified_gmt":"2024-03-09T07:12:02","slug":"lab-mmap","status":"publish","type":"post","link":"https:\/\/www.yewpo.top\/index.php\/64\/","title":{"rendered":"Lab mmap"},"content":{"rendered":"<h1>Lab mmap<\/h1>\n<blockquote>\n<p>\u96be\u5ea6\uff1a<strong>hard<\/strong><\/p>\n<p>\u7531\u4e8e\u672c\u5b9e\u9a8c\u9700\u8981\u5728\u5176\u4ed6\u7a0b\u5e8f\u4ee3\u7801\u4e2d\u4f7f\u7528\u4f8b\u5982\uff1a<code>struct file, MAP_SHARE<\/code>\u7b49\u5b8f\u6216\u8005\u662f\u7ed3\u6784\u4f53\uff0c<strong>\u5f53\u51fa\u73b0\u76f8\u5173\u62a5\u9519\u65f6<\/strong>\uff0c<em>\u8bf7\u4e25\u683c\u4ee5\u4ee5\u4e0b\u987a\u5e8f\u6dfb\u52a0\u5934\u6587\u4ef6\u81f3\u76f8\u5173\u4ee3\u7801\u4e2d<\/em>\uff0c<strong>\u4e00\u5b9a\u8981\u6309\u987a\u5e8f<\/strong>\uff0c\u539f\u56e0\u8bf7\u4e86\u89e3<em>\u94fe\u63a5<\/em>\u3002<\/p>\n<pre><code class=\"language-c\">#include \"fs.h\"\n#include \"sleeplock.h\"\n#include \"fcntl.h\"\n#include \"file.h\"<\/code><\/pre>\n<p><strong>\u6574\u4e2a\u5b9e\u9a8c\u91c7\u7528\u7684\u865a\u62df\u5185\u5b58\u5206\u914d\u673a\u5236\u662f\uff1a\u61d2\u5206\u914d<\/strong>\uff0c\u91c7\u7528\u8fd9\u79cd\u65b9\u5f0f\u53ef\u4ee5\u63d0\u9ad8\u5206\u914d\u6548\u7387\uff0c\u5e76\u4e14\u53ef\u4ee5\u6620\u5c04\u4e00\u4e2a\u5b9e\u9645\u5927\u5c0f\u5927\u4e8e\u7269\u7406\u7a7a\u95f4\u7684\u6587\u4ef6\u3002<\/p>\n<\/blockquote>\n<h2>1 mmap &amp; munmap<\/h2>\n<p>\u5728<code>C programmmer&#039;s manual<\/code>\u4e2d\u5bf9<code>mmap &amp; munmap<\/code>\u7684\u63cf\u8ff0\u5982\u4e0b\uff1a<\/p>\n<pre><code>mmap() creates a new mapping in the virtual address space of the calling process.  The starting address for the new mapping is specified in addr.  The length argument specifies\n       the length of the mapping (which must be greater than 0).\n\n       If addr is NULL, then the kernel chooses the (page-aligned) address at which to create the mapping; this is the most portable method of creating a new mapping.  If addr is  not\n       NULL,  then the kernel takes it as a hint about where to place the mapping; on Linux, the kernel will pick a nearby page boundary (but always above or equal to the value speci\u2010\n       fied by \/proc\/sys\/vm\/mmap_min_addr) and attempt to create the mapping there.  If another mapping already exists there, the kernel picks a new address that may or may not depend\n       on the hint.  The address of the new mapping is returned as the result of the call.\n\n       The contents of a file mapping (as opposed to an anonymous mapping; see MAP_ANONYMOUS below), are initialized using length bytes starting at offset offset in the file (or other\n       object) referred to by the file descriptor fd.  offset must be a multiple of the page size as returned by sysconf(_SC_PAGE_SIZE).\n\n       After the mmap() call has returned, the file descriptor, fd, can be closed immediately without invalidating the mapping.\n\n       The prot argument describes the desired memory protection of the mapping (and must not conflict with the open mode of the file).  It is either PROT_NONE or the  bitwise  OR  of\n       one or more of the following flags:\n\n       PROT_EXEC  Pages may be executed.\n\n       PROT_READ  Pages may be read.\n\n       PROT_WRITE Pages may be written.\n\n       PROT_NONE  Pages may not be accessed.\n\n       The  flags  argument determines whether updates to the mapping are visible to other processes mapping the same region, and whether updates are carried through to the underlying\n       file.  This behavior is determined by including exactly one of the following values in flags:\n\n       MAP_SHARED\n      Share this mapping.  Updates to the mapping are visible to other processes mapping the same region, and (in the case of file-backed mappings) are carried through to  the\n              underlying file.  (To precisely control when updates are carried through to the underlying file requires the use of msync(2).)\n\n       MAP_SHARED_VALIDATE (since Linux 4.15)\n       This  flag  provides  the  same  behavior  as  MAP_SHARED  except  that  MAP_SHARED  mappings  ignore unknown flags in flags.  By contrast, when creating a mapping using\n       MAP_SHARED_VALIDATE, the kernel verifies all passed flags are known and fails the mapping with the error EOPNOTSUPP for unknown flags.  This mapping  type  is  also  required to be able to use some mapping flags (e.g., MAP_SYNC).\n       MAP_PRIVATE\n       Create  a  private copy-on-write mapping.  Updates to the mapping are not visible to other processes mapping the same file, and are not carried through to the underlying file.  It is unspecified whether changes made to the file after the mmap() call are visible in the mapped region.\n\n   Both MAP_SHARED and MAP_PRIVATE are described in POSIX.1-2001 and POSIX.1-2008.  MAP_SHARED_VALIDATE is a Linux extension.\n\n   Memory mapped by mmap() is preserved across fork(2), with the same attributes.\n\n       A file is mapped in multiples of the page size.  For a file that is not a multiple of the page size, the remaining memory is zeroed when mapped, and writes to that  region  are\n       not  written  out  to the file.  The effect of changing the size of the underlying file of a mapping on the pages that correspond to added or removed regions of the file is un\u2010\n       specified.\n\n   munmap()\n       The munmap() system call deletes the mappings for the specified address range, and causes further references to addresses within the range to  generate  invalid  memory  refer\u2010\n       ences.  The region is also automatically unmapped when the process is terminated.  On the other hand, closing the file descriptor does not unmap the region.\n\n       The  address  addr  must be a multiple of the page size (but length need not be).  All pages containing a part of the indicated range are unmapped, and subsequent references to\n       these pages will generate SIGSEGV.  It is not an error if the indicated range does not contain any mapped pages.<\/code><\/pre>\n<p>\u6839\u636e\u624b\u518c\u63cf\u8ff0\uff0c<code>mmap<\/code>\u67096\u4e2a\u53c2\u6570\u3002\u7b2c\u4e00\u4e2a\u53c2\u6570<code>addr<\/code>\uff0c\u8868\u793a\u5e0c\u671b\u6620\u5c04\u7684\u865a\u62df\u5730\u5740\u7684\u8d77\u70b9\uff0c\u5982\u679c\u4e3a0\uff0c\u8868\u793a\u5e0c\u671b\u7cfb\u7edf\u8c03\u7528\u5206\u914d\u4e00\u4e2a\u53ef\u7528\u7a7a\u95f4\uff1b\u7b2c2\u4e2a\u53c2\u6570<code>length<\/code>\uff0c\u8868\u793a\u5e0c\u671b\u5206\u914d\u7684\u865a\u62df\u7a7a\u95f4\u7684\u5b57\u8282\u5927\u5c0f\uff1b\u7b2c\u4e09\u4e2a\u53c2\u6570<code>prot<\/code>\uff0c\u8868\u793a\u8be5\u865a\u62df\u7a7a\u95f4\u5e0c\u671b\u62e5\u6709\u7684\u64cd\u4f5c\u6743\u9650\uff08\u5728\u672c\u5b9e\u9a8c\u4e2d\uff0c\u4ec5\u6d89\u53ca<code>PROT_READ, PROT_WRITE or both<\/code>\uff09\uff1b\u7b2c4\u4e2a\u53c2\u6570<code>flag<\/code>\uff0c\u8868\u793a\u5e0c\u671b\u5206\u914d\u7684\u865a\u62df\u7a7a\u95f4\u7684\u5206\u914d\u89c4\u5219\uff08\u5728\u672c\u5b9e\u9a8c\u4e2d\uff0c\u4ec5\u6d89\u53ca<code>MAP_SHARED, MAP_PRIVITE<\/code>\uff09\uff1b\u7b2c5\u4e2a\u53c2\u6570<code>fd<\/code>\uff0c\u8868\u793a\u4e00\u4e2a\u6587\u4ef6\u63cf\u8ff0\u7b26\uff1b\u7b2c6\u4e2a\u53c2\u6570<code>offset<\/code>\uff0c\u8868\u793a\u5e0c\u671b\u6620\u5c04\u7684\u6587\u4ef6\u7684\u8d77\u59cb\u4f4d\u7f6e\u504f\u79fb\u91cf\uff08\u5728\u672c\u5b9e\u9a8c\u4e2d\uff0c\u504f\u79fb\u91cf\u9ed8\u8ba4\u4e3a0\uff0c\u8868\u793a\u4ece\u6587\u4ef6\u7684\u8d77\u59cb\u4f4d\u7f6e\u5f00\u59cb\u6620\u5c04\uff09\u3002<\/p>\n<p>\u4e0b\u9762\u5bf9\u4e24\u4e2a<code>flag<\/code>\u53c2\u6570\u7684\u89e3\u91ca\uff1a<\/p>\n<ul>\n<li>MAP_SHARED\uff1a\u8868\u793a\u8be5\u6620\u5c04\u7684\u7a7a\u95f4\u662f\u5171\u4eab\u7684\uff0c\u5982\u679c\u8be5\u6620\u5c04\u7684\u7a7a\u95f4\u4e2d\u7684\u6570\u636e\u53d1\u751f\u53d8\u5316\uff0c\u5219\u5f53\u5728\u89e3\u9664\u6620\u5c04\u7684\u65f6\u5019\u5e94\u5f53\u5199\u56de\u6587\u4ef6\uff08\u4f7f\u7528<code>filewrite<\/code>\u51fd\u6570\uff09\u3002\u5f53\u6709\u4e24\u4e2a\u8fdb\u7a0b\u540c\u65f6\u6620\u5c04\u8fd9\u4e2a\u6587\u4ef6\u7684\u65f6\u5019\uff0c\u53ef\u4ee5\u4e3a\u5176\u5206\u914d\u4e0d\u540c\u7269\u7406\u7a7a\u95f4\u3002<\/li>\n<li>MAP_PRIVATE\uff1a\u8868\u793a\u8fd9\u4e2a\u6620\u5c04\u7684\u7a7a\u95f4\u662f\u79c1\u6709\u7684\uff0c<strong>\u5982\u679c\u8be5\u7a7a\u95f4\u7684\u6570\u636e\u53d1\u751f\u4e86\u53d8\u5316\uff0c\u6700\u540e\u4e5f\u4e0d\u4f1a\u5199\u56de\u6587\u4ef6\uff0c\u540c\u65f6\u8be5\u7a7a\u95f4\u7684\u6743\u9650\u4e5f\u4e0d\u53d7\u9650\u4e8e\u539f\u6587\u4ef6\u7684\u4f7f\u7528\u6743\u9650<\/strong>\u3002<\/li>\n<\/ul>\n<p>\u5982\u679c<code>mmap<\/code>\u5206\u914d\u6210\u529f\uff0c\u5219\u8fd4\u56de\u8fd9\u4e2a\u7a7a\u95f4\u7684\u8d77\u59cb\u5730\u5740\uff0c\u5982\u679c\u5931\u8d25\uff0c\u5219\u8fd4\u56de-1\u3002<\/p>\n<p>\u5bf9\u4e8e<code>munmap<\/code>\uff0c\u8be5\u7cfb\u7edf\u8c03\u7528\u6709\u4e24\u4e2a\u53c2\u6570\u3002\u7b2c\u4e00\u4e2a\u53c2\u6570<code>addr<\/code>\uff0c\u8868\u793a\u9700\u8981\u89e3\u9664\u6620\u5c04\u7684\u865a\u62df\u5730\u5740\u7684\u8d77\u59cb\u5730\u5740\u3002\u7b2c2\u4e2a\u53c2\u6570<code>length<\/code>\uff0c\u8868\u793a\u5e0c\u671b\u89e3\u9664\u6620\u5c04\u7684\u7a7a\u95f4\u7684\u5b57\u8282\u957f\u5ea6\u3002\u5982\u679c\u89e3\u9664\u6620\u5c04\u6210\u529f\uff0c\u5219\u8fd4\u56de0\uff0c\u5931\u8d25\u8fd4\u56de-1\u3002<\/p>\n<h2>2 \u6dfb\u52a0\u7cfb\u7edf\u8c03\u7528<\/h2>\n<p>\u5728\u7528\u6237\u5c42\u9762\uff0c\u4fee\u6539<code>user.pl &amp; user.h<\/code>\uff0c\u589e\u52a0\u4e24\u4e2a\u7cfb\u7edf\u8c03\u7528\u7684\u51fd\u6570\u58f0\u660e\u548c\u4e24\u4e2a\u7cfb\u7edf\u8c03\u7528\u7684\u5165\u53e3\u70b9\u3002\u5177\u4f53\u6dfb\u52a0\u65b9\u6cd5\uff0c\u53c2\u8003<code>syscall<\/code>\u5b9e\u9a8c\u3002<\/p>\n<p>\u5728\u5185\u6838\u5c42\u9762\uff0c\u4fee\u6539<code>syscall.c<\/code>\uff0c\u589e\u52a0\u58f0\u660e\u548c\u5165\u53e3\u70b9\uff1b\u4fee\u6539<code>sysproc.c<\/code>\uff0c\u6dfb\u52a0\u4e24\u4e2a\u7cfb\u7edf\u8c03\u7528\u51fd\u6570\u3002\u521d\u59cb\u8fd4\u56de\u503c\u4e3a-1\uff0c\u8868\u793a\u8c03\u7528\u5931\u8d25\u3002\u5177\u4f53\u6dfb\u52a0\u65b9\u6cd5\uff0c\u53c2\u8003<code>syscall<\/code>\u5b9e\u9a8c\u3002<\/p>\n<p><strong>\u4e3a\u4e86\u65b9\u4fbf\u540e\u9762\u6d4b\u8bd5\u548c\u8c03\u8bd5\uff0c\u53ef\u4ee5\u5c06<code>trap<\/code>\u5b9e\u9a8c\u4e2d\u7684<code>backtrace<\/code>\u90e8\u5206\u6dfb\u52a0\u81f3\u672c\u5b9e\u9a8c\u3002\u65b9\u4fbf\u81ea\u5df1\u5728\u7a0b\u5e8f\u51fa\u9519\u65f6\uff0c\u8ffd\u8e2a\u51fd\u6570\u8c03\u7528\u8fc7\u7a0b<\/strong>\u3002\uff08\u9644\u52a0\u4f7f\u7528\uff1a<code>$ addr2line -e kernel\/kernel<\/code>\uff09\u3002<\/p>\n<h2>3 \u8bbe\u8ba1VMA\u7ed3\u6784<\/h2>\n<p>\u7531\u4e8e<code>mmap<\/code>\u8981\u5206\u914d\u53ef\u7528\u7684\u865a\u62df\u5185\u5b58\u7a7a\u95f4\uff0c\u800c\u4e14\u5e0c\u671b\u80fd\u591f\u77e5\u9053\u90a3\u4e9b\u7a7a\u95f4\u662f\u53ef\u4ee5\u7528\u7684\u3002\u90a3\u6211\u4eec\u53ef\u4ee5\u8bbe\u8ba1\u4e00\u4e2a<code>VMA<\/code>\u7ed3\u6784\u4f53\uff0c\u6765\u4fdd\u5b58\u5df2\u7ecf\u5206\u914d\u7684\u865a\u62df\u5730\u5740\u7a7a\u95f4\u3002\u5728<code>6.s081 lecture 17<\/code>\u4e2d\uff0c\u4ecb\u7ecd\u4e86\u4e00\u4e9b\u5173\u4e8e<code>vma<\/code>\u7684\u8bbe\u8ba1\u3002<\/p>\n<h3>3.1 VMA\u57fa\u672c\u5c5e\u6027\u503c<\/h3>\n<ul>\n<li>addr\uff1a\u5206\u914d\u7684\u865a\u62df\u7a7a\u95f4\u7684\u8d77\u59cb\u4f4d\u7f6e<\/li>\n<li>length\uff1a\u5206\u914d\u7684\u865a\u62df\u7a7a\u95f4\u7684\u5b57\u8282\u957f\u5ea6<\/li>\n<li>file\uff1a\u6620\u5c04\u7684\u6587\u4ef6<\/li>\n<li>prot\uff1a\u6620\u5c04\u7684\u7a7a\u95f4\u6743\u9650<\/li>\n<li>flag\uff1a\u6620\u5c04\u7684\u89c4\u5219<\/li>\n<\/ul>\n<h3>3.2 \u52a8\u6001\u5206\u914dVMA<\/h3>\n<p>\u6bcf\u6b21\u5206\u914d\u865a\u62df\u5185\u5b58\u7a7a\u95f4\u65f6\uff0c\u68c0\u67e5\u6240\u6709\u5df2\u7ecf\u5206\u914d\u597d\u7684\u865a\u62df\u7a7a\u95f4\uff0c\u4ee5\u627e\u5230\u4e00\u4e2a\u672a\u88ab\u4f7f\u7528\u7684\u865a\u62df\u5185\u5b58\u7a7a\u95f4\u3002\u8fd9\u4e2a\u65b9\u5f0f\u5206\u914d\u7684\u865a\u62df\u5730\u5740\u4e0d\u662f\u56fa\u5b9a\u7684\uff0c\u968f\u7740\u5206\u914d\u6b21\u6570\u7684\u589e\u52a0\uff0c\u4f1a\u4ea7\u751f\u5927\u91cf\u7684\u5916\u90e8\u788e\u7247\uff0c\u7ef4\u62a4\u96be\u5ea6\u6bd4\u8f83\u5927\uff0c\u6240\u4ee5\u6211\u81ea\u5df1\u6ca1\u6709\u91c7\u7528\u8fd9\u4e2a\u65b9\u5f0f\u5b9e\u73b0\u3002<\/p>\n<h3>3.3 \u9759\u6001\u5206\u914dVMA<\/h3>\n<p>\u5728\u5206\u914d\u4e00\u4e2a\u65b0\u7684\u8fdb\u7a0b\u7684\u65f6\u5019\uff0c\u6211\u4eec\u5c31\u9884\u5206\u914d16\u4e2a\u53ef\u7528\u7684VMA\u7a7a\u95f4\uff0c\u5206\u914d\u5927\u5c0f\u5982\u4e0b\uff08\u5b9e\u9645\u4e0a\uff0c\u6d4b\u8bd5\u4ee3\u7801\u6700\u591a\u4e5f\u53ea\u662f\u6620\u5c04\u4e86\u5927\u5c0f\u4e3a<code>4PGSIZE<\/code>\u7684\u9875\u9762\uff09\u3002\u5f53\u6709<code>mmap<\/code>\u9700\u8981\u5206\u914d\u4e00\u4e2a\u865a\u62df\u5185\u5b58\u7a7a\u95f4\u7684\u65f6\u5019\uff0c\u6211\u4eec\u67e5\u8be2\u8fd916\u4e2aVMA\u5757\uff0c\u627e\u5230\u4e00\u4e2a\u672a\u88ab\u4f7f\u7528\uff0c\u800c\u4e14\u5927\u5c0f\u5408\u9002\u7684\u3002\u8fd9\u79cd\u65b9\u5f0f\u5bb9\u6613\u4ea7\u751f\u5185\u90e8\u788e\u7247\uff0c\u4f46\u662f\u7ef4\u62a4\u96be\u5ea6\u6781\u4f4e\u3002\u6240\u4ee5\u6211\u4f7f\u7528\u8fd9\u4e2a\u65b9\u5f0f\u3002<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/raw.githubusercontent.com\/YEWPO\/yewpoblogonlinePic\/main\/image-20221128153248485.png'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/raw.githubusercontent.com\/YEWPO\/yewpoblogonlinePic\/main\/image-20221128153248485.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"figure 1\" \/><\/div><\/p>\n<p>\u6bcf\u4e00\u4e2a\u5757\u90fd\u6709\u81ea\u5df1\u7684\u5927\u5c0f\uff0c\u548c\u81ea\u5df1\u7684\u8d77\u59cb\u4f4d\u7f6e\uff0c\u6240\u5728\u8fd9\u91cc\uff0c\u6211\u4eec\u5728<code>3.1<\/code>\u5c5e\u6027\u7684\u57fa\u7840\u4e0a\u5728\u6dfb\u52a0\u4e86\u4e24\u4e2a\u5c5e\u6027\uff1a<\/p>\n<ul>\n<li>pos\uff1a\u8be5\u865a\u62df\u7a7a\u95f4\u7684\u8d77\u59cb\u5730\u5740\u3002\u5176\u5b9e\u6bcf\u6b21<code>mmap<\/code>\u8fd4\u56de\u7684\u5730\u5740\u4e00\u5b9a\u662f\u8be5\u5757\u7684pos\u503c\u3002<\/li>\n<li>size\uff1a\u8868\u793a\u8be5\u865a\u62df\u7a7a\u95f4\u7684\u9ed8\u8ba4\u5927\u5c0f\uff0c\u5b9e\u9645\u7684\u5206\u914d\u5927\u5c0f\u53ef\u4ee5\u5c0f\u4e8e\u7b49\u4e8e\u8be5\u5927\u5c0f\u3002<\/li>\n<\/ul>\n<p>\u8bbe\u8ba1\u7684\u7ed3\u6784\u4f53\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"language-C\">struct vma {\n  struct file *file;\n  uint64 addr;\n  uint64 pos;\n  uint length;\n  uint size;\n  int prot;\n  int flag;\n};<\/code><\/pre>\n<p>\u5e76\u5728<code>struct proc<\/code>\u4e2d\u6dfb\u52a016\u4e2a<code>vma<\/code>\u5757\uff08NVMA\u5df2\u5728<code>kernel\/parma.h<\/code>\u4e2d\u5b9a\u4e49\uff0c\u4e3a16\uff09\uff1a<\/p>\n<pre><code class=\"language-C\">struct vma vma[NVMA];<\/code><\/pre>\n<h3>3.4 \u521d\u59cb\u5316VMA<\/h3>\n<h4>3.4.1 \u7528\u6237\u53ef\u7528\u7684\u865a\u62df\u7a7a\u95f4<\/h4>\n<p>\u9996\u5148\u4e86\u89e3\u4e00\u4e0b<a href=\"https:\/\/pdos.csail.mit.edu\/6.828\/2022\/xv6\/book-riscv-rev3.pdf\">xv6 book<\/a>\u7684\u7528\u6237\u8fdb\u7a0b\u7684\u865a\u62df\u5730\u5740\u7684\u5206\u914d\uff1a<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/raw.githubusercontent.com\/YEWPO\/yewpoblogonlinePic\/main\/image-20221128154730305.png'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/raw.githubusercontent.com\/YEWPO\/yewpoblogonlinePic\/main\/image-20221128154730305.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"figure 2\" \/><\/div><\/p>\n<p>\u53ef\u4ee5\u5f97\u51fa\uff0c<code>trapfram<\/code>\u4e4b\u4e0b\u6709\u4e00\u6bb5\u53ef\u4ee5\u4f7f\u7528\u7684\u865a\u62df\u5185\u5b58\u7a7a\u95f4\uff0c\u6211\u4eec\u4e0d\u59a8\u8fdb\u884c\u4ee5\u4e0b\u8bbe\u8ba1\uff1a<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/raw.githubusercontent.com\/YEWPO\/yewpoblogonlinePic\/main\/image-20221128155105155.png'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  decoding=\"async\" data-original=\"https:\/\/raw.githubusercontent.com\/YEWPO\/yewpoblogonlinePic\/main\/image-20221128155105155.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"figure 3\" \/><\/div><\/p>\n<p><code>VMA<\/code>\u5177\u4f53\u5206\u914d\u5982\u672c\u6587\u7ae0\u7684<code>figure 1<\/code>\u6240\u793a\u3002<\/p>\n<h4>3.4.2 \u9884\u5206\u914d<\/h4>\n<p>\u6211\u4eec\u5b9a\u4e49<code>va<\/code>\u8868\u793a\u4e00\u4e2a\u5757\u7684\u9876\u5730\u5740\uff0c\u6bd4\u5982\u521d\u59cb\u65f6\u4e3a<code>trapframe<\/code>\u7684\u4e0b\u7aef<code>VAMAX - 2 * PGSIZE<\/code>\uff0c\u5f53\u5206\u914d\u4e00\u4e2a\u5757\u7684\u65f6\u5019\uff0c\u5c06<code>va<\/code>\u7684\u503c\u51cf\u53bb\u8981\u5206\u914d\u7684\u5757\u7684\u5927\u5c0f\uff0c\u5373\u5f97\u5230\u4e86\u4e00\u4e2a\u5feb\u7684\u8d77\u59cb\u5730\u5740\uff1b\u5e76\u5c06\u8be5\u5757\u7684<code>size<\/code>\u5c5e\u6027\u4fee\u6539\u4e3a\u5bf9\u5e94\u7684\u5927\u5c0f\u3002<\/p>\n<p>\u521d\u59cb\u5316\u7684\u4ee3\u7801\u5982\u4e0b\uff08\u6dfb\u52a0\u81f3<code>kernel\/proc.c: allocproc()<\/code>\uff09\uff1a<\/p>\n<pre><code class=\"language-c\">...\n  uint64 va = MAXVA - 2 * PGSIZE;\n  for (int i = 0; i &lt; 6; ++i) {\n    va -= 2 * PGSIZE;\n    p-&gt;vma[i].size = 2 * PGSIZE;\n    p-&gt;vma[i].pos = va;\n  }\n\n  for (int i = 6; i &lt; 10; ++i) {\n    va -= 4 * PGSIZE;\n    p-&gt;vma[i].size = 4 * PGSIZE;\n    p-&gt;vma[i].pos = va;\n  }\n\n  for (int i = 10; i &lt; 13; ++i) {\n    va -= 8 * PGSIZE;\n    p-&gt;vma[i].size = 8 * PGSIZE;\n    p-&gt;vma[i].pos = va;\n  }\n\n  for (int i = 13; i &lt; 15; ++i) {\n    va -= 16 * PGSIZE;\n    p-&gt;vma[i].size = 16 * PGSIZE;\n    p-&gt;vma[i].pos = va;\n  }\n\n  for (int i = 15; i &lt; 16; ++i) {\n    va -= 32 * PGSIZE;\n    p-&gt;vma[i].size = 32 * PGSIZE;\n    p-&gt;vma[i].pos = va;\n  }    \n...<\/code><\/pre>\n<h2>4 \u5b9e\u73b0<code>sys_mmap<\/code><\/h2>\n<blockquote>\n<p><code>sys_mmap<\/code>\u7684\u5b9e\u73b0\u76f8\u5bf9\u6bd4\u8f83\u7b80\u5355\u548c\u5bb9\u6613\u7406\u89e3\uff0c\u5927\u81f4\u5b9e\u73b0\u8fc7\u7a0b\u5982\u4e0b\uff1a<\/p>\n<\/blockquote>\n<h3>4.1 \u83b7\u5f97\u7cfb\u7edf\u8c03\u7528\u53c2\u6570<\/h3>\n<p>\u901a\u8fc7\u4e00\u7cfb\u5217<code>arg***<\/code>\u51fd\u6570\u5f97\u5230<code>mmap<\/code>\u7684\u516d\u4e2a\u53c2\u6570\u3002\u5177\u4f53\u505a\u6cd5\u4e5f\u53ef\u4ee5\u53c2\u8003<code>syscall<\/code>\u5b9e\u9a8c\u3002<\/p>\n<h3>4.2 \u68c0\u67e5\u6743\u9650<\/h3>\n<p>\u4e0d\u540c\u7684\u6620\u5c04\u89c4\u5219\u6240\u6620\u5c04\u7684\u9875\u9762\u6743\u9650\u53ef\u4ee5\u4e0d\u5927\u4e00\u6837\u3002\u5bf9\u4e8e\u672c\u5b9e\u9a8c\u6765\u8bf4\uff0c<code>NAP_SHARED<\/code>\u7684\u6620\u5c04\u9875\u9762\u7684\u6743\u9650\u5fc5\u987b\u548c\u539f\u6587\u4ef6\u4e00\u6837\uff0c\u5982\u679c\u4e0d\u4e00\u6837\uff0c\u5219\u5e94\u8be5\u8fd4\u56de\u9519\u8bef\uff1b\u5bf9\u4e8e<code>MAP_PRIVATE<\/code>\u6765\u8bf4\uff0c\u56e0\u4e3a\u6620\u5c04\u9875\u9762\u7684\u6570\u636e\u4e0d\u7528\u5199\u56de\uff0c\u4e14\u5bf9\u4e8e\u5176\u4ed6\u8fdb\u7a0b\u4e0d\u53ef\u89c1\uff0c\u6240\u4ee5\u8be5\u6620\u5c04\u7684\u9875\u9762\u53ef\u4ee5\u548c\u539f\u6587\u4ef6\u7684\u6743\u9650\u4e0d\u4e00\u6837\u3002<\/p>\n<h3>4.3 \u641c\u7d22\u53ef\u7528VMA<\/h3>\n<p>\u904d\u5386\u6574\u4e2aVMA\u8868\uff0c\u627e\u5230\u4e00\u4e2a\u672a\u88ab\u4f7f\u7528\uff0c\u4e14\u5927\u5c0f\u6700\u4e3a\u63a5\u8fd1\u7684VMA\u5757\u3002<strong>\u5982\u679c\u5206\u914d\u6210\u529f\uff0c\u5219\u589e\u52a0\u5bf9\u8be5\u6587\u4ef6\u7684\u5f15\u7528\u6b21\u6570\uff08<code>filedup<\/code>\u51fd\u6570\uff09<\/strong>\u3002<\/p>\n<h3>4.4 \u4ee3\u7801<\/h3>\n<pre><code class=\"language-C\">uint64\nsys_mmap(void)\n{\n  uint64 addr;\n  uint length;\n  int prot;\n  int flag;\n  int fd;\n  uint offset;\n\n  argaddr(0, &amp;addr);\n  argint(1, (int*)&amp;length);\n  argint(2, &amp;prot);\n  argint(3, &amp;flag);\n  argint(4, &amp;fd);\n  argint(5, (int*)&amp;offset);\n\n  struct proc *p = myproc();\n  struct file *file = p-&gt;ofile[fd];\n\n  if (prot &amp; PROT_READ) {\n    if (!file-&gt;readable) {\n      return -1;\n    }\n  }\n\n  if (prot &amp; PROT_WRITE) {\n    if (!file-&gt;writable &amp;&amp; flag != MAP_PRIVATE) {\n      return -1;\n    }\n  }\n\n  for (int i = 0; i &lt; NVMA; ++i) {\n    if (!p-&gt;vma[i].length &amp;&amp; p-&gt;vma[i].size &gt;= length) {\n      p-&gt;vma[i].file = file;\n      p-&gt;vma[i].addr = p-&gt;vma[i].pos;\n      p-&gt;vma[i].length = length;\n      p-&gt;vma[i].prot = prot;\n      p-&gt;vma[i].flag = flag;\n      filedup(file);\n      return p-&gt;vma[i].addr;\n    }\n  }\n\n  return -1;\n}<\/code><\/pre>\n<h2>5 \u7cfb\u7edf\u5f02\u5e38<code>scause: 0xd<\/code><\/h2>\n<p>\u5f53\u5b9e\u73b0\u5b8c\u4e0a\u8ff0\u4ee3\u7801\u4e4b\u540e\uff0c\u8fd0\u884c<code>mmaptest<\/code>\u6d4b\u8bd5\uff0c\u4f1a\u5f97\u5230<code>scause = 0xd<\/code>\u7684\u9519\u8bef\u3002\u901a\u8fc7\u67e5\u8be2<code>risc-v<\/code>\u624b\u518c\u53ef\u5f97\uff0c<code>0xd<\/code>\u7684\u9519\u8bef\u8868\u793a<code>Load Page Fault<\/code>\u3002\u4ea7\u751f\u8fd9\u4e2a\u9519\u8bef\u7684\u539f\u56e0\u662f\u5206\u914d\u865a\u62df\u5185\u5b58\u65f6\u5e76\u6ca1\u6709\u5bf9\u7269\u7406\u9875\u9762\u8fdb\u884c\u6620\u5c04\uff0c\u6240\u4ee5\u8bfb\u53d6\u9875\u9762\u662f\u65f6\u4f1a\u53d1\u751f\u9519\u8bef\u3002<\/p>\n<p>\u4e3a\u4e86\u89e3\u51b3\u8fd9\u4e2a\u9519\u8bef\uff0c\u6211\u4eec\u5f15\u5165\u4e86<code>vma page fault<\/code>\u7684\u9875\u9762\u9519\u8bef\u5904\u7406\u3002<\/p>\n<h2>6 VMA page fault<\/h2>\n<p>\u5f53\u6709\u9875\u9762\u9519\u8bef\u65f6\uff0c\u4f1a\u8fdb\u5165<code>usertrap<\/code>\u51fd\u6570\u3002\uff08\u5177\u4f53\u53c2\u8003<code>trap<\/code>\u5b9e\u9a8c\uff09\u901a\u8fc7\u5224\u65ad<code>r_scause()<\/code>\u7684\u503c\u4e3a<code>0xd<\/code>\u6765\u622a\u83b7\u8fd9\u4e2a\u9519\u8bef\u3002\u5e76\u8fdb\u5165\u81ea\u5df1\u8bbe\u8ba1\u7684<code>vmapagefault()<\/code>\u51fd\u6570\u4e2d\u3002\u5177\u4f53\u53ef\u4ee5\u4eff\u7167<code>cow<\/code>\u5b9e\u9a8c\u3002<\/p>\n<h3>6.1 \u5904\u7406\u673a\u5236<\/h3>\n<ul>\n<li>\u68c0\u67e5\u865a\u62df\u5730\u5740\u662f\u5426\u5728\u5df2\u7ecf\u5206\u914d\u7684<code>VMA<\/code>\u4e2d\u3002\u5982\u679c\u4e0d\u5728\u5176\u4e2d\uff0c\u5219\u8be5\u9519\u8bef\u4e0d\u662f<code>vma page fault<\/code>\uff0c\u8fd4\u56de\u9519\u8bef\u7801-1\u3002<\/li>\n<li>\u5206\u914d\u7269\u7406\u9875\u9762\uff0c\u5982\u679c\u5206\u914d\u9519\u8bef\uff0c\u5219\u8fd4\u56de\u9519\u8bef\u7801-1\u3002<strong>\u5206\u914d\u6210\u529f\u4e4b\u540e\u8bb0\u5f97\u7ed9\u8be5\u9875\u9762\u6e05\u96f6\uff08memset\uff09\uff0c\u5982\u679c\u4e0d\u6e05\u96f6\uff0c\u540e\u679c\u8bf7\u81ea\u5df1\u5c1d\u8bd5\u3002\uff08hint\uff1a<code>kernel\/kalloc.c: kalloc()<\/code>RTFSC\uff09<\/strong><\/li>\n<li>\u8bfb\u53d6\u6587\u4ef6\u6570\u636e\u5230\u7269\u7406\u5185\u5b58\u4e2d\u3002\u5982\u679c\u8bfb\u53d6\u5931\u8d25\uff0c\u91ca\u653e\u7269\u7406\u5185\u5b58\uff0c\u5e76\u8fd4\u56de\u9519\u8bef\u7801-1\u3002\uff08\u8bfb\u53d6\u6570\u636e\u4f7f\u7528<code>readi<\/code>\u51fd\u6570\uff0c\u8be5\u51fd\u6570\u5728<code>kernel\/fs.c<\/code>\u4e2d\uff0c\u5177\u4f53\u7528\u6cd5\uff0c\u8bf7<code>RTFSC<\/code>\uff09\u3002<strong>\u4f7f\u7528\u8be5\u51fd\u6570\u4e4b\u524d\uff0c\u8981\u5bf9<code>inode<\/code>\u8282\u70b9\u4e0a\u9501\uff0c\u8bfb\u53d6\u5b8c\u6210\u4e4b\u540e\u8981\u4e0b\u9501\u3002\u4e0b\u9501\u8bf7\u4f7f\u7528<code>iunlock<\/code><\/strong>\uff0c\u4e0d\u8981\u4f7f\u7528<code>iunlockput<\/code>\uff0c\u56e0\u4e3a\u4e0d\u6d89\u53ca\u4fee\u6539\u64cd\u4f5c\u3002<\/li>\n<li>\u6dfb\u52a0\u6620\u5c04\u89c4\u5219\u3002\u4f7f\u7528<code>mappages<\/code>\u51fd\u6570\u5b8c\u6210\u865a\u62df\u5730\u5740<code>va<\/code>\u5230\u7269\u7406\u5730\u5740<code>pa<\/code>\u4e4b\u95f4\u7684\u6620\u5c04\u3002<strong>\u9664\u4e86\u8981\u6dfb\u52a0<code>prot<\/code>\u6807\u8bb0\u4ee5\u5916\uff0c\u8fd8\u9700\u6807\u8bb0<code>PTE_U<\/code>\uff0c\u8868\u793a\u7528\u6237\u53ef\u4ee5\u8bbf\u95ee\u8fd9\u4e2a\u9875\u9762<\/strong>\u3002\u5982\u679c\u6620\u5c04\u9519\u8bef\uff0c\u91ca\u653e\u7269\u7406\u7a7a\u95f4\uff0c\u8fd4\u56de\u9519\u8bef\u7801-1\u3002<\/li>\n<li>\u5bf9\u4e8e\u4ee5\u4e0a\u7684\u6240\u6709\u9519\u8bef\uff0c\u8fd4\u56de\u9519\u8bef\u7801\u4e4b\u540e\u6740\u6b7b\u8fdb\u7a0b\u3002<\/li>\n<\/ul>\n<h3>6.2 \u4ee3\u7801<\/h3>\n<p><code>kernel\/trap.c<\/code>\u4e2d\u5b9e\u73b0\u4ee5\u4e0b\u90e8\u5206\uff1a<\/p>\n<pre><code class=\"language-C\">int\nvmapagefault(struct proc *p, uint64 va)\n{\n  int index;\n  for (index = 0; index &lt; NVMA; ++index) {\n    if (p-&gt;vma[index].addr &lt;= va &amp;&amp; va &lt; p-&gt;vma[index].addr + p-&gt;vma[index].length) {\n      break;\n    }\n  }\n\n  if (index &gt;= 16) {\n    printf(&quot;not vma\\n&quot;);\n    return -1;\n  }\n\n  uint64 pa;\n\n  if ((pa = (uint64)kalloc()) == 0) {\n    printf(&quot;kalloc failed\\n&quot;);\n    return -1;\n  }\n\n  memset((void*)pa, 0, PGSIZE);\n\n  ilock(p-&gt;vma[index].file-&gt;ip);\n  if (readi(p-&gt;vma[index].file-&gt;ip, 0, pa, va - p-&gt;vma[index].pos, PGSIZE) &lt; 0) {\n    kfree((void*)pa);\n    iunlock(p-&gt;vma[index].file-&gt;ip);\n    printf(&quot;readi failed\\n&quot;);\n    return -1;\n  }\n  iunlock(p-&gt;vma[index].file-&gt;ip);\n\n  int perm = PTE_U | (p-&gt;vma[index].prot &lt;&lt; 1);\n\n  if (mappages(p-&gt;pagetable, va, PGSIZE, pa, perm) &lt; 0) {\n    kfree((void*)pa);\n    printf(&quot;mapapges failed\\n&quot;);\n    return -1;\n  }\n\n  return 0;\n}<\/code><\/pre>\n<p>\u5b9e\u73b0\u4e86\u4ee5\u4e0a\u90e8\u5206\u540e\uff0c<code>mmaptest<\/code>\u53ef\u4ee5\u6d4b\u8bd5\u5230<code>munmap<\/code>\uff0c\u5e76\u56e0\u4e3a\u9519\u8bef\u7ed3\u675f\u6d4b\u8bd5\u3002<\/p>\n<h2>7 \u5b9e\u73b0<code>sys_munmap<\/code><\/h2>\n<blockquote>\n<p><code>sys_munmap<\/code>\u5b9e\u73b0\u4f1a\u6bd4<code>sys_mmap<\/code>\u7a0d\u663e\u590d\u6742\u4e00\u70b9\uff0c\u4f46\u4e5f\u4e0d\u7b97\u590d\u6742\uff0c\u552f\u4e00\u8981\u89e3\u51b3\u7684\u95ee\u9898\u662f\uff0c\u4e0d\u662f\u6240\u6709\u9875\u9762\u90fd\u9700\u8981\u89e3\u9664\u548c<strong>\u7269\u7406\u9875\u9762<\/strong>\u7684\u6620\u5c04\u3002<\/p>\n<\/blockquote>\n<p>\u5927\u81f4\u7684\u5b9e\u73b0\u8fc7\u7a0b\u5982\u4e0b\uff1a<\/p>\n<h3>7.1 \u83b7\u5f97\u7cfb\u7edf\u8c03\u7528\u53c2\u6570<\/h3>\n<p>\u83b7\u53d6\u65b9\u5f0f\u548c<code>4.1<\/code>\u7c7b\u4f3c\u3002<\/p>\n<h3>7.2 \u662f\u5426\u4e3aVMA\uff1f<\/h3>\n<p>\u904d\u5386\u6574\u4e2aVMA\u8868\uff0c\u68c0\u67e5\u9700\u8981\u91ca\u653e\u865a\u62df\u7a7a\u95f4\u7684\u8d77\u59cb\u5730\u5740\u662f\u5426\u5c5e\u4e8e<code>vma<\/code>\uff0c\u5e76\u83b7\u5f97<code>VMA<\/code>\u5757\u7684\u4e0b\u6807\u3002\u5982\u679c\u4e0d\u662f<code>VMA<\/code>\u5757\uff0c\u5219\u8fd4\u56de\u9519\u8bef\u7801-1\u3002<\/p>\n<h3>7.3 \u68c0\u67e5\u5408\u6cd5\u6027<\/h3>\n<p>\u5982\u679c\u8981\u91ca\u653e\u7684\u7a7a\u95f4\u7684\u8303\u56f4\u8d85\u8fc7\u4e86<code>VMA<\/code>\u5757\u7684\u8303\u56f4\uff0c\u5219\u8fd4\u56de\u9519\u8bef\u7801-1\u3002<\/p>\n<h3>7.4 \u5199\u56de\u6587\u4ef6<\/h3>\n<p>\u5982\u679c\u8be5\u7a7a\u95f4\u7684\u6620\u5c04\u89c4\u5219\u662f<code>MAP_SHARED<\/code>\uff0c\u5219\u5c06\u8be5\u865a\u62df\u5185\u5b58\u7a7a\u95f4\u4e2d\u7684\u6570\u636e\u5199\u56de\u6587\u4ef6\u3002\u5199\u56de\u6587\u4ef6\u4f7f\u7528<code>filewrite<\/code>\u51fd\u6570\uff0c\u8be5\u51fd\u6570\u7684\u5177\u4f53\u4f7f\u7528\u65b9\u6cd5\u8bf7<code>RTFSC<\/code>\u3002<\/p>\n<h3>7.5 \u89e3\u9664\u548c\u7269\u7406\u5185\u5b58\u4e4b\u95f4\u7684\u6620\u5c04<\/h3>\n<p>\u68c0\u67e5\u91ca\u653e\u7684\u7a7a\u95f4\u91cc\u7684\u6240\u6709\u9875\u9762\uff0c\u83b7\u5f97\u6bcf\u4e2a\u9875\u9762\u7684<code>pte<\/code>\uff0c\u68c0\u67e5\u8be5PTE\u662f\u5426\u6709\u6548\u3002\u5982\u679c\u6709\u6548\uff0c\u5219\u89e3\u9664\u8be5\u9875\u9762\u548c\u7269\u7406\u9875\u9762\u4e4b\u95f4\u7684\u6620\u5c04\u5173\u7cfb\u3002<strong>\u5e76\u4e0d\u53ef\u4ee5\u76f4\u63a5\u89e3\u9664\u6574\u4e2a\u9875\u9762\u7684\u7269\u7406\u5185\u5b58\u6620\u5c04\uff0c\u56e0\u4e3a\u53ef\u80fd\u67d0\u4e9b\u9875\u9762\u7684\u6620\u5c04\u5e76\u4e0d\u5b58\u5728\u3002<\/strong><\/p>\n<h3>7.6 \u4fee\u6539VMA\u5757\u5c5e\u6027<\/h3>\n<p>\u7531\u4e8e\u672c\u5b9e\u9a8c\u89e3\u9664\u7684\u6620\u5c04\u7684\u5757\u90fd\u662f\u81ea\u4e0b\u800c\u4e0a\u89e3\u9664\u6620\u5c04\uff0c\u6240\u4ee5\uff0c\u4fee\u6539\u65b9\u5f0f\u6bd4\u8f83\u7b80\u5355\uff0c\u5e76\u6ca1\u6709\u8003\u8651\u6bd4\u8f83\u590d\u6742\u7684\u60c5\u51b5\u3002<\/p>\n<p>\u5bf9\u4e8e\u5c5e\u6027\u5730\u5740<code>addr<\/code>\uff0c\u76f4\u63a5\u5c06\u8be5\u5730\u5740\u52a0\u4e0a\u89e3\u9664\u6620\u5c04\u7684\u5927\u5c0f\u3002<\/p>\n<p>\u5bf9\u4e8e\u5c5e\u6027\u6620\u5c04\u5927\u5c0f<code>length<\/code>\uff0c\u76f4\u63a5\u5c06\u8be5\u503c\u51cf\u53bb\u89e3\u9664\u6620\u5c04\u7684\u5927\u5c0f\u3002<\/p>\n<p>\u5982\u679c\u5df2\u7ecf\u89e3\u9664\u5b8c\u4e86\u6574\u4e2a\u5757\u7684\u6620\u5c04\uff0c\u5219<strong>\u89e3\u9664\u5bf9\u6587\u4ef6\u7684\u5f15\u7528<\/strong>\uff0c\u89e3\u9664\u5f15\u7528\u4f7f\u7528<code>fileclose()<\/code>\u51fd\u6570\u3002<\/p>\n<h3>7.7 \u4ee3\u7801<\/h3>\n<pre><code class=\"language-C\">uint64\nsys_munmap(void)\n{\n  uint64 addr;\n  uint length;\n\n  argaddr(0, &amp;addr);\n  argint(1, (int*)&amp;length);\n\n  struct proc *p = myproc();\n\n  int index;\n  for (index = 0; index &lt; NVMA; ++index) {\n    if (p-&gt;vma[index].addr &lt;= addr &amp;&amp; addr &lt; p-&gt;vma[index].addr + p-&gt;vma[index].length) {\n      break;\n    }\n  }\n\n  if (index &gt;= 16) {\n    return -1;\n  }\n\n  if (length &gt; p-&gt;vma[index].length) {\n    return -1;\n  }\n\n  if (p-&gt;vma[index].flag == MAP_SHARED) {\n    filewrite(p-&gt;vma[index].file, addr, length);\n  }\n\n  uint64 va;\n  for (va = addr; va &lt; addr + length; va += PGSIZE) {\n    pte_t *pte = walk(p-&gt;pagetable, va, 0);\n\n    if (*pte &amp; PTE_V) {\n      uvmunmap(p-&gt;pagetable, va, 1, 0);\n    }\n  }\n\n  p-&gt;vma[index].addr = addr + length;\n  p-&gt;vma[index].length -= length;\n\n  if (p-&gt;vma[index].length == 0) {\n    fileclose(p-&gt;vma[index].file);\n  }\n\n  return 0;\n}<\/code><\/pre>\n<p>\u5b9e\u73b0\u4ee5\u4e0a\u4ee3\u7801\u4e4b\u540e\uff0c\u53ef\u901a\u8fc7<code>fork<\/code>\u4e4b\u524d\u7684<code>mmaptest<\/code>\u6d4b\u8bd5\u3002<\/p>\n<h2>8 \u5b8c\u5584<code>fork &amp; exit<\/code><\/h2>\n<h3>8.1 fork<\/h3>\n<p>\u5f53\u4e00\u4e2a\u8fdb\u7a0b\u65b0\u5efa\u4e00\u4e2a\u5b50\u8fdb\u7a0b\u7684\u65f6\u5019\uff0c\u9700\u8981\u5bf9<code>VMA<\/code>\u8868\u8fdb\u884c\u590d\u5236\uff08\u539f\u56e0\u53c2\u8003<code>1<\/code>\u4e2d\u7684\u624b\u518c\u5185\u5bb9\uff09\uff0c<strong>\u5982\u679c\u6709\u6587\u4ef6\u6620\u5c04\uff0c\u5219\u5e94\u8be5\u7528<code>filedup<\/code>\u589e\u52a0\u5bf9\u8be5\u6587\u4ef6\u7684\u5f15\u7528<\/strong>\u3002<\/p>\n<p>\u4ee3\u7801\u5982\u4e0b\uff08<code>kernel\/proc.c: fork()<\/code>\uff09:<\/p>\n<pre><code class=\"language-C\">fork()\n{\n    ...\n  for (i = 0; i &lt; NVMA; ++i) {\n    np-&gt;vma[i] = p-&gt;vma[i];\n    if (np-&gt;vma[i].length) {\n      filedup(np-&gt;vma[i].file);\n    }\n  }\n    ...\n}<\/code><\/pre>\n<h3>8.2 exit<\/h3>\n<p>\u5f53\u4e00\u4e2a\u8fdb\u7a0b\u7ed3\u675f\u7684\u65f6\u5019\uff0c\u5e94\u5f53\u89e3\u9664\u672a\u53ca\u65f6\u89e3\u9664\u6620\u5c04\u7684VMA\uff0c<strong>\u5e76\u51cf\u5c11\u76f8\u5173\u6587\u4ef6\u7684\u5f15\u7528<\/strong>\uff0c\u8fc7\u7a0b\u7c7b\u4f3c<code>7.5<\/code>\u3002<\/p>\n<p>\u4ee3\u7801\u5982\u4e0b\uff08<code>kernel\/proc.c: exit()<\/code>\uff09:<\/p>\n<pre><code class=\"language-C\">exit()\n{\n    ...\n    for (int i = 0; i &lt; NVMA; ++i) {\n    if (p-&gt;vma[i].length) {\n      if (p-&gt;vma[i].flag == MAP_SHARED) {\n        filewrite(p-&gt;vma[i].file, p-&gt;vma[i].addr, p-&gt;vma[i].length);\n      }\n\n      uint64 va;\n      for (va = p-&gt;vma[i].addr; va &lt; p-&gt;vma[i].addr + p-&gt;vma[i].length; va += PGSIZE) {\n        pte_t *pte = walk(p-&gt;pagetable, va, 0);\n        if (*pte &amp; PTE_V) {\n          uvmunmap(p-&gt;pagetable, va, 1, 0);\n        }\n      }\n\n      fileclose(p-&gt;vma[i].file);\n      p-&gt;vma[i].length = 0;\n    }\n  }\n  ...\n}<\/code><\/pre>\n<h2>9 END<\/h2>\n<p>\u7ecf\u8fc7\u4e00\u5929\u7684\u52aa\u529b\uff0c\u91cd\u6784\u4e86\u4e00\u6b21\u4ee3\u7801\uff0c\u6d4b\u8bd5\u7ed3\u679c\u5982\u4e0b\uff0c\u81f3\u6b64\uff0c\u4e5f\u5b8c\u6210\u4e86\u6574\u4e2a<code>6.1810 operation system course lab fall 2022<\/code>\uff1a<\/p>\n<pre><code>== Test   mmaptest: mmap f ==\n  mmaptest: mmap f: OK\n== Test   mmaptest: mmap private ==\n  mmaptest: mmap private: OK\n== Test   mmaptest: mmap read-only ==\n  mmaptest: mmap read-only: OK\n== Test   mmaptest: mmap read\/write ==\n  mmaptest: mmap read\/write: OK\n== Test   mmaptest: mmap dirty ==\n  mmaptest: mmap dirty: OK\n== Test   mmaptest: not-mapped unmap ==\n  mmaptest: not-mapped unmap: OK\n== Test   mmaptest: two files ==\n  mmaptest: two files: OK\n== Test   mmaptest: fork_test ==\n  mmaptest: fork_test: OK\n== Test usertests ==\n$ make qemu-gdb\nusertests: OK (222.1s)\n== Test time ==\ntime: OK\nScore: 140\/140<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>xv6\u64cd\u4f5c\u7cfb\u7edf\u5b9e\u9a8c10\u3002<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[14],"class_list":["post-64","post","type-post","status-publish","format-standard","hentry","category-os","tag-xv6"],"_links":{"self":[{"href":"https:\/\/www.yewpo.top\/index.php\/wp-json\/wp\/v2\/posts\/64","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.yewpo.top\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.yewpo.top\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.yewpo.top\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.yewpo.top\/index.php\/wp-json\/wp\/v2\/comments?post=64"}],"version-history":[{"count":0,"href":"https:\/\/www.yewpo.top\/index.php\/wp-json\/wp\/v2\/posts\/64\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.yewpo.top\/index.php\/wp-json\/wp\/v2\/media?parent=64"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.yewpo.top\/index.php\/wp-json\/wp\/v2\/categories?post=64"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.yewpo.top\/index.php\/wp-json\/wp\/v2\/tags?post=64"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}