MIT 6.S081 lab学习记录

news/2024/11/23 9:52:08/

lab0

Google 翻译
第零章 操作系统接口 | xv6 中文文档 (gitbooks.io)
6.1810 / Fall 2022 (mit.edu)

sleep(easy)

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"int main(int argc, char *argv[]){if(argc <= 2) sleep(atoi(argv[1]));
return 0;
}

pingpong (easy)

pipe与dup的讲解:
(209条消息) xv6中pipe&dup_xv6 dup函数的含义_G129558的博客-CSDN博客

pipe: 创建一个通道使得两个进程能够进行通信
dup:复制一个稳健描述符,文件描述符的生成以最小数开始

#include "kernel/types.h"
#include "user/user.h"int main(int argc, char *argv[]) {int parent_fd[2], child_fd[2];pipe(parent_fd);pipe(child_fd);char buf[64];if (fork()) {// Parentclose(child_fd[1]);write(parent_fd[1], "ping", strlen("ping"));read(child_fd[0], buf, 4);printf("%d: received %s\n", getpid(), buf);close(parent_fd[1]);close(parent_fd[0]);close(child_fd[0]);} else {// Childclose(parent_fd[1]);read(parent_fd[0], buf, 4);printf("%d: received %s\n", getpid(), buf);write(child_fd[1], "pong", strlen("pong"));close(child_fd[1]);close(child_fd[0]);}exit(0);
}

lab1

Using gdb

在第一个terminal调用 make qemu-gdb
在另一个terminal执行 gdb-multiarch

通过gdb实现寄存器的查看
p /x $sstatusbacktrace 回看栈中的数据b *0x000000008000215a 对具体的地址进行打断点

System call tracing

思路:增加一个系统调用sys_trace,此时我们需要在所有的进程中添加一个mask变量来记录我们需要跟踪的指令,随后在syscall中打印出来

/user/usys.pl :perl脚本 实现对系统调用的汇编语言的生成
在其中添加

entry("trace");

/user/user.h : 系统调用以及用户常见的函数的定义

int trace(int);

/kernel/proc.h 进程相关的结构体函数的定义

struct proc {struct spinlock lock;// p->lock must be held when using these:enum procstate state;        // Process statevoid *chan;                  // If non-zero, sleeping on chanint killed;                  // If non-zero, have been killedint xstate;                  // Exit status to be returned to parent's waitint pid;                     // Process ID**int mask;**                // 添加一个 mask 用来进行记录// wait_lock must be held when using this:struct proc *parent;         // Parent process// these are private to the process, so p->lock need not be held.uint64 kstack;               // Virtual address of kernel stackuint64 sz;                   // Size of process memory (bytes)pagetable_t pagetable;       // User page tablestruct trapframe *trapframe; // data page for trampoline.Sstruct context context;      // swtch() here to run processstruct file *ofile[NOFILE];  // Open filesstruct inode *cwd;           // Current directorychar name[16];               // Process name (debugging)
};

/kernel/proc.c 进程相关函数实现
在fork()系统调用中实现mask的赋值

  // copy mask for tracenp->mask = p->mask;

kernel/syscall.c 系统调用函数实现
添加一个表

static const char*syscall_names[]={
[SYS_fork]    "sys_fork",
[SYS_exit]    "sys_exit",
[SYS_wait]    "sys_wait",
[SYS_pipe]    "sys_pipe",
[SYS_read]    "sys_read",
[SYS_kill]    "sys_kill",
[SYS_exec]    "sys_exec",
[SYS_fstat]   "sys_fstat",
[SYS_chdir]   "sys_chdir",
[SYS_dup]     "sys_dup",
[SYS_getpid]  "sys_getpid",
[SYS_sbrk]    "sys_sbrk",
[SYS_sleep]   "sys_sleep",
[SYS_uptime]  "sys_uptime",
[SYS_open]    "sys_open",
[SYS_write]   "sys_write",
[SYS_mknod]   "sys_mknod",
[SYS_unlink]  "sys_unlink",
[SYS_link]    "sys_link",
[SYS_mkdir]   "sys_mkdir",
[SYS_close]   "sys_close",
[SYS_trace]   "sys_trace"
};

添加判断命令

