MIT6S081-Lab2总结

大家好,我叫徐锦桐,个人博客地址为www.xujintong.com,github地址为https://github.com/xjintong。平时记录一下学习计算机过程中获取的知识,还有日常折腾的经验,欢迎大家访问。

Lab2就是了解一下xv6的系统调用流程,熟悉一下系统调用过程中的结构啥的。

一、xv6系统调用流程

tarce系统调用为例

1、在用户态的user.h中加入对应加入对应系统调用的跳板函数

image-20231206141549969

2、在user/usys.pl中加入对应的entry()

image-20231206141753130

这个entry()是从用户态到内核态的一个关键,它的宏定义展开代码为:

entry的具体宏展开是:
sub entry {
    my $name = shift;
    print ".global $name\n";
    print "${name}:\n";
    print " li a7, SYS_${name}\n";
    print " ecall\n";
    print " ret\n";
}

# 经过compiler后, entry("trace")为我们在usys.S里生成了如下的汇编代码

# usys.S
.global trace
trace:
 li a7, SYS_trace
 ecall
 ret

通过上述代码可以看出来,entry将对应系统调用的调用号(SYS_trace)加入到a7寄存器中,然后通过ecall(risc-v汇编的系统调用指令)从用户态进入内核态。

3、之后首先会跳到kernel/syscall.c中的syscall函数。

系统调用号(SYS_trace–就是个宏定义)从a7寄存器中获取,然后通过这个号调用对应的系统调用函数,返回值存在a0寄存器中。

image-20231206142355776

4、通过系统调用号找到对应的系统调用函数

