ucore扩展练习

扩展proj4,增加syscall功能,即增加一用户态函数(可执行一特定的系统调用:获得始终计数值),当内核初始化完毕后,可从内核态返回到用户态的函数,而用户态的函数用通过系统调用得到内核态的服务

  • 在操作系统中,内核态对应的是ring0,而用户态对应的是ring3,ring0和ring3指的是当前代码运行的特权等级。这个特权登记由cs中的标识特权级的几位进行声明。在访问数据段是,数据段的特权级(DPL)必须大于等于代码段的特权级(CPL)。

由于要求通过中断实现用户态到内核态的转变,需要知道T_SWITCH_TOU以及T_SWITCH_TOK的中断号。在trap,h中存在定义

#define T_SWITCH_TOU
#define T_SWITCH_TOK

查看中断处理函数入口vector.S,可以看到中断处理函数为trapentry.S中的_alltraps函数,而__alltraps就是将各种寄存器压栈保存,然后调用trap.c中的trap函数,最后恢复各寄存器并返回,在trap.h中可发现压栈保存的数据结构

struct pushregs {
    uint32_t reg_edi;
    uint32_t reg_esi;
    uint32_t reg_ebp;
    uint32_t reg_oesp;            
    uint32_t reg_ebx;
    uint32_t reg_edx;
    uint32_t reg_ecx;
    uint32_t reg_eax;
};

由上述可知从内核态切换到用户态只能通过iret指令修改cs的值。也就是修改之前压入栈中的值,iret指令将栈中的值弹出时修改cs的值。同时为了之后的访问不出问题,需要将ds,es,ss中的特权级一并修改,并且要修改i/o特权级。

下述使用内联汇编。在调用中断之前需要先修改esp,因为当切换优先级时,iret指令会额外弹出ss和esp,但调用中断时并不会产生特权级的切换,因此不用压入ss和esp。需要预先留出空间防止代码出错。从用户,态切换到内核态时,由于用户态调用中断时本来就自动切换到内核态,因此不会产生上述的问题,无需额外压入ss和esp
在这里插入图片描述

对于中断内部的处理代码需要对trap.c中的trap_dispatch的switch里面增加部分代码用于返回ticks。

trap_dispatch的switch代码如下:

在这里插入图片描述

在lab1中使用make qemu运行结果如下:

在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值