终于又回来了。内核态和用户态切换比较麻烦,今天解决了一个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态的切换。
分享到:
相关推荐
hive 开发UDF 使用maven工程 引发jar包缺失 hive 开发UDF 使用maven工程 引发jar包缺失
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 :...
gEDA homepage: http://www.geda-project.org -----gschem.exe 1.9.2 (g9e1f72c) -----pcb.exe Compile Time Options ----- GUI: gtk : Gtk - The Gimp Toolkit Exporters: bom : Exports a Bill of Materials ...
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 固定资产信息系统项目....
在"Pintos-project2"中,我们将深入探讨如何在Pintos内核中实现对用户程序的支持,包括加载可执行文件、系统调用处理机制以及进程间通信(IPC)。这个过程涉及到多个关键的计算机系统概念,如内存管理、中断处理和...
431-Project1:RIT CSCI 431
JavaScript滑块是一种常见的网页...总之,"javascript-project-slider"项目是一个涉及HTML、CSS和JavaScript的综合实践,涵盖了网页动态效果的实现、用户交互处理等多个方面,对于提升前端开发技能具有很好的学习价值。
4. **开源软件**:"ncpi-project-forge-master" 提示这是一个开源项目,意味着源代码对公众开放,允许用户自定义、扩展和贡献代码,以满足特定需求。 5. **版本控制**:“master”分支是版本控制系统中的一个概念,...
CS50W项目1使用Python和JavaScript进行网络编程在Heroku上使用该应用用法寄存器按名称,作者或ISBN搜索书籍获取有关书籍的信息并提交您自己的评论! :gear: 自行设定# Clone repo$ git clone ...
来自emule-project的原版emule,里面没有关键字过滤,可以自由的下载一切资源,不可多得啊~
在这个项目中,"fireworx-streamline-project-master"可能包含源代码、配置文件和其他相关资源,以改善MATLAB的默认设置,提供更加智能化的代码提示功能。 MATLAB的快捷键通常分为两类:基本编辑器快捷键和特定功能...
composer create-project drupal-composer/drupal-project:9.x-dev some-dir --no-interaction 使用composer require ...您可以将新的依赖项下载到您的安装中。 cd some-dir composer require drupal/devel ...
WebUml-ProjectManager WebUml项目管理器后端。 职责: 用于元模型和表示模型元素的CRUD 要求: GIT 1.9( ) Java 8( ) Maven 3.0.5( ) heroku-toolbelt 3.6.0( ) MongoDB的 推荐工具: jq( ) 在...
midterm-project-aagamsh1:GitHub Classroom创建的midterm-project-aagamsh1
Lesson 1 - Why should you learn how to program? Lesson 2 - Basic principles of learning a programming language UNIT 1 - VARIABLES, TYPES, EXPRESSIONS, AND STATEMENTS Lesson 3 - Introducing Python: a ...
此外,在注释部分还提到了其他一些权限,例如用户管理和项目管理等,但这些内容并未在枚举类中具体实现。 通过以上解析,我们可以看出这是一个用于定义用户角色及其对应权限的枚举类,涵盖了从项目层面到数据层面再...
15年6月更新,完整的repo-project,完美解决fatal: Cannot get https://gerrit.googlesource.com/git-repo/clone.bundle 错误,绕开GFW。
team-project-team2:由GitHub Classroom创建的team-project-team2
总之,"CIS3100--Term-Project--AddressBook"是一个涵盖C++核心概念和编程实践的教学项目,旨在提升学生的编程技能和问题解决能力,同时也体现了C++在实际应用中的价值。通过参与这样的项目,学生不仅能够加深对C++...