static uint64 (*syscalls[])(void) = {
[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,
[SYS_sysinfo] sys_sysinfo,
};

其实就是个数组,每个数组存着对应的系统调用函数指针。像SYS_fork、SYS_exit这些,其实就是一个宏定义,定义的编号,具体源码如下:

// System call numbers
#define SYS_fork    1
#define SYS_exit    2
#define SYS_wait    3
#define SYS_pipe    4
#define SYS_read    5
#define SYS_kill    6
#define SYS_exec    7
#define SYS_fstat   8
#define SYS_chdir   9
#define SYS_dup    10
#define SYS_getpid 11
#define SYS_sbrk   12
#define SYS_sleep  13
#define SYS_uptime 14
#define SYS_open   15
#define SYS_write  16
#define SYS_mknod  17
#define SYS_unlink 18
#define SYS_link   19
#define SYS_mkdir  20
#define SYS_close  21
#define SYS_trace  22
#define SYS_sysinfo 23

具体的系统调用的函数实现放在了各个文件中,这里是个extern函数。

比如说,sys_trace放在kernel/sysproc.c文件中,sys_read放在kernel/sysfile.c文件中。

image-20231206143328256

二、将内核态数据复制到用户态

应为内核态和用户态是隔离的,它俩拥有不用的地址空间、寄存器。所以获取系统调用用户态传入的参数我们需要argint()argaddrargstr进行获取。(这三个函数在kernel/syscall.c文件中)

将内核态的数据返回到用户态,这里是用到了copyout函数。具体源码如下:

// Copy from kernel to user.
// Copy len bytes from src to virtual address dstva in a given page table.
// Return 0 on success, -1 on error.
/*
 将 len 个字节从 src 复制到给定页表中的虚拟地址 dstva
*/
int
copyout(pagetable_t pagetable, uint64 dstva, char *src, uint64 len)
{
  uint64 n, va0, pa0;

  while(len > 0){
    va0 = PGROUNDDOWN(dstva);   // 找到虚拟地址对应的虚拟页表起始地址
    pa0 = walkaddr(pagetable, va0);   // 通过虚拟页表找到对应的物理页表起始地址
    if(pa0 == 0)
      return -1;
    n = PGSIZE - (dstva - va0);   // 计算该页表的剩余空间
    // 如果剩余空间大于要拷贝的数据长度,只拷贝数据长度部分
    if(n > len)
      n = len;
    /*
      在物理页表中,以(void *)(pa0 + (dstva - va0))地址开始,将n个字节的src,复制到对应位置
    */
    memmove((void *)(pa0 + (dstva - va0)), src, n); 

    len -= n;
    src += n;
    dstva = va0 + PGSIZE;
  }
  return 0;
}

核心就是通过虚拟地址找到对应变量的物理地址,然后直接复制到的物理地址上面。

流程:

  • 1、找到虚拟地址对应的虚拟页表起始地址。

  • 2、通过虚拟页表找到对应的物理页表起始地址

  • 3、如果剩余空间大于要拷贝的数据长度,只拷贝数据长度部分

  • 4、在物理页表中,以(void *)(pa0 + (dstva - va0))地址开始,将n个字节的src,复制到对应位置

三、杂

内核态的头文件

内核态的函数声明都在kernel/defs.h头文件中。

image-20231206143652669

一些结构

kernel/proc.c中定义了一个

struct proc proc[NPROC];

存着当前所有进程的proc结构。

image-20231206150341027

每个进程都对应一个proc结构,该结构存储着该进程的信息,运行状态,进程名字,pid号等等。

image-20231206150507722

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/224545.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python 进阶(十三):JSON 序列化和反序列化(json 模块)

大家好,我是水滴~~ 本篇文章主要介绍json模块的功能,包括将Python对象序列化到文件、将Python对象序列化为字符串、序列化时类型的对照表、将文件中JSON数据反序列化为Python对象,将JSON字符串反序列化为Python对象、反序列化时类型的对照表…

Kafka使用指南

Kafka简介架构设计Kafka的架构设计关键概念Kafka的架构设计关键机制 Partition介绍Partition工作机制 应用场景ACK机制介绍ACK机制原理ACK机制对性能的影响ACK控制粒度Kafka分区数对集群性能影响调整分区优化集群性能拓展Kafka数据全局有序 Kafka简介 Kafka是由Apache软件基金…

Spring Boot学习随笔-SpringBoot的引言,回顾传统SSM开发

学习视频:【编程不良人】2021年SpringBoot最新最全教程 第一章、传统SSM开发回顾以及问题 Spring SpringMVC Mybatis SSM 实现一个简单功能 员工添加、查询… SSM项目简单实现 项目 需求分析 —>概要设计 —>(库表设计) —> 详细…

Linux进程解析(冯诺依曼体系结构,操作系统,进程初步解析)

冯诺依曼体系结构: 我们常见的计算机,如笔记本。我们常见的计算机,服务器,大部分都遵守冯诺依曼体系。 截至目前,我们所认识的计算机,都是有一个个的硬件组件组成: 中央处理器(CPU)&am…

MIT6.5840-2023-Lab1: MapReduce

前置知识 MapReduce:Master 将一个 Map 任务或 Reduce 任务分配给一个空闲的 worker。 Map阶段:被分配了 map 任务的 worker 程序读取相关的输入数据片段,生成并输出中间 k/v 对,并缓存在内存中。 Reduce阶段:所有 ma…

Linux socket编程(12):Unix套接字之socketpair、sendmsg和recvmsg详解

在上一篇文章Unix套接字编程及通信例子中,我们对Unix套接字编程有一个基本的了解。但在Unix套接字编程的领域中,有一组特殊而强大的工具:socketpair、sendmsg 和 recvmsg,它们为实现本地进程间通信提供了便捷的方式。 文章目录 1 …

python二维数组创建赋值问题:更改单个值却更改了所有项的值

test_list [] dic1 {} test_list [dic1 for _ in range(3)] ll [1, 2, 3]for i in range(3):test_list[i][value] ll[i]print(test_list)运行结果:每次赋值都更改了所有项 原因:python的二位数据创建方式就是这样,官方文档中有描述Wha…

大话数据结构-查找-线性索引查找

注:本文同步发布于稀土掘金。 4 线性索引查找 4.1 概述 索引就是把一个关键字与它对应的记录相关联的过程,一个索引由若干个索引项构成,每个索引项至少应包含关键字和其对应的记录在存储器中的位置等信息。 索引按照结构可分为线性索引、树…

【SpringBoot】在SpringBoot中配置序列化的Redis

文章目录 前言展示包结构在SpringBoot中配置Redis测试总结 前言 在使用Java操作Redis时,如果不对Redis进行序列化操作,可能会导致存储的key和value与原来的数据不一致的问题 本文也借此机会来详细讲解一下SpringBoot中配置序列化Redis的步骤 展示包结构 …

AI助力智慧农业,基于YOLOv7【tiny/yolov7/yolov7x】开发构建不同参数量级农田场景下庄稼作物、杂草智能检测识别系统

智慧农业随着数字化信息化浪潮的演变有了新的定义,在前面的系列博文中,我们从一些现实世界里面的所见所想所感进行了很多对应的实践,感兴趣的话可以自行移步阅读即可: 《自建数据集,基于YOLOv7开发构建农田场景下杂草…

绘图 Seaborn 10个示例

绘图 Seaborn 是什么安装使用显示中文及负号散点图箱线图小提琴图堆叠柱状图分面绘图分类散点图热力图成对关系图线图直方图 是什么 Seaborn 是一个Python数据可视化库,它基于Matplotlib。Seaborn提供了高级的绘图接口,可以用来绘制各种统计图形&#xf…

nodejs+vue+微信小程序+python+PHP新闻发布系统的设计与实现-计算机毕业设计推荐

根据现实需要,此系统我们设计出一下功能,主要有以下功能模板。 (1)新闻发布系统前台:首页、时事新闻、公告资讯、个人中心。 (2)管理员功能:首页、个人中心、用户管理、新闻分类管理…

文本编辑软件:Ulysses mac介绍说明

Ulysses mac是面向 Mac、iPhone 和 iPad 的一站式写作环境。Ulysses 提供令人愉悦、专注的写作体验,加上高效文稿管理、无缝同步以及灵活导出。markdown 可以直接对于文本进行不同类型的分类、编辑,比如标题、注解、评论之类的内容。 Ulysses让注意力专…

rpm安装gitlab

1.rpm包下载 https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/ 2.进行安装 rpm -ivh gitlab-ce-15.9.7-ce.0.el7.x86_64.rpm --nodeps --force 3.配置访问地址 vim /etc/gitlab/gitlab.rb 4.重新加载配置以及重启服务 gitlab-ctl reconfiguregitlab-ctl resta…

Ubuntur编译ROS报错:error PCL requires C++14 or above

ubuntu20.04 编译ROS包 报错: error: PCL requires C14 or above: 修改Cmakelists.txt文件: set(CMAKE_CXX_STANDARD 14) 再次编译成功.

2023 IoTDB 用户大会成功举办,深入洞察工业互联网数据价值

2023 年 12 月 3 日,中国通信学会作为指导单位,Apache IoTDB Community、清华大学软件学院、中国通信学会开源技术委员会联合主办,“科创中国”开源产业科技服务团和天谋科技(北京)有限公司承办的 2023 IoTDB 用户大会…

AI 绘画 | Stable Diffusion 动漫人物真人化

前言 如何让一张动漫人物变成真实系列人物?Stable Diffusion WebUI五步即可实现。快来使用AI绘画打开异世界的大门吧!!! 动漫真人化 首先在图生图里上传一张二次元动漫人物图片,然后选择一个真实系人物画风的大模型,最后点击DeepBooru 反推,自动填充提示词,调整重绘…

【MySQL】:数据库基本认识

数据库基础 一.什么是数据库1.mysql是什么2.为什么要有数据库3.服务器,数据库,表关系4.Mysql架构5.SQL语句分类 二.存储引擎 一.什么是数据库 1.mysql是什么 1.mysql是数据库服务的客户端。 2.mysqld是数据库服务的服务器端。 3.mysql本质:基…

【Python】logging模块函数详解和示例

在Python中,LOGGER通常是指一个用于记录日志的模块或对象。它可以帮助你在程序中跟踪和记录事件,以便于调试、错误跟踪和日志分析。Python的标准库中包含了一个名为logging的模块,它提供了一个灵活且功能强大的日志记录系统。本文对相应的函数…

unity 2d 入门 飞翔小鸟 下坠功能且碰到地面要停止 刚体 胶囊碰撞器 (四)

1、实现对象要受重力 在对应的图层添加刚体 改成持续 2、设置胶囊碰撞器并设置水平方向 3、地面添加盒状碰撞器 运行则能看到小鸟下坠并落到地面上