代码之家  ›  专栏  ›  技术社区  ›  Alex

操作系统中的用户模式和内核模式有什么区别?

  •  89
  • Alex  · 技术社区  · 16 年前

    用户模式和内核模式之间有什么区别,为什么激活它们,如何激活它们,它们的用例是什么?

    7 回复  |  直到 6 年前
        1
  •  126
  •   Chris Simmons Badrinarayanan Lakshmiraghavan    11 年前
    1. 内核模式

      在内核模式下,执行代码是完整的和不受限制的 访问底层硬件。它 可以执行任何CPU指令和 引用任何内存地址。内核 模式通常为 最低级别,最可信的功能 操作系统的。崩溃 内核模式是灾难性的;它们 将停止整个PC。

    2. 用户模式

      在用户模式下,执行代码不能直接访问 硬件或参考存储器。代码 在用户模式下运行必须委托给 访问硬件或 记忆。由于所提供的保护 通过这种隔离,崩溃 用户模式始终是可恢复的。大多数 在您的计算机上运行的代码 将在用户模式下执行。

    多读

    Understanding User and Kernel Mode

        2
  •  44
  •   Salvador Dali    13 年前

    这是两种不同的计算机操作模式。在此之前,当计算机就像一个大房间,如果有什么东西崩溃,它会停止整个计算机。所以计算机架构师决定改变它。现代微处理器在硬件上实现至少两种不同的状态。

    用户模式:

    • 所有用户程序执行的模式。它不能访问RAM 和硬件。原因是如果所有程序都在 内核模式下,它们可以覆盖彼此的内存。如果 它需要访问这些功能中的任何一个,它调用 基础API。由Windows启动的每个进程(系统除外) 进程以用户模式运行。

    内核模式:

    • 所有内核程序执行的模式(不同的驱动程序)。它有 访问每个资源和底层硬件。任何CPU指令 可以执行,并且可以访问每个内存地址。这种模式 为最低级别的驾驶员保留

    开关是如何发生的。

    CPU不会自动完成从用户模式到内核模式的切换。CPU被中断中断(计时器、键盘、I/O)。当中断发生时,CPU停止执行当前运行的程序,切换到内核模式,执行中断处理程序。此处理程序保存CPU的状态,执行其操作,恢复状态并返回到用户模式。

    http://en.wikibooks.org/wiki/Windows_Programming/User_Mode_vs_Kernel_Mode

    http://tldp.org/HOWTO/KernelAnalysis-HOWTO-3.html

    http://en.wikipedia.org/wiki/Direct_memory_access

    http://en.wikipedia.org/wiki/Interrupt_request

        3
  •  8
  •   niconoe    9 年前

    运行Windows的计算机中的处理器有两种不同的模式:用户模式和内核模式。处理器根据处理器上运行的代码类型在两种模式之间切换。应用程序以用户模式运行,核心操作系统组件以内核模式运行。当许多驱动程序在内核模式下运行时,一些驱动程序可能在用户模式下运行。

    启动用户模式应用程序时,Windows会为该应用程序创建一个进程。这个过程为应用程序提供了一个私有虚拟地址空间和一个私有句柄表。由于应用程序的虚拟地址空间是私有的,因此一个应用程序无法更改属于另一个应用程序的数据。每个应用程序都是独立运行的,如果应用程序崩溃,则崩溃仅限于该应用程序。其他应用程序和操作系统不受崩溃影响。

    除了私有之外,用户模式应用程序的虚拟地址空间也受到限制。以用户模式运行的处理器无法访问为操作系统保留的虚拟地址。限制用户模式应用程序的虚拟地址空间可防止应用程序更改并可能损坏关键操作系统数据。

    在内核模式下运行的所有代码共享一个虚拟地址空间。这意味着内核模式驱动程序与其他驱动程序和操作系统本身没有隔离。如果内核模式驱动程序意外写入错误的虚拟地址,则属于操作系统或其他驱动程序的数据可能会受到损害。如果内核模式驱动程序崩溃,整个操作系统就会崩溃。

    如果您是Windows用户,一旦浏览此链接,您将获得更多信息。

    Communication between user mode and kernel mode

        4
  •  5
  •   Mark Rushakoff    16 年前

    我要在黑暗中捅一刀,猜你是在说窗户。简而言之,内核模式可以完全访问硬件,但用户模式不能。例如,许多设备驱动程序(如果不是大多数)都是以内核模式编写的,因为它们需要控制硬件的更详细信息。

    也见 this wikibook .

        5
  •  3
  •   Dirk Vollmar    16 年前

    其他答案已经解释了用户模式和内核模式之间的区别。如果你真的想了解细节,你应该得到一份 Windows Internals 这是一本由MarkRussinovich和DavidSolomon撰写的优秀书籍,描述了各种Windows操作系统的体系结构和内部细节。

        6
  •  2
  •   Ciro Santilli OurBigBook.com    6 年前

    CPU环是最明显的区别

    在x86保护模式下,CPU始终处于4个环中的一个环中。Linux内核仅使用0和3:

    • 0内核
    • 3用户

    这是内核与用户土地之间最难和最快的定义。

    为什么Linux不使用环1和环2: CPU Privilege Rings: Why rings 1 and 2 aren't used?

    当前环是如何确定的?

    当前环通过以下组合选择:

    • 全局描述符表:一个包含gdt项的内存表,每个项都有一个字段 Privl 它对环进行编码。

      lgdt指令将地址设置为当前描述符表。

      参见: http://wiki.osdev.org/Global_Descriptor_Table

    • 段寄存器cs、ds等,这些寄存器指向gdt中某个条目的索引。

      例如, CS = 0 表示GDT的第一个条目对于正在执行的代码当前处于活动状态。

    每个戒指能做什么?

    CPU芯片的物理结构如下:

    • 电话0可以做任何事

    • 环3不能运行多个指令并写入多个寄存器,最明显的是:

      • 不能改变自己的戒指!否则,它可以将自己设置为环0,而环将是无用的。

        换句话说,不能修改当前 segment descriptor ,决定当前环。

      • 无法修改页表: How does x86 paging work?

        换句话说,不能修改CR3寄存器,分页本身会阻止修改页表。

        这会阻止一个进程看到其他进程的内存,因为安全/易于编程。

      • 无法注册中断处理程序。这些是通过写入内存位置来配置的,也可以通过分页来阻止。

        处理程序在环0中运行,将破坏安全模型。

        换句话说,不能使用lgdt和lidt指令。

      • 不能像这样做IO指令 in out 从而具有任意的硬件访问。

        否则,例如,如果任何程序可以直接从磁盘读取,那么文件权限将是无用的。

        更准确地说,多亏了 Michael Petch :操作系统实际上可以允许3号环上的IO指令,这实际上由 Task state segment .

        不可能的是,如果3号环一开始没有它,它就允许自己这样做。

        Linux总是不允许这样做。参见: Why doesn't Linux use the hardware context switch via the TSS?

    程序和操作系统如何在环之间转换?

    • 当CPU打开时,它开始在环0中运行初始程序(很好,但这是一个很好的近似值)。您可以认为这个初始程序是内核(但它通常是一个引导加载程序,然后调用仍然处于环0中的内核)。

    • 当一个userland进程希望内核为它做一些事情,比如写一个文件,它使用一条产生中断的指令,比如 int 0x80 向内核发出信号。

      当发生这种情况时,CPU调用并中断内核在启动时注册的回调处理程序。

      这个处理程序在环0中运行,它决定内核是否允许这个操作,执行这个操作,并重新启动环3中的userland程序。

    • exec 使用系统调用(或当内核 will start /init )内核 prepares the registers and memory 在新的userland进程中,它跳到入口点并将CPU切换到3环

    • 如果程序试图做一些淘气的事情,比如写到禁止的寄存器或内存地址(因为分页),CPU也会在环0中调用一些内核回调处理程序。

      但是由于userland很淘气,内核这次可能会终止进程,或者给它一个带有信号的警告。

    • 当内核启动时,它会设置一个固定频率的硬件时钟,从而定期生成中断。

      这个硬件时钟生成运行0环的中断,并允许它计划唤醒哪个userland进程。

      这样,即使进程没有进行任何系统调用,也可以进行调度。

    有多个环有什么意义?

    分离内核和用户土地有两个主要优点:

    • 制作程序更容易,因为您更确定一个程序不会干扰另一个程序。例如,一个userland进程不必担心由于分页而重写另一个程序的内存,也不必担心将硬件置于另一个进程的无效状态。
    • 它更安全。例如,文件权限和内存分离可能会阻止黑客程序读取您的银行数据。当然,这假设您信任内核。

    怎么玩它?

    我已经创建了一个裸机设置,它应该是直接操作环的好方法: https://github.com/cirosantilli/x86-bare-metal-examples

    不幸的是,我没有耐心去做一个userland示例,但我确实做了分页设置,所以userland应该是可行的。我很想看到拉车请求。

    或者,Linux内核模块在环0中运行,因此您可以使用它们来尝试特权操作,例如读取控制寄存器: How to access the control registers cr0,cr2,cr3 from a program? Getting segmentation fault

    这里是一个 convenient QEMU + Buildroot setup 在不杀死主人的情况下尝试一下。

    内核模块的缺点是其他kthread正在运行,可能会干扰您的实验。但理论上,您可以用内核模块接管所有中断处理程序,并拥有系统,这实际上是一个有趣的项目。

    负环

    虽然在Intel手册中没有实际引用负环,但实际上有一些CPU模式比环0本身具有更多的功能,因此非常适合“负环”名称。

    一个例子是虚拟化中使用的管理程序模式。

    有关更多详细信息,请参阅: https://security.stackexchange.com/questions/129098/what-is-protection-ring-1

    手臂

    在ARM中,环被称为异常级别,但主要思想保持不变。

    ARMV8中存在4个异常级别,通常用作:

    • EL0:用户地

    • EL1:内核

    • EL2: hypervisors ,例如 Xen .

      管理程序对操作系统而言,就像操作系统对用户土地一样。

      例如,Xen允许您同时在同一个系统上运行多个操作系统,如Linux或Windows,它将操作系统彼此隔离,以确保安全性和易于调试,就像Linux对userland程序所做的那样。

      管理程序是当今云基础设施的一个关键部分:它们允许多个服务器在一个硬件上运行,使硬件使用率始终接近100%,并节省大量资金。

      例如,美国焊接学会(AWS)在2017年之前使用XEN,当时 its move to KVM made the news .

    • EL3:又一个层次。TODO示例。

    这个 ARMv8 Architecture Reference Model DDI 0487C.a -第D1章-AARCH64系统级程序员模型-图D1-1完美地说明了这一点:

    enter image description here

    请注意,ARM如何在不需要负级别的情况下,为特权级别提供比x86更好的命名约定,这可能是由于事后诸葛亮:0是低级别,3是高级别。更高的级别往往比低级别更容易创建。

    当前EL可以通过 MRS 指令: what is the current execution mode/exception level, etc?

    ARM并不要求所有异常级别都存在,以允许不需要该特性来保存芯片区域的实现。ARMV8“异常级别”表示:

    实现可能不包括所有异常级别。所有实现必须包括EL0和EL1。 EL2和EL3是可选的。

    例如,qemu默认为el1,但可以使用命令行选项启用el2和el3: qemu-system-aarch64 entering el1 when emulating a53 power up

        7
  •  1
  •   Ali Asgari    7 年前

    什么

    基本上,内核模式和用户模式之间的区别不依赖于操作系统,只有通过硬件设计来限制某些指令只能在内核模式下运行才能实现。像内存保护这样的所有其他目的只能通过这种限制来实现。

    怎么用?

    这意味着处理器要么处于内核模式,要么处于用户模式。使用一些机制,体系结构可以保证每当它切换到内核模式时,都会提取操作系统代码以运行。

    为什么?

    有了这个硬件基础设施,可以在通用操作系统中实现这些功能:

    • 保护用户程序不访问整个内存,例如不让程序覆盖操作系统,
    • 防止用户程序执行敏感指令,例如更改CPU内存指针边界的指令,以防止程序打破其内存边界。