首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

MIT 6.S081 教材第八章内容 -- 文件系统 -- 02

iget()返回struct inode指针相应iput()调用之前保证有效: inode不会被删除,指针引用内存也不会被其他inode重用。...,直接返回 // 文件系统,目录是一种特殊类型文件,它包含其他文件和子目录条目。...清理大型文件系统可能需要数小时时间,而且某些情况下,无法以导致原始系统调用原子化方式解决不一致问题。从日志恢复要快得多,并且崩溃时会导致系统调用原子化。...不同于xv6fileread和filewriteif语句,这些系统通常为每个打开文件提供一个函数指针表,每个操作一个,并通过函数指针来援引inode调用实现。...网络文件系统和用户级文件系统提供了将这些调用转换为网络RPC并在返回之前等待响应函数。---- 练习 为什么要在ballocpanic?xv6可以恢复吗? 为什么要在iallocpanic?

29340

xv6(6) 系统调用

$Linux$ 里面系统调用使用向量号是 $0x80$,$xv6$ 里面使用 $64$(不同 $xv6$ 版本可能不同)。...代码部分 先来看张总图把握一下整体流程: 首先便是用户接口部分,用户接口是操作系统提供系统调用 $API$ 函数,一般是 $POSIX$ 标准,$xv6$ 关于这用户接口定义 $user.h$ ,...这里还使用了一些宏定义,首先是系统调用号,定义 $syscall.h$ 当中,随便看几个意思一下: #define SYS_fork 1 #define SYS_getpid 11...关于系统调用还剩下最后一个问题,根据上述内核具体系统调用函数原型可以看出,它们返回类型都是 $int$ 型且没有参数,但是有些系统调用是需要参数,所以那些需要参数系统调用就要去获取参数,去哪获取呢...注意这里使用是二级指针,为什么要使用二级指针,我们来看看如果使用一级指针会发生什么,如果这个函数是这样: int argptr(int n, char *pp, int size) //pp类型变为

29010
您找到你想要的搜索结果了吗?
是的
没有找到

xv6(13) 文件系统:文件描述符&系统调用

根据定义,可以看出 $xv6$ 这个系统最多支持打开 $100$ 个文件。...答案不是,比如文件结构体文件类型定义了 $FD_NONE$, $FD_INODE$, $FD_PIPE$ 三种类型,分别表示 无,$inode$ 型,管道型文件,$xv6$ 里会根据文件结构体里面的文件类型使用不同操作方法... $inode$ 定义有文件类型: $T_DIR$, $T_FILE$, $T_DEV$,分别表示目录文件,普通文件,设备文件。...这里简单再过一下系统调用,$xv6$ 系统调用使用 INT 64 指令来实现,触发一个 $64$ 号中断陷入内核,根据向量号 $64$ 去获取执行中断服务程序。...执行系统调用之前传入了系统调用号,中断服务程序根据系统调用号获取执行内核功能函数。

32610

MIT6.828实验2 —— Lab Shell

;对系统调用异常进行处理 xv6提供有sh.c实现,除了重定向和管道,还对括号、列表命令、后台命令等做了支持,且整体设计较为复杂。...工作原理是启动后不断接收并解析用户输入命令,调用操作系统接口去执行命令,并把结果返回给用户。...首先需要了解几个核心系统调用: * **fork() :** 该调用会创建一个子进程,会复制一份内存到独立进程空间,代码根据返回值来区分是子进程 (返回0) 还是父进程 (返回子进程pid)。...,等到具体使用时候,再根据type字段类型,强转回具体类型进行使用。...(指针指向结构体首地址,根据声明来访问字段,所以这里强转不影响使用)。 这里使用了面向对象思想,借助指针类型强转实现了类似于"多态"效果。

1.7K30

MIT 6.S081 (BOOK-RISCV-REV1)教材第三章内容 -- 页表

