在内核模式下,执行代码已完成且不受限制 访问底层硬件。它可以执行任何CPU指令 并引用任何内存地址
任何一个例子?喜欢什么说明,什么内存地址?(x86最好)。至于内存,它是否意味着为内核保留的高1GB地址(32位)?此外,谁决定这个?是CPU还是操作系统?如果是OS,那么CPU如何知道哪些内存被认为是保留的(可能是页表中的某些位)?如何在内核模式下访问内存,仍由虚拟地址访问?
至于进入内核模式,它是由某些指令完成的,如int
对吗?我理解所有系统调用都受到严密保护的部分,但是如果我用汇编代码编写程序,包括int
指令呢?这是如何守卫的?我的意思是当编译该程序时,最终我得到了一个可执行文件,int
指令必须在' .text'因为编辑不会做任何关于它的事情吗?那么操作系统在运行时会怎么做呢?或者' .text'中的内容是什么?部分确实?它是由CPU识别的指令,还是它仍然是某种中间格式的指令,它们将被翻译成'通过操作系统,操作系统将有机会拒绝'某些指令,如' int',或其他任何限制' CPU运行之前的说明?
更新: 对于任何有兴趣的人来说,这里有一个很好的解释(至少对我而言)来自quora:https://www.quora.com/What-is-CPU-kernel-mode-and-how-is-it-guarded-by-the-OS/answer/Mostafa-Abd-El-Aziz?snids=937993065&nsrc=1&filter=all
答案 0 :(得分:1)
我们拥有内核模式的原因是保护进程彼此之间以及它们自身。 (存在过度简化的风险)每个进程看到其地址空间在用户和内核区域之间划分。用户区域仅属于(有一些例外)该进程。所有进程共享相同的系统区域。
将对系统区域的访问限制为内核模式可以防止它在用户模式下运行的恶意进程。
所有进程都需要与内核通信。执行此操作的过程是中断或异常。两者都以相同的方式处理,区别在于它们是如何被触发的。
内核通过调度表定义自身的路径(使用了各种名称)。异常和中断的数字是表中的索引,包含处理特定事件或服务的函数的地址。
示例:
如果要进行I / O,则fprintf语句最终会转换为用户模式包装函数(系统服务),该函数以定义的方式设置堆栈和寄存器。该系统服务触发异常。调度表将它发送到正确的内核模式处理程序,以处理对磁盘的写入(通常是写入)。
内核模式处理程序需要仔细验证发送给它的所有参数。寄存器值是否正确?是否所有对内存的引用都有效且在用户区域中?此处的任何验证漏洞都可能导致系统损坏。
内核模式功能会使您想要写入的数据以正确的停止方式发送到磁盘。
问题:
至于进入内核模式,它是由某些指令完成的 对吧?
是。也有例外,例如除以零,页面错误。恕我直言,Intel INT指令是异常生成器,而不是通常描述的软件中断。让你进入内核模式的三件事是:
我理解所有系统调用的部分都受到严密保护, 但是如果我用汇编代码编写一个程序,包括int 指令?
您的应用程序将通过调度表进行路由。在那里调用的函数应该捕获一个无效的调用。
这是如何守卫的?我的意思是该程序编译时,和 最终我得到了一个可执行文件,int指令必须在 ' .text'因为编译器不会对此做任何事情 对?那么操作系统在运行时会怎么做呢?或者是什么 '的.text'部分确实?它是被认可的指令吗? CPU,或者它可能仍然是一些中间格式 '翻译'通过操作系统,操作系统将有机会拒绝' 某些指令,如' int',或其他任何限制' CPU运行之前的说明?
它由1)强制你去调度表中的处理程序和2)处理程序进行适当的验证。
答案 1 :(得分:0)
全部在手册中。
例如说视频内存/寄存器。或者说例如某些其他程序也在计算机上运行,该计算机具有一些用于指令和数据的存储器。你的程序不应该被允许直接触及内核拥有权限的任何内容,可以,好,坏或其他方式触摸任何内容,但你的应用程序只能触摸你的内存。
这是如何工作的?取决于处理器系列和其他东西,但通常有一个mmu允许你的程序使用一个虚拟地址,该虚拟地址通过mmu提供,这是根据你正在使用的地址查找表中的东西的逻辑,是它是下一条指令的地址,内存中变量的地址或其他。 mmu以及从虚拟地址到物理地址的转换,表格还包含权限和缓存或未缓存的信息。因此,如果您访问mmu表显示的地址不是您的地址,则会发生故障,并且根据硬件(处理器)和操作系统的情况发生,它可能只会给您垃圾或0xFF并让您继续进入杂草或者它可能会一起杀死你的应用程序或介于两者之间。在x86系统上,I / O空间也有类似的东西,允许或不允许I / O地址。
现在故障是可取的,例如您可能听说过虚拟内存。交换或交换空间或其他什么。比如运行的所有应用程序都需要比系统更多的ram,最新的应用程序需要一些内存。选择了一些其他应用程序ram,ram基本上被写入交换文件或硬盘或其他一些媒体,然后标记旧应用程序的mmu表,这样它就会出错,因为它被标记为你得到一个虚拟的解决那个物理公羊。当另一个应用程序出现并且想要访问曾经是他的那个ram时,他会遇到操作系统被调用的错误,并且记得它已经将应用程序内存换成了磁盘,所以它现在从其他人那里找到了一些ram,接受它,将其保存到磁盘,并从磁盘拉出当前的应用程序内存补丁其mmu表并让它保持运行,这种事情不断发生。他们也这样做是为了虚拟化外围设备或允许多个应用程序认为他们正在使用外围设备,但都是真正共享的,没有人真正触摸外围设备只是触摸虚拟设备,每次访问都会导致故障,导致操作系统模拟外设。那时你可以做无穷无尽的事情。
mmu还允许所有程序都认为它们位于相同的地址空间中,所以说所有程序都被编译为具有0x8000的入口点,并且ram是从0x00000线性到您需要或可以解决的数量。如何使每个程序具有相同的地址空间?实际情况是他们都没有那个地址空间,他们认为从地址0到N的线性地址空间真的被mmu切割成各种大小的块,每个块可以在ram中完全不同的位置。也许0x8000到0x10000现在在物理地址0xD0008000,而0x10000现在在物理地址0x22000000,这是完全正常的并且并不罕见。当每个程序启动时,操作系统知道在管理它时可用的物理地址空间,程序说它需要N个字节,因此操作系统将ram拼凑在一起,不像过去的mmu你不必移动其他的东西向上或向下打洞N字节大,你只需要找到一些适合mmu表的子N字节块,这样你最终得到N个字节,然后用程序填充那个空间让应用程序启动。因此,由同一编译器为同一操作系统构建的每个程序的.text将把.text放在同一个地方,理想情况下是.data,依此类推,或者至少它必须符合该操作系统规则。它是正在运行的应用程序的执行模式或虚拟ID,或某些特定于处理器的机制,用于确定您是受保护还是不受保护的程序。在一些我会假设大多数系统甚至内核代码必须通过mmu但内核id或模式或任何被标记为拥有所有权限的内容。并且不是必需的,但对于外围访问,虚拟地址可能等于物理地址,但可能不是你可能仍然需要进行某种内核api调用来获取某个物理地址的虚拟地址/指针(类似于mmap)申请)。
谁决定。操作系统根据该cpu和其他硬件的规则决定并实现所需的任何内容。它通常是cpu和操作系统特定的组合,你基本上如何从应用程序切换到内核或基本上进行"系统调用"从你的申请。当你阅读手册时,它将以某种形式拼写出来。例如,ARM首先要比较容易学习,然后去寻找更复杂的东西......在程序员模型章节和svc指令(有一个我现在无法想到的别名)中为你详细说明了这些模式)告诉你它将处理器切换到在该模式下命中处理程序的模式,该模式基本上是实现调用并返回切换模式的内核/操作系统(假设它是一个返回的调用而不是应用程序退出或正在由于错误而被杀死)。同样,数据中止或预取中止清楚地记录了它进入的模式等等。定义了用户模式限制,您开始看到用户模式代码确实被困在一个无法摆脱的安全沙箱中。
所以这个物理地址以上这个巨大范围的情况不受保护,下面是公平游戏,所有的应用程序地址空间都由操作系统为您管理,并由cpu和相关硬件强制执行,所有它是可能很少映射到物理地址的虚拟地址。内核可能会或可能不会在物理地址中播放,但其执行模式或ID具有比您的更多的权限。您的访客徽章可能会限制您到候诊室或自助餐厅,但其他人的徽章会让他们更深入地进入公司/建筑物的内部,所有这些都由具有神力的人管理,该系统可以为您的徽章或他的徽章或徽章将根据他们的要求和信任打开。