这是内核态和用户态切换的最后一篇,也是project4的最后一篇了。
完成了使用call gate进行用户态到内核态的切换,使用lret进行内核态到用户态的切换的实验。这是project4.1.2的内容。
内核态到用户态的切换比较麻烦一些,首先将用户态段selector给ds,es,fs,gs赋值,将用户态栈的selector压栈,然后ebp压栈。因为c编译器会再函数开头将ebp压栈,然后将esp赋值给ebp,因此压栈的实际上就是压用户态栈selector前的esp的值。然后将用户态代码段selector压栈,然后将lret下一条指令位置压栈,然后执行lret,完成。代码如下:
static void callk2u()
{
asm volatile ("movw %0, %%ax;"
"movw %%ax, %%ds;"
"movw %%ax, %%es;"
"movw %%ax, %%fs;"
"movw %%ax, %%gs;"
"pushl %0;"
"pushl %%ebp;"
"pushl %1;"
"pushl $1f;"
"lret;"
"1:"
::"i"(SS_UDATA), "i"(SS_UTEXT));
}
callk2u函数返回后,cpu已经处于用户态了。
用户态切换到内核态代码比较简单,使用callgate操作,不过在这里犯了个错误,调用lcall时,没有传入callgate的selector(51),而是传了callgate在gdt数组中的下标(6),导致调用出错,改过来就好了。
首先建立callgate:
setcallgate(&gdt[GATE_CALLU2K], SS_KTEXT, to_kernel, 0, DPL_USER);
这里to_kernel函数用来做假,将栈换掉,执行ret而不是lret,所以to_kernel返回时,不是原样不变返回原来的用户态,而是处于内核态了,并且代码还继续往后执行。to_kernel代码如下:
static void to_kernel()
{
asm volatile("movw %0, %%ax"
"movw %%ax, %%ds;"
"movw %%ax, %%es;"
"movw %%ax, %%fs;"
"movw %%ax, %%gs;"
"movl 4(%%ebp), %%eax;"
"movl 12(%%ebp), %%esp;"
"pushl %%eax;"
"pushl %%ebp;"
::"i" (SS_KDATA));
}
其中最后一句pushl %%ebp主要是用来应对c编译器为to_kernel生成的popl %ebp; ret这两条指令的,也可以不要pushl %%ebp,直接使用ret指令,此时编译器自动生成的popl %ebp; ret两条指令就不会被执行了。无论哪种方式,都不会对堆栈产生影响。
调用callgate的代码如下(因使用lcall,所以也要使用汇编来处理):
static void callu2k()
{
asm volatile ("lcall %0, $0;"
::(i)(GS_CALLU2K));
}
分享到:
相关推荐
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)。这个过程涉及到多个关键的计算机系统概念,如内存管理、中断处理和...
JavaScript滑块是一种常见的网页...总之,"javascript-project-slider"项目是一个涉及HTML、CSS和JavaScript的综合实践,涵盖了网页动态效果的实现、用户交互处理等多个方面,对于提升前端开发技能具有很好的学习价值。
llvm-project-18.1.8.src 官方离线下载包 # 下载 llvm-project wget -nc https://github.com/llvm/llvm-project/releases/download/llvmorg-18.1.8/llvm-project-18.1.8.src.tar.xz # 解压 llvm-project-18.1.8.src...
4. **开源软件**:"ncpi-project-forge-master" 提示这是一个开源项目,意味着源代码对公众开放,允许用户自定义、扩展和贡献代码,以满足特定需求。 5. **版本控制**:“master”分支是版本控制系统中的一个概念,...
来自emule-project的原版emule,里面没有关键字过滤,可以自由的下载一切资源,不可多得啊~
在这个项目中,"fireworx-streamline-project-master"可能包含源代码、配置文件和其他相关资源,以改善MATLAB的默认设置,提供更加智能化的代码提示功能。 MATLAB的快捷键通常分为两类:基本编辑器快捷键和特定功能...
431-Project1:RIT CSCI 431
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( ) 在...
Lesson 4 - Variables and expressions: giving names and values to things Lesson 5 - Object types and statements of code 46 Lesson 6 - Capstone project: your first Python program-convert hours to ...
在“GeekOS-project3”中,学生可能需要实现进程的概念,包括进程创建、销毁、上下文切换等。进程是执行中的程序实例,每个进程都有自己的独立内存空间。理解进程状态转换(新建、就绪、运行、等待和结束)以及如何...
此外,在注释部分还提到了其他一些权限,例如用户管理和项目管理等,但这些内容并未在枚举类中具体实现。 通过以上解析,我们可以看出这是一个用于定义用户角色及其对应权限的枚举类,涵盖了从项目层面到数据层面再...
:gear: 自行设定# Clone repo$ git clone https://github.com/marcorichetta/cs50-project1.git$ cd cs50-project1# Create a virtualenv (Optional but reccomended)$ python3 -m venv myvirtualenv# Activate the...
midterm-project-aagamsh1:GitHub Classroom创建的midterm-project-aagamsh1
team-project-team2:由GitHub Classroom创建的team-project-team2