kinit调用freerange将内存添加到空闲列表freerange每页都会调用kfree。...当进程向xv6请求更多用户内存时,xv6首先使用kalloc来分配物理页面。然后,它将PTE添加到进程页表,指向新物理页面。...作为返回值,它提供一个指向新分配内存起始位置指针 uint64 sys_sbrk(void) { int addr; int n; //从a0系统调用参数寄存器取出参数值 if...exec是创建地址空间用户部分系统调用: 它使用一个存储文件系统文件初始化地址空间用户部分。...exec必须等待系统调用成功后再释放旧映像:因为如果旧映像消失了,系统调用将无法返回-1。exec唯一错误情况发生在映像创建过程

77440

MIT_6.s081_Lab

trace(1<<SYS_USER_FORK).我们需要修改 xv6 内核以每个系统调用即将返回时打印出一行.该行应包含进程id、系统调用名称和返回值,我们还必须对这个进程以及所有子进程进行跟踪....现在我们开始实验: 1) user.h添加对于trace函数支持. 图片 这里面存储了所有user函数会调用系统调用. 2) 添加一个entryuser.pl里面 #!...这消除了执行这些系统调用时对内核交叉需要。 创建每个进程时, USYSCALL(memlayout.h 定义 VA)映射一个只读页面。...● kernel/defs.h定义vmprint原型,以便可以从exec.c调用它。 ● printf调用使用%p输出完整64位十六进制PTE和地址,如示例所示。...输出应如下: 1) def.h添加backtrace()函数声明. 2) GCC 编译器将当前执行函数指针存储寄存器s0,s0就对应上面的fp指针. static inline uint64

1.1K10

笔记 Lab2: System calls | 系统调用

xv6 添加一些新系统调用,帮助加深对 xv6 内核理解。 System call tracing (moderate) 准备环境,编译编译器、QEMU,克隆仓库,略过。...添加一个系统调用 trace 功能,为每个进程设定一个位 mask,用 mask 设定位来指定要为哪些系统调用输出调试信息。...用 extern 全局声明新内核调用函数,并且 syscalls 映射表,加入从前面定义编号到系统调用函数指针映射 // kernel/syscall.c extern uint64 sys_chdir...p->trapframe->a0 = syscalls[num](); // 通过系统调用编号,获取系统调用处理函数指针调用并将返回值存到用户进程 a0 寄存器 // 如果当前进程设置了对该编号系统调用...添加一个系统调用返回空闲内存、以及已创建进程数量。大多数步骤和上个实验是一样,所以不再描述。唯一不同就是需要把结构体从内核内存拷贝到用户进程内存

92920

MIT 6.S081 Lab Three -- 页表

一些提示: 你可以将vmprint()放在kernel/vm.c 使用定义kernel/riscv.h末尾处宏 函数freewalk可能会对你有所启发 将vmprint原型定义kernel/defs.h...,这样你就可以exec.c调用它了 在你printf调用使用%p来打印像上面示例完成64比特十六进制PTE和地址 QUESTION 根据文本图3-4解释vmprint输出。...因此,当内核需要使用系统调用传递用户指针(例如,传递给write()缓冲区指针)时,内核必须首先将指针转换为物理地址。本节和下一节目标是允许内核直接解引用用户指针。...你将会考虑allocproc调用这个函数 确保每一个进程内核页表都关于该进程内核栈有一个映射。未修改XV6,所有的内核栈都在procinit设置。...YOUR JOB 将定义kernel/vm.ccopyin主题内容替换为对copyin_new调用kernel/vmcopyin.c定义); 对copyinstr和copyinstr_new

27140

MIT 6.S081 (BOOK-RISCV-REV1)教材第一章内容 --- 操作系统接口

