返回介绍

实验五:可在内核态和用户态之间进行切换的 ucore

发布于 2025-02-16 22:47:46 字数 1759 浏览 0 评论 0 收藏 0

在操作系统原理中,一直强调操作系统运行在内核态(特权态),应用程序运行在用户态(非特权态)。但为什么说处于用户态的应用程序就不能访问内核态的数据,而内核态的操作系统可以访问用户态的数据?我们有没有一个 project 来体验内核态和用户态的区别是什么?更进一步体验如何在内核态和用户态之间进行切换呢?project4.1.1 为此进行了尝试。

实验目标

通过学习和实践,读者可以了解如何 CPU 处不同特权态下的执行特点和限制,理解如何从内核态切换到用户态,以及如何从用户态切换到内核态。

proj4.1.1 概述

实现描述

proj4.1.1 建立在 proj4.1(当然是基于 proj4)基础之上,主要完成了用户态(非特权态)与内核态相互切换的过程。相对于 proj4,主要增加了两部分工作,一部分是从用户态返回内核态的准备工作,即建立任务段(Task Segment)和任务段描述符(SEG_TSS),设置陷阱中断号(T_SWITCH_TOK)和对应的中断处理例程。另外一部分是对内核栈进行各种特殊处理,使得能够完成内核态切换到用户态或用户态切换到内核态的工作。

项目组成

这里我们通过 proj4.1.1 来完成此事。proj4.1.1 整体目录结构如下所示:

proj4.1.1
| -  kern
|   | -  init
|   |   ` -  init.c
|   | -  mm
|   |   | -  memlayout.h
|   |   | -  mmu.h
|   |   | -  pmm.c
|   |   ` -  pmm.h
|   ` -  trap
|       | -  trap.c
|       | -  trapentry.S
|       | -  trap.h
|       ` -  vectors.S
……

相对于 proj4,改动不多,主要修改和增加的文件如下:

  • memlayout.h:定义了全局描述符的索引值和一些段描述符的属性。
  • pmm.[ch]:为了能够使 CPU 从用户态转换到内核态,在 ucore 初始化时,设置任务段和任务段描述符,重新加载任务段和段描述符表;
  • trap.c:设置自定义的陷阱中断 T_SWITCH_TOK(用于用户态切换到内核态)和实现对自定义的陷阱中断 T_SWITCH_TOK/T_SWITCH_TOU 的中断处理例程,使得 CPU 能够在内核态和用户态之间切换。

编译运行

编译并运行 proj4.1.1 的命令如下:

make
make qemu

则可以得到如下显示界面

3.5.2.1

通过上图,我们可以看到 ucore 在切换到用户态之前,先显示了当前 CPU 的特权级(CS 的最低两位),CS/DS/ES/SS 的值(即对应的段描述符表的索引值),可以看到特权级为 0。根据 lgdt 函数(位于 kern/mm/pmm.c 中)的处理,CS 的值是内核代码段描述符的索引下标,DS/ES/SS 的值是内核数据段描述符的索引下标;而在切换到用户态后,又显示了一下,当前 CPU 的特权级为 3, CS 的值为 1b,DS/ES/SS 的值为 23,把这四个寄存器的值&0xfc,则分别为 0x18(SEG_UTEXT)和 0x20(SEG_UDATA),说明确实运行在用户态了。在执行了系统调用 T_SWITCH_TOK 后,又回到了内核态。下面我们将分析到底发生了什么事情。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文