终于又回来了。内核态和用户态切换比较麻烦,今天解决了一个bug,搞定了从内核态切换到用户态。
x86中,从高优先级代码切换到低优先级代码的唯一方法就是使用ret或iret返回指令,而从低优先级切换到高优先级的方法是int或call调用指令。这几个指令在跨优先级过程中,都会进行堆栈切换。而切换的目的堆栈,对于int/call指令,是记录在当前task的tss段中,对于ret/iret指令,是记录在当前堆栈返回指令的底下。
先说明本次用的从内核态切换到用户态的处理方式。
本次是使用中断处理程序的iret指令完成内核态到用户态的切换。首先在内核态(cpl=0)执行int中断指令,因同样在内核态,不会造成堆栈切换,所以当前堆栈返回指令的底下也不会有切换堆栈的地址。为此构造一个新的trapframe结构,将trap_c函数的参数tf所指向的trapframe拷贝到新的trapframe,同时给其中的esp、ss赋值,esp的值就是正常返回后的地址,而ss的值是用户态段选择子(实际上和内核态空间完全重合,只不过优先级不同)。之后将新的trapframe的地址赋值给trap_c函数的参数tf:
temptf_k2u = *tf;
temptf_k2u.esp = (unsigned int)tf + sizeof(struct trapframe) - 8;
temptf_k2u.ss = SS_UDATA;
temptf_k2u.cs = SS_UTEXT;
temptf_k2u.ds = SS_UDATA;
temptf_k2u.es = SS_UDATA;
temptf_k2u.fs = SS_UDATA;
temptf_k2u.gs = SS_UDATA;
tf = &temptf_k2u;
其中最后一句是重点。在C语言中,一般来说,函数的参数实际上就是函数的局部变量,在函数返回后被直接丢弃,所以给函数的参数赋值没有任何意义。实际上函数的参数和局部变量都放在堆栈中,其中函数参数在调用函数返回地址的下面,而函数的局部变量在调用函数返回地址的上面,所以执行完成ret后,栈指针esp是指向第一个参数的,一般来说都是直接将esp加上某个值,从而直接将所有参数丢弃,所以造成参数被直接丢弃的后果。
而在trap_asm中,并没有直接把参数丢弃,而是把参数值赋值给了esp(通过popl %esp指令),这样,参数实际上即作为trap_c函数的输入值,有作为trap_c函数的输出值来使用:
.globl trap_asm
trap_asm:
pushl %gs
pushl %fs
pushl %es
pushl %ds
pushal
pushl %esp
call trap_c /* trap_c(taskframe *tf) */
popl %esp
popal
popl %ds
popl %es
popl %fs
popl %gs
addl $8, %esp /* remove trap number and error code */
iret
其中第九行 pushl %esp将当前的esp压入堆栈,作为参数tf,调用trap_c完成后,第11行popl %esp将tf参数再次弹出来,作为esp的值。而在trap_c中,因为已经给tf赋了一个新值&temptf_k2u,所以后续的pop操作实际上都是在temptf_k2u上做的。从而后续一系列pop和iret,就完成了优先级从kernel到user态的切换。
分享到:
相关推荐
Root project 'Almost-Famous' +--- Project ':famous-cloud' +--- Project ':famous-config' \--- Project ':famous-unique' +--- Project ':famous-common' +--- Project ':famous-login' +--- Project ':famous-...
Version : 5.7 Vendor : Fedora Project Release : 2.20090207.fc11 Date : 2009-02-26 09:37:30 Group : Development/Libraries Source RPM : ncurses-5.7-2.20090207.fc11.src.rpm Size : 1.71 MB Packager :...
Java-EE-Project1:Java EE
hive 开发UDF 使用maven工程 引发jar包缺失 hive 开发UDF 使用maven工程 引发jar包缺失
Daniels-Project:https://khadijaserag.github.ioDaniels-Project
cs32-project4:代码编辑器
iat339-project2:iat339-project2-蔡妍公园和王Ceyao团队
ncpi-project-forge::light_bulb::notebook:Project Forge的材料和计划
2006-03-11 15:26 122,880 关键路径分析.mpp 2005-10-06 00:21 339,456 固定资产信息系统项目.mpp 2005-11-17 16:56 622,592 固定资产信息系统项目.多比较基准.mpp 2005-11-17 16:56 637,440 固定资产信息系统项目....
TodoList-Project-:PHP-OPP-Todolist项目
pintos-project2 在 Pintos 内核中添加用户程序支持:加载可执行文件/系统调用处理机制/IPC
CS-347-Project1:CS 347 Web开发项目1
HTML-CSS-Project1:HTML&CCS firt项目
MEng-Y3-Group-Project-:医学教育的人眼3D动力学模型
431-Project1:RIT CSCI 431
Caleb-Project1:最好的商店应用
JAVA-Project2:JAVA项目
CS50W项目1使用Python和JavaScript进行网络编程在Heroku上使用该应用用法寄存器按名称,作者或ISBN搜索书籍获取有关书籍的信息并提交您自己的评论! :gear: 自行设定# Clone repo$ git clone ...
nd-aws-architect-project1:Udacity AWS Architect ND计划项目1:AWS中的可恢复性
pods-project1:使用弹簧的出租车叫法