void
syscall(void)
{int num;struct proc *p = myproc();num = p->trapframe->a7;if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {// Use num to lookup the system call function for num, call it,// and store its return value in p->trapframe->a0p->trapframe->a0 = syscalls[num]();// printf("%s -> %d\n", )if(p->mask & (1 << num)){printf("%d: syscall %s -> %d\n", p->pid, syscall_names[num], p->trapframe->a0);}} else {printf("%d %s: unknown sys call %d\n",p->pid, p->name, num);p->trapframe->a0 = -1;}
}

/kernel/sysproc 系统调用实现
添加trace命令

uint64 sys_trace(void){int mask;struct proc *now_proc = myproc();argint(0, &mask);now_proc -> mask = mask;return 0;
}

在进行系统调用函数的使用时,所有的参数会依次存入到寄存器 a0 a1 a2 a3 a4 a5

Sysinfo

实现Sysinfo的系统调用

步骤:
step1:/user/usys.pl中添加

entry("sysinfo")

step2: /user/user.h中添加

struct sysinfo;

step3: 在sysproc中添加sys_sysinfo

uint64 sys_sysinfo(void){uint64 addr;argaddr(0, &addr);struct sysinfo info;info.freemem = get_freemem();info.nproc = get_freeproc();struct proc *p = myproc();if(copyout(p->pagetable, addr, (char *)&info, sizeof(info)) < 0)return -1;return 0;
}

在上述代码中为什么使用argaddr?

void
argaddr(int n, uint64 *ip)
{*ip = argraw(n);
}

因为地址是无符号型

为什么使用copyout?
copyout能够Copy from kernel to user

step4: /kernel/kalloc.v
freelist表示一个空闲页表链,每一个空闲页表的大小为4096byte

int get_freemem(){struct run *p;int freemem = 0;acquire(&kmem.lock);p = kmem.freelist;while(p){if(p) freemem += PGSIZE;p = p -> next;}release(&kmem.lock);return freemem;
}

为什么要加锁?
为了能够节约CPU资源
防止内存访问出现问题

step 5: /kernel/proc.c
进程中维护了一个进程表,把进程表中没有利用使用的进程记录下来即可

int get_freeproc(){struct proc *p;int free_num = 0;for(p = proc; p < &proc[NPROC]; p++) {if(p->state != UNUSED){free_num += 1;}}return free_num;
}

MIT课程

Lecture 3 - OS Organization and System Calls_哔哩哔哩_bilibili
操作系统的结构:
隔离性 内核/用户模式 系统调用
操作系统与应用之间不会出现很大的隔离
例如在使用fork()系统调用时,会出现对CPU进行分配任务,这种抽象实际上就是避免用户直接对CPU进行操作从而实现隔离
通过时间复用从而实现不同进程的使用
内存读写在linux中都是通过文件进行映射的,然后操作系统自己对内存进行映射

操作系统必须具有防守性 防御性编程
应用不能够对OS进行影响

用户内核模式 与 虚拟内存 能够为防御性编做工作

用户内核模式:用户模式 内核模式 机器模式
在内核模式CPU能够执行特权指令 : 直接对硬件进行操作 设置时间中断 对页表的处理
在用户模式CPU只能够实现非特权指令

存在一个寄存器能够实现对特权级别的更改

每个进程维护自己的页表,页表定义了内存的布局 将所有的进程与用户进行隔离
每一个进程在不同的页表中维护,从而实现了不同的程序可能起始地址都是0 不能够存在内存的相互访问
fork() 调用 ecall 给定系统调用标号 从而实现对应的功能

宏内核设计与微内核设计 区别在于是否在内核段存放大量的代码
![[截图_20230709095928.png]]
微内核实际上需要在内核态与用户态中不断地切换从而实现功能
微内核的性能如何提升,大多是宏内核的


http://www.ppmy.cn/news/804716.html

相关文章

如何实现音视频同步 (live555)

live555中视频和音频是分别进行编码的&#xff0c;如何实现两者的同步呢? 如果可以做到让视频和音频的时间戳&#xff0c;都与NTP时间保持同步&#xff0c;就可达到音视频同步的目的。 Network Time Protocol (NTP) is a networking protocol for clock synchronizationbetwee…

音视频的同步原理

1. 音视频同步的原理 2. 音视频同步的较正方法 3. 音视频同步时遇到的问题 声明&#xff1a;以下所有内容均为转载 1.原文转自&#xff1a;http://bbs.chinavideo.org/viewthread.php?tid1183&extrapage%3D1%26amp%3Bfilter%3Ddigest&page1 下面贴出部分&#xff…

VLC LIVE555音视频同步学习

&#xff11;&#xff0c;音频知识&#xff1a; 采样频率是指将模拟声音波形进行数字化时&#xff0c;每秒钟抽取声波幅度样本的次数。 。正常人听觉的频率范围大约在20Hz~20kHz之间&#xff0c;根据奈奎斯特采样理论&#xff0c;为了保证声音不失真&#xff0c;采样频率应该在…

FFMPEG音视频同步-音视频实时采集并编码推流-优化版本

FFMPEG音视频同步-音视频实时采集并编码推流-优化版本 //------------------------------------------------------------------------------------------------- 参考链接1、https://blog.csdn.net/leixiaohua1020/article/details/39702113 参考链接2、https://blog.csdn.ne…

ffmpeg音视频同步

先讲一个概念&#xff1a; pts &#xff1a;音视频显示时间。 dts&#xff1a;音视频解码时间。 time_base: 时间刻度单位&#xff0c;时间基。例如视频播放30fps&#xff0c;表示1秒钟播放30张图片&#xff0c;视频的时间基time_base等于{1&#xff0c;30}&#xff1b;如果…

音视频同步技术

1.什么是音视频同步? 音视频同步顾名思义就是视频画面与音频能够对应起来,尤其是对于视频画面中能看到声源动作(如:嘴型)的场景,音视频同步问题非常影响体验。 在视频源采集端作为音视频的生产者,如果采集端产生的音视频源本身就无法保证同步,那么后面不管经过什么处理…

SRT视频字幕的解析与同步

转自&#xff1a;http://www.eoeandroid.com/thread-171556-1-1.html 在论坛搜索srt字幕的解析&#xff0c;没有资源&#xff0c;于是自己琢磨&#xff0c;有点结果&#xff0c;与大家分享。 srt字幕文件的格式是&#xff1a; 1 00:00:02,580 --> 00:00:05,980 This is fro…

各大视频平台怎么一键同步?

现如今许多朋友都在自己运行官方帐户&#xff0c;但他们没有太多时间和精力在其他平台上推送内容。所以他们这时多会借助辅助工具来帮助自己&#xff0c;这些工具可以通过单击将您在官方帐户上撰写的文章同步推送到10多个其他平台。不仅可以同步短视频&#xff0c;还有图文&…