2021 XV6 4:traps

news/2024/11/30 0:40:09/

目录

1.RISC-V assenbly

2.Backtrace

 3.Alarm


1.RISC-V assenbly

第一个任务是阅读理解,一共有6个问题。

1.Which registers contain arguments to functions? For example, which register holds 13 in main's call to printf?

具体来说就是a0,a1几个寄存器存了相应的系统调用参数,a7存的是系统调用号。

2.Where is the call to function f in the assembly code for main? Where is the call to g? (Hint: the compiler may inline functions.)

 这个好像汇编代码直接内联了。

3.At what address is the function printf located?

 这里很明显了,跳到的地址是1552+ra=1552+0x30=0x640

4.What value is in the register ra just after the jalr to printf in main?

 

 这个auipc噢,用那个跳转的16进制地址减去1552就可以算出来,实际上就是存的0x097当前的地址,这个auipc就是把当前pc和后面那个立即数的低12位取0相加得到的。

jalr会在跳转之后把ra加8,也就是ra+8=0x38,即下一条返回执行的地址。

5.Run the following code.

	unsigned int i = 0x00646c72;printf("H%x Wo%s", 57616, &i);

What is the output? Here's an ASCII table that maps bytes to characters.

The output depends on that fact that the RISC-V is little-endian. If the RISC-V were instead big-endian what would you set i to in order to yield the same output? Would you need to change 57616 to a different value?

这考察大端小端的问题,第一个就是10进制转8进制,第二个是小端的输出,输出726c64

6.In the following code, what is going to be printed after 'y='? (note: the answer is not a specific value.) Why does this happen?

	printf("x=%d y=%d", 3);

这里输出的就是寄存器a1里边的值,是什么值就是啥。

2.Backtrace

实现一个系统调用,用来打印调用的栈的系统信息的。据说对debug有用,虽然我还没想到哪里可以用。

首先我们得熟悉一下系统里边调用的层次结构:

 我们来看一下这张图,从上往下看,高地址在高位,但是栈是向低地址增长的。首先呢是存个return address,也就是返回执行的地址,然后存的就是prev frame辣,这就是我们要打印的东西,xv6还提示我们可以用一条内联汇编去取出当前的栈帧指针,这个指针是指向那个return address的上一个位置的,意味着我们可以用-8,-16取到返回地址以及上一个栈帧的指针,那么我们写个循环就好了对吧。

那么循环条件是什么?我们在给一个程序分配栈时,按照页为单位,其中每个页面之间有个保护页面。

Xv6 allocates one page for each stack in the xv6 kernel at PAGE-aligned address.

意思就是我们的栈桢指针应该是指向一个页的顶部的,所以当他不等于的时候就是循环结束的条件。

void
backtrace(void)
{printf("backtrace:\n");// fp保存当前栈帧指针uint64 fp=r_fp();while(fp!=PGROUNDUP(fp)){uint64 ret_addr=*(uint64 *)(fp-8);printf("%p\n", ret_addr);fp=*(uint64 *)(fp-16);}
}

最后在sys_sleep里边backtrace一下就行了,当然,系统调用号以及入口一些细节按照xv6里边来就行了。

执行bttest如下所示:

 3.Alarm

这里的任务就是加个系统调用来处理信号。这个信号处理流程大概是这样的:

sigalarm(time,handler),设置每隔time的ticks执行handler,这个handler是用户态的函数,在函数末尾我们要用sigreturn返回。

其实这里有个东西我想了挺久的,如果说在进入trap之前已经存下来了所有寄存器的话,为什么还要用sigreturn处理用户的返回呢?这个其实是因为,首先啊,在time到的时候,我们为了要返回用户态执行handler,我们要设置返回的trapframe是handler的地址,然后呢,如果没有sigreturn会怎么样?trap返回然后恢复寄存器,handler继续执行,然后返回到原来中断的函数里边执行,那么,原来的context其实可能已经打乱了,所以,我们得用一个sigreturn来恢复sigalarm之前的上下文。

具体思路及步骤如下所示:

1.首先还是处理系统调用号以及一些入口

2.在sysproc.c里边写这两个函数:

uint64
sys_sigalarm(void)
{int ticks=0;uint64 handler=0;struct proc *p=myproc();if (argint(0, &ticks)<0){return -1;}if (argaddr(1, &handler)<0){return -1;}p->ticks=ticks;p->has_return=1;p->pass_ticks=0;p->handler=(void (*)())handler;// printf("In sys_sigalarm pass_ticks:%d   ticks:%d    epc:%p\n",p->pass_ticks,p->ticks,p->trapframe->epc);return 0;
}uint64
sys_sigreturn(void)
{struct proc *p=myproc();memmove(p->trapframe,p->signal_trapframe,sizeof(struct trapframe));p->pass_ticks=0;p->has_return=1;// printf("In sys_sigreturn pass_ticks:%d   ticks:%d   epc:%p\n",p->pass_ticks,p->ticks,p->trapframe->epc);return 0;
}