例如:当wait返回值存入父进程变量pid时,并不会影响子进程pid,子进程pid仍然为0。 exec系统调用使用从文件系统存储文件所加载新内存映像替换调用进程内存。...xv6使用ELF格式(将会在第三章详细讨论)。当exec执行成功,它不向调用进程返回数据,而是使加载自文件指令ELF header声明程序入口处开始执行。...它填充一个stat类型结构体,struct statstat.h(kernel/stat.h)定义为: #define T_DIR 1 // Directory #define T_FILE...添加命令之前,确保将可执行文件放置适当位置,并根据需要设置文件执行权限。这样,当用户命令行输入新命令时,系统就能够找到并执行对应用户级程序。...Unix系统调用接口已经通过便携式操作系统接口(POSIX)标准进行了标准化。Xv6与POSIX兼容: 它缺少许多系统调用(包括lseek等基本系统调用),并且它提供许多系统调用与标准不同。

22420

MIT 6.S081 Lab Four -- Trap

backtrace应当使用这些帧指针来遍历栈,并在每个栈帧打印保存返回地址。...注意返回地址位于栈帧帧指针固定偏移(-8)位置,并且保存指针位于帧指针固定偏移(-16)位置 XV6在内核以页面对齐地址为每个栈分配一个页面。...先使用r_fp()读取当前指针,然后读出返回地址并打印,再将fp定位到前一个帧指针位置继续读取即可。 根据提示:XV6在内核以页面对齐地址为每个栈分配一个页面。...---- Alarm(Hard) YOUR JOB 在这个练习你将向XV6添加一个特性,进程使用CPU时间内,XV6定期向进程发出警报。...如果一个程序调用了sigalarm(0, 0),系统应当停止生成周期性报警调用。 你将在XV6存储库中找到名为user/alarmtest.c文件。将其添加到Makefile。

23130

xv6(19) SHELL交互程序

接下来还是回到 $xv6$ 管道创建上面,系统调用 $pipe$ 用来创建一个管道,它调用了另一个函数 $pipealloc$ 来分配管道文件文件结构体和内存,先来看看这个函数: int pipealloc...这些概念不懂没关系,看后面实际代码使用也就明白了。...这里提一句虽然 $shell$ 里面区分了输出重定向覆盖和追加两种情况,但实际 $xv6$ 还没有实现相应功能,这需要我们自行添加这个功能,具体点就是从文件结构体偏移量入手。...另外管道是属于内核一片内存区域,$xv6$ 机制很简单,回收管道资源就是依靠 $close$ 系统调用,它会调用 $fileclose$ 来减少文件结构体引用数,当文件结构体引用数减少到 0 时候就会调用...总而言之 $xv6$ 机制少,使用方面也要符合习惯于规范。关于文件系统和进程资源回收详见前文,这里赘述。

31710

xv6(18) 控制台输入输出

为什么 $write$ 系统调用使用文件描述符 $1$ 就会将消息打印到屏幕?$printf$ 函数又是如何实现?看完本文相信你会找到答案。...现今键盘大多数都是用第二套键盘扫描码,但也排除使用第一套和第三套,所以为了兼容,键盘控制器会统统地转换为第一套扫描码。...调用 $dup$ 函数之后,文件描述符 1,2 也指向了文件表控制台文件结构体,如下图所示: 所以说当我们调用 $write$ 和 $read$ 系统调用时,指定文件描述符如果为 $0、1、2$,则它们指向控制台文件结构体...$va_arg$ 使得 $ap$ 指向下一个参数地址,做类型转换再解引用返回其值。...加 4 是因为一般用到类型如 $char$、$short$、指针等等传参压栈时候实际上都是占用 4 字节,这涉及到了默认参数提升, $c$ 缺陷和陷进,细说,后面有相关文章链接。

26210

MIT_6.s081_Lab1:Xv6 and Unix utilities

