MIT6S081-Lab2总结
大家好,我叫徐锦桐,个人博客地址为www.xujintong.com,github地址为https://github.com/xjintong。平时记录一下学习计算机过程中获取的知识,还有日常折腾的经验,欢迎大家访问。
Lab2就是了解一下xv6的系统调用流程,熟悉一下系统调用过程中的结构啥的。
一、xv6系统调用流程
(以tarce
系统调用为例)
1、在用户态的user.h
中加入对应加入对应系统调用的跳板函数
2、在user/usys.pl
中加入对应的entry()
这个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_traceecallret
通过上述代码可以看出来,entry
将对应系统调用的调用号(SYS_trace)加入到a7寄存器中,然后通过ecall
(risc-v汇编的系统调用指令)从用户态进入内核态。
3、之后首先会跳到kernel/syscall.c
中的syscall
函数。
系统调用号(SYS_trace–就是个宏定义)从a7寄存器中获取,然后通过这个号调用对应的系统调用函数,返回值存在a0寄存器中。
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
文件中。
二、将内核态数据复制到用户态
应为内核态和用户态是隔离的,它俩拥有不用的地址空间、寄存器。所以获取系统调用用户态传入的参数我们需要argint()
、argaddr
、argstr
进行获取。(这三个函数在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头文件中。
一些结构
kernel/proc.c
中定义了一个
struct proc proc[NPROC];
存着当前所有进程的proc结构。
每个进程都对应一个proc
结构,该结构存储着该进程的信息,运行状态,进程名字,pid号等等。
相关文章:

MIT6S081-Lab2总结
大家好,我叫徐锦桐,个人博客地址为www.xujintong.com,github地址为https://github.com/xjintong。平时记录一下学习计算机过程中获取的知识,还有日常折腾的经验,欢迎大家访问。 Lab2就是了解一下xv6的系统调用流程&…...

CMMI5大成熟度等级和4大过程域
CMMI(Capability Maturity Model Integration,能力成熟度模型集成)模型系列是帮助组织改进其过程的最佳实践的集合。这些模型由来自产业界、政府以及软件工程研究所(Software Engineering Institute, SEI)的…...

c++新经典模板与泛型编程:const修饰符的移除与增加
const修饰符的移除 让你来写移除const修饰符,你会怎么样来写? 😂😂trait类模板,如下 #include <iostream>// 泛化版本 template<typename T> struct RemoveConst {using type T; };// 特化版本 template…...

AUTOSAR汽车电子嵌入式编程精讲300篇-基于加密算法的车载CAN总线安全通信
目录 前言 研究现状 系统架构研究 异常检测研究 认证与加密研究 相关技术 2.1车联网 2.2车载网络及总线 2.2.1 CAN总线基础 2.2.2 CAN总线网络安全漏洞 2.2.3 CAN总线信息安全需求 2.3密码算法 2.3.1 AES算法 2.3.2 XTEA算法 CAN网络建模与仿真 3.1 CAN网络建模…...
4-Docker命令之docker start
1.docker start介绍 docker start命令是用来启动一个或多个已经被停止的docker容器。 2.docker start用法 docker start [参数] container [container......] [root@centos79 ~]# docker start --helpUsage: docker start [OPTIONS] CONTAINER [CONTAINER...]Start one or…...

AWS Remote Control ( Wi-Fi ) on i.MX RT1060 EVK - 2 “架构 AWS”
接续上一章节,我们把开发环境架设好之后,此章节叙述如何建立 AWS IoT 环境,请务必已经有 AWS Account,申请 AWS Account 之流程将不在此说明。 III-1. 登入AWS IoT, 在“管理”>“所有装置”>“实物”下点击“建…...

日志框架梳理(Log4j,Reload4j,JUL,JCL,SLF4J,Logback,Log4j2)
原文链接 日志框架发展历程 在了解日志框架时总会列出一系列框架:Log4j,Reload4j,JUL,JCL,SLF4J,Logback,Log4j2,这么多框架让人感到混乱,该怎么选取、该怎么用。接下来…...

内核无锁队列kfifo
文章目录 1、抛砖引玉2、内核无锁队列kfifo2.1 kfifo结构2.2 kfifo分配内存2.3 kfifo初始化2.4 kfifo释放2.5 kfifo入队列2.6 kfifo出队列2.7 kfifo的判空和判满2.8 关于内存屏障 1、抛砖引玉 昨天遇到这样一个问题,有多个生产者,多个消费者,…...

18、XSS——cookie安全
文章目录 1、cookie重要字段2、子域cookie机制3、路径cookie机制4、HttpOnly Cookie机制5、Secure Cookie机制6、本地cookie与内存cookie7、本地存储方式 一般来说,同域内浏览器中发出的任何一个请求都会带上cookie,无论请求什么资源,请求时&…...

从零开发短视频电商 Jmeter压测示例模板详解(无认证场景)
文章目录 添加线程组添加定时器添加HTTP请求默认值添加HTTP头管理添加HTTP请求添加结果断言响应断言 Response AssertionJSON断言 JSON Assertion持续时间断言 Duration Assertion 添加察看结果树添加聚合报告添加表格察看结果参考 以压测百度搜索为例 https://www.baidu.com/s…...
C++可以函数重载而C不可以的原因
函数重载是指在同一个作用域内,可以定义多个函数,它们具有相同的名称但是参数列表不同。函数重载的主要原理是函数的签名不同,而在 C 中,函数签名包括函数的名称和参数列表。而在 C 中,函数的标识仅依赖于函数的名称&a…...
Spark常见算子汇总
创建RDD 在Spark中创建RDD的方式分为三种: 从外部存储创建RDD从集合中创建RDD从其他RDD创建 textfile 调用SparkContext.textFile()方法,从外部存储中读取数据来创建 RDD parallelize 调用SparkContext 的 parallelize()方法,将一个存在的集合&…...

【华为数据之道学习笔记】3-1 基于数据特性的分类管理框架
华为根据数据特性及治理方法的不同对数据进行了分类定义:内部数据和外部数据、结构化数据和非结构化数据、元数据。其中,结构化数据又进一步划分为基础数据、主数据、事务数据、报告数据、观测数据和规则数据。 对上述数据分类的定义及特征描述。 分类维…...

电脑版便签软件怎么设置在桌面上显示?
对于不少上班族来说,如果想要在使用电脑办公的时候,随手记录一些常用的工作资料、工作注意事项等内容,直接在电脑上使用便签软件记录是比较方便的。电脑桌面便签工具不仅方便我们随时记录各类工作事项,而且支持我们快速便捷使用这…...

【华为数据之道学习笔记】2-建立企业级数据综合治理体系
数据作为一种新的生产要素,在企业构筑竞争优势的过程中起着重要作用,企业应将数据作为一种战略资产进行管理。数据从业务中产生,在IT系统中承载,要对数据进行有效治理,需要业务充分参与,IT系统确保遵从&…...
【IC前端虚拟项目】git和svn项目托管平台的简单使用说明
【IC前端虚拟项目】数据搬运指令处理模块前端实现虚拟项目说明-CSDN博客 代码托管在gitee平台上,进去后会看到文档目录“MVU芯片前端设计验证虚拟项目”和工程目录“mvu_prj”,可以通过git来下载工程: git clone gitgitee.com:gjm9999/ic_vi…...

C++ IO库
IO类 IO对象不能拷贝和赋值 iostream 表示形式的变化: 将100转换成二进制序列 然后格式化输出 x,y共用一块内存 输出的时候用不同的方式解析同一块内存 操作 格式化:内部表示转换为相应字节序列 缓存:要输出的内容放到缓存 编码转换&…...
Springboot 项目关于版本升级到 3.x ,JDK升级到17的相关问题
由于spring 停止对2.x 版本的维护,以及 jdk 频繁发布等客观因素,现需要对已有springboot 工程做一次全面升级;已因对市面上第三方等依赖库的兼容问题; 现有工程使用哥技术栈是版本: freemarker :2.3.32 spr…...

QGraphicsView实现简易地图7『异步加载-多瓦片-无底图』
前文链接:QGraphicsView实现简易地图6『异步加载-单瓦片-无底图』 前一篇文章提到的异步单瓦片加载,是指线程每准备好一个瓦片数据后,立刻抛出信号让主线程加载。而本篇异步多瓦片加载是指线程准备好所有瓦片数据后,一起抛出信号让…...
Spring Boot学习(三十三):集成kafka
前言 下面是zookeeper和kafka的官网下载地址,大家可以学习下载 zookeeper下载地址:http://zookeeper.apache.org/releases.html kafka下载地址:http://kafka.apache.org/downloads.html 1、添加依赖 在 pom.xml 文件中添加kafka依赖&am…...

TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...

vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...

关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...

FFmpeg avformat_open_input函数分析
函数内部的总体流程如下: avformat_open_input 精简后的代码如下: int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...