sigalarm接收时间戳和handler两个参数,并且添加到进程的数据结构里面。

sigreturn重新设置时间戳,并且标记目前正在执行handler,试着想一下,如果一个handler要执行很久,那么我们在handler里面又会handler,这是我们不期望的,也就是说,当执行handler时,就一直执行完而屏蔽sigalarm设置的handler。

3.在trap.c里边修改如下:

  // give up the CPU if this is a timer interrupt.if(which_dev == 2){// printf("In trap pass_ticks:%d   ticks:%d    epc:%p\n",p->pass_ticks,p->ticks,p->trapframe->epc);if (p->ticks==0){yield();usertrapret();}else{int pass_ticks=p->pass_ticks+1;if (pass_ticks>=p->ticks&&p->has_return==1){// 记录时钟中断前上下文p->signal_trapframe=(struct trapframe*)kalloc();memmove(p->signal_trapframe,p->trapframe,sizeof(struct trapframe));// 调整返回执行地址p->trapframe->epc=(uint64)p->handler;p->has_return=0;}else{p->pass_ticks=pass_ticks;}}yield();}

 这里的逻辑就是应该已经很清晰了~

执行alarmtest如下所示:

这个实验通过backtrace以及一些信号系统调用让我们理解了系统调用的流程以及一些汇编指令的作用,当然,收获最大的是这个信号处理流程。

 


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

相关文章

中国再领跑:成功发射全球首颗6G试验卫星?

中国6G加速布局 在全球5G网络建设逐步走上正轨后&#xff0c;全球多国开始提前押注6G技术。10月19日消息指出&#xff0c;美国科技巨头高通、微软等已经拉上知名5G巨头诺基亚、三星组建6G联盟&#xff0c;意图在下下一代通信技术中&#xff0c;主导技术标准。然而&#xff0c;这…

国内星载光学卫星详解

1.资源一号02C卫星 资源一号02C星(ZY1-02C)于2011年12月22日成功发射&#xff0c;牵头主用户为自然资源部。ZY1-02C星搭载有全色多光谱相机和全色高分辨率相机&#xff0c;主要任务是获取全色和多光谱图像数据&#xff0c;可广泛应用于自然资源调查与监测、防灾减灾、农林水利…

HG 新闻 RS5 环境点

前言&#xff1a;海guan局的RS5代 环境检测点相对于药监J 要多了不少 本文主要是说下海guan局新闻页的RS5检测环境 网址 base64: aHR0cDovL3d3dy5jdXN0b21zLmdvdi5jbi9jdXN0b21zL3h3ZmIzNC8zMDI0MjUvaW5kZXguaHRtbA 本文说下重点的地方 一、window下的一些函数检测 挂上w…

高分6号宽幅(GF6-WFV)卫星数据快速批量处理

李国春 2021 10 11 GF6-WFV是共享免费数据&#xff0c;应用广泛。其数据规模比较大&#xff0c;处理时间比较长。RSD的框架机制可以正射处理指定范围内的部分GF6-WFV数据&#xff0c;不需要处理整个数据集&#xff0c;因此可以减少处理时间。同时&#xff0c;RSD可以对GF6-WFV…

证照之星2023全新XE版本功能

吧证照之星是国内顶级的证件照片制作软件&#xff0c;具有一键裁剪&#xff0c; 智能背景替换&#xff0c;批量制作、内置证照规格的四大优势。同时两大独创技术&#xff1a;智能去除皮肤油光、证照服装替换。同时支持联机拍摄&#xff1a;支持网络摄像头及可联机拍摄的相机。本…

小谈Intel SGX

目录 Intel SGX简介 背景 为什么要Intel SGX&#xff1f; Intel SGX尚处于学术讨论 Intel SGX和可信启动什么关系&#xff1f; 开发者眼中SGX长什么样子&#xff1f; SGX访问控制是什么&#xff1f; MEE与SGX EPC内存加密 CPU里面SGX长什么样子&#xff1f; 有Enclav…

SGX Enable

根据INTEl的官方建议&#xff0c; 目前的电脑主板在BIOS设置上只保留了Disabled和Software Controlled来开启和关闭SGX扩展 使用Software Controlled开关的原因官方文档有阐述&#xff0c;如下&#xff1a; 开启SGX扩展&#xff0c;首先需要满足以下要求&#xff1a; CPU具有…

SpringBoot + Vue前后端分离项目实战 || 二:Spring Boot后端与数据库连接

系列文章&#xff1a; SpringBoot Vue前后端分离项目实战 || 一&#xff1a;Vue前端设计 文章目录 新建Spring后台项目添加依赖 新建数据库IDEA 连接数据库IDEA 自动创建类实体定义数据传递至前端的格式 B站视频讲解&#xff1a;2023全网最简单但实用的SpringBootVue前后端分离…