将程序添加到 Makefile UPROGS。 xv6用户程序有一组有限库函数可供它们使用。...可以使用write(写端口,写出来元素写在哪里,长度)来把元素写进一个端口. fork函数就是一次调用,两次返回,调用之后父进程和子进程都从获得函数返回值开始继续往下运行,就像一条河流,遇到了一个分叉口...当管道写端关闭时,read 返回零。 将 32 位(4 字节)整数直接写入管道是最简单,而不是使用格式化 ASCII I/O。 您应该仅在需要时管道创建流程。...下面就是stat信息,stat信息存放了文件一些控制信息,比如说链接信息,大小和类型之类.我们利用open打开文件后,open函数会返回一个数字,我们再利用fstat这个调用找到stat控制块....对文件系统更改在 qemu 运行持续存在; 要获得一个干净文件系统,请运行 make clean 然后 make qemu。 将程序添加到 Makefile UPROGS。

75220

MIT 6.S081 (BOOK-RISCV-REV1)教材第二章内容 -- 操作系统架构

例如,使用第1章描述系统调用接口,一个进程可以用fork启动新进程。 操作系统必须在这些进程之间分时使用计算机资源。 例如,即使进程比硬件处理器多,操作系统也必须确保所有进程都有机会执行。...想要调用内核函数应用程序(例如xv6read系统调用)必须过渡到内核。...---- 代码(XV6架构篇) XV6源代码位于kernel/*子目录,源代码按照模块化概念划分为多个文件,图2.2列出了这些文件,模块间接口都被定义了def.h*(*kernel/defs.h...有许多因素限制了进程地址空间最大范围: RISC-V上指针有64位宽;硬件页表查找虚拟地址时只使用低39位;xv6使用这39位38位。...当进程进入内核(由于系统调用或中断)时,内核代码进程内核堆栈上执行;当一个进程在内核时,它用户堆栈仍然包含保存数据,只是处于活动状态。进程线程主动使用用户栈和内核栈之间交替。

31720

xv6(17) 进程三:代码部分

): 根据调度算法挑一个进程出来,这里我们称之为进程 $B$ 调用上述 $swtch$ 函数切换到进程 $B$ 调度算法 我调度算法总结了常见几种调度算法,诸位可以一观,其中就包括了 $xv6$...#define KSTACKSIZE 4096 使用 $kalloc$ 函数空闲空间分配了一页作为内核栈,它位置固定,完全却决于当时内存使用情况。...返回 $exec$ 最后一部分我们来讨论返回相关问题,$exec$ 是个系统调用系统调用流程在前文系统调用如何实现时候出过一张图,当时是用 $write$ 为例子来说,这里来看一眼: 每个系统调用基本流程都是差不多...$RPL$ 应为 $3$ 用户态 总之 $kill$ 就是强迫某个进程执行 $exit$ $LOCK$ 锁同步问题一直是操作系统里面最为复杂问题之一,$xv6$ 设计锁一篇已经聊过,$xv6...没有问题 进程相关系统调用 这里来简单看看有关进程系统调用,$xv6$ 里系统调用用户接口和内核函数名字很多都是一样,不要搞混了 fork 用户接口: int fork(void); 内核函数:

32910

MIT 6.S081 教材第六章内容 -- 锁 -- 下

---- 为什么要使用锁? 使用多个CPU核可以带来性能提升,如果一个应用程序运行在多个CPU核上,并且执行了系统调用,那么内核需要能够处理并行系统调用。...但是实际情况有些令人失望,因为我们想要通过并行来获得高性能,我们想要并行不同CPU核上执行系统调用,但是如果这些系统调用使用了共享数据,我们又需要使用锁,而锁又会使得这些系统调用串行执行,所以最后锁反过来又限制了性能...系统调用会按照这样流程处理: 一个系统调用获取到了big kernel lock,完成自己操作,之后释放这个big kernel lock,再返回到用户空间,之后下一个系统调用才能执行。...这样的话,如果我们有一个应用程序并行调用多个系统调用,这些系统调用会串行执行,因为我们只有一把锁。 所以通常来说,例如XV6操作系统会有多把锁,这样就能获得某种程度并发执行。...如果对于所有的锁有了一个全局排序,这里死锁就不会出现了。 不过设计一个操作系统时候,定义一个全局顺序会有些问题。

16540

MIT 6.S081 Lab Nine --- file system

MIT 6.S081课程前置基础参考: 基于RISC-V搭建操作系统系列 ---- File system 本实验室,您将向xv6文件系统添加大型文件和符号链接。...ALL TESTS PASSED $ 提示: 首先,为symlink创建一个新系统调用号,user/usys.pl、user/user.h添加一个条目,并在kernel/sysfile.c实现一个空...向kernel/stat.h添加文件类型(T_SYMLINK)以表示符号链接。 kernel/fcntl.h添加一个新标志(O_NOFOLLOW),该标志可用于open系统调用。...---- 硬链接 简单复习一下xv6硬链接实现: xv6 ,硬链接是一种创建多个目录项指向同一个 inode 方法,从而允许一个文件文件系统中有多个不同名称。...配置系统调用常规操作,如在user/usys.pl、user/user.h添加一个条目,kernel/syscall.c、kernel/syscall.h添加相关内容 // usys.pl entry

30530

XV6操作系统代码阅读心得(一):启动加载、中断与系统调用

但是,XV6系统启动过程,第一条指令就使用cli指令来屏蔽中断,直到第一个进程调度时才会在scheduler()里使用STI指令允许硬件中断。...因此,即使是第一个用户进程启动时,XV6系统也会在内核态手动构建Trap Frame,设置Trap FrameCS寄存器上相关权限位,然后调用中断返回函数进入用户态。...如何在XV6添加系统调用(以setrlimit为例) Linux系统,setrlimit系统调用作用是设置资源使用限制。...我们以setrlimit为例,要在XV6系统添加一个新系统调用,首先在syscall.h添加一个新系统调用定义 #define SYS_setrlimit 22 然后,syscall.c增加新系统调用函数指针...setrlimit()这个函数系统调用函数接口,并在usys.S添加有关用户系统调用接口。

1.6K20

xv6(12) 文件系统:Inode&Directory&Path

文件系统:Inode&Directory&Path 本文继续来看 $xv6$ 文件系统部分,$xv6$ 将文件系统设计分为 7 层:$磁盘 \rightarrow 缓存区 \rightarrow 日志...这里重新再来看看 $xv6$ 文件系统布局: 引导块 第 0 块是引导块,里面存放启动程序也就是 $bootblock$,详见前面的启动 超级块 第 1 块是超级块,存有文件系统元信息,相关结构体定义如下...后面我们会看到如果文件类型为设备,则读写时候会根据 $major\ number$ 调用相应设备读写程序。 每个 $inode$ 有 11 个一级指针,一个间接指针,用来指向数据块。...当然并未真正地直接写到磁盘了,只是将该缓存数据标记为脏,关于日志,读写磁盘操作本文赘述了 回到分配 $dinode$ 函数上来,磁盘上 $dinode$ 已分配,得到了 $inode$ 号,但是文件系统实际工作时候使用是内存...} $skipelem$ 调用一次解析一个头部文件名放在 $name$ 返回剩下路径。

25710

MIT 6.S081 Lab Two -- 系统调用

本实验室,您将向xv6添加一些新系统调用,这将帮助您了解它们是如何工作,并使您了解xv6内核一些内部结构。您将在以后实验室添加更多系统调用。...如果在掩码设置了系统调用编号,则必须修改xv6内核,以便在每个系统调用即将返回时打印出一行。 该行应该包含进程id、系统调用名称和返回值; 您不需要打印系统调用参数。...从用户空间检索系统调用参数函数kernel/syscall.c,您可以kernel/sysproc.c中看到它们使用示例。...MakefileUPROGS添加$U/_trace 将系统调用原型添加到user/user.h头文件 2....(逻辑地址)对应物理地址 // 然后将 &sinfo 数据复制到该指针所指位置,供用户进程使用

41240
领券