kc3*_*kc3 134 operating-system kernel terminology linux-kernel
内核空间和用户空间有什么区别?内核空间,内核线程,内核进程和内核堆栈是否意味着相同的事情?另外,为什么我们需要这种区别?
Jer*_*fin 113
在真正简单的答案是,内核在内核空间中运行,在用户空间运行的正常程序.用户空间基本上是沙拳的一种形式-它限制用户程序,使他们不能惹的内存(和其他资源)的其它程序或操作系统内核拥有.这限制了(但通常并不完全消除)他们做坏事如撞毁机器的能力.
内核是操作系统的核心.它通常可以完全访问所有内存和机器硬件(以及机器上的所有其他内容).为了使机器尽可能稳定,通常只需要在内核模式/内核空间中运行最受信任,经过良好测试的代码.
堆栈只是内存的另一部分,所以它自然会与内存的其余部分隔离开来.
Aqu*_*irl 62
在随机存取存储器(RAM),逻辑上可以分为两个不同的区域分别是-在内核空间和用户空间(该物理地址的RAM都没有实际划分只是虚拟地址,这一切都被实现MMU)
内核运行在有权使用它的内存部分.这部分内存不能由普通用户的进程直接访问,而内核可以访问内存的所有部分.访问内核的某些部分,用户进程必须使用预定义的系统调用,即open,read,write等等.另外,C库函数一样printf调用系统调用write反过来.
系统调用充当用户进程和内核进程之间的接口.访问权限放在内核空间上,以便在不知不觉中阻止用户搞乱内核.
因此,当发生系统调用时,会向内核发送软件中断.CPU可以将控制暂时移交给相关的中断处理程序例程.在中断处理程序例程完成其工作后,中断停止的内核进程将恢复.
Var*_*rma 22
内核空间和虚拟空间是虚拟内存的概念......它并不意味着Ram(您的实际内存)分为内核和用户空间.每个进程都有虚拟内存,分为内核和用户空间.
所以说"随机存取存储器(RAM)可以分为两个不同的区域,即内核空间和用户空间." 是错的.
&关于"内核空间与用户空间"的事情
创建进程并将其虚拟内存划分为用户空间和内核空间时,其中用户空间区域包含数据,代码,堆栈,进程堆和内核空间包含诸如进程的页表之类的内容为了运行内核空间代码,控制必须转移到内核模式(使用0x80软件中断进行系统调用),内核堆栈基本上是在内核空间中当前执行的所有进程之间共享的,内核数据结构和内核代码等.
Cir*_*四事件 15
CPU环是最明显的区别
在x86保护模式下,CPU始终处于4个环之一.Linux内核仅使用0和3:
这是kernel vs userland最硬,最快的定义.
为什么Linux不使用环1和2:CPU权限环:为什么不使用环1和2?
目前的戒指是如何确定的?
当前环由以下组合选择:
全局描述符表:GDT条目的内存表,每个条目都有一个Privl对该环进行编码的字段.
LGDT指令将地址设置为当前描述符表.
段注册CS,DS等,它指向GDT中条目的索引.
例如,CS = 0表示GDT的第一个条目当前对执行代码有效.
每个戒指可以做什么?
CPU芯片是物理构建的,因此:
ring 0可以做任何事情
ring 3无法运行多条指令并写入多个寄存器,最值得注意的是:
不能改变自己的戒指!否则,它可以将自己设置为响铃0并且响铃将是无用的.
换句话说,不能修改当前的段描述符,这决定了当前的环.
无法修改页面表:x86分页如何工作?
换句话说,不能修改CR3寄存器,并且分页本身会阻止修改页表.
这可以防止一个进程为了安全性/易于编程的原因而看到其他进程的内存.
无法注册中断处理程序.这些是通过写入存储器位置来配置的,这也可以通过分页来防止.
处理程序在0环中运行,会破坏安全模型.
换句话说,不能使用LGDT和LIDT指令.
不能像in和那样做IO指令out,因而有任意硬件访问.
否则,例如,如果任何程序可以直接从磁盘读取,则文件权限将无用.
更确切地说,感谢Michael Petch:操作系统实际上可以在环3上允许IO指令,这实际上是由任务状态段控制的.
不可能的是,如果戒指3首先没有它,则允许自己这样做.
Linux总是不允许它.另请参阅:为什么Linux不通过TSS使用硬件上下文切换?
程序和操作系统如何在环之间转换?
当CPU打开时,它开始在环0中运行初始程序(很好,但它是一个很好的近似值).你可以认为这个初始程序是内核(但它通常是一个引导程序,然后仍然在内环0中调用内核).
当userland进程希望内核为其执行某些操作(如写入文件)时,它会使用生成中断的指令int 0x80来向内核发送信号.
发生这种情况时,CPU会调用内核回调处理程序,内核在引导时注册该处理程序.
此处理程序在ring 0中运行,它决定内核是否允许此操作,执行操作,并在ring 3中重新启动userland程序.
当使用syscall系统调用时(或内核启动时exec),内核准备新用户空进程的寄存器和内存,然后跳转到入口点并将CPU切换到3
如果程序试图做一些顽皮的事情,比如写入禁止的寄存器或内存地址(因为分页),CPU也会调用环0中的一些内核回调处理程序.
但是由于用户区很淘气,内核可能会杀死这个进程,或者用信号给它一个警告.
当内核启动时,它会设置一个具有固定频率的硬件时钟,从而定期生成中断.
此硬件时钟生成运行环0的中断,并允许其调度唤醒哪些用户空进程.
这样,即使进程没有进行任何系统调用,也可能发生调度.
有多个戒指有什么意义?
分离内核和用户区有两个主要优点:
怎么玩呢?
我已经创建了一个裸机设置,应该是直接操作环的好方法:https://github.com/cirosantilli/x86-bare-metal-examples
不幸的是,我没有耐心做出用户名的例子,但我确实做了分页设置,所以userland应该是可行的.我很乐意看到拉动请求.
或者,Linux内核模块在ring 0中运行,因此您可以使用它们来尝试特权操作,例如读取控制寄存器:如何从程序中访问控制寄存器cr0,cr2,cr3?获得分段错误
这是一个方便的QEMU + Buildroot设置,可以在不杀死主机的情况下进行试用.
内核模块的缺点是其他kthreads正在运行并可能干扰您的实验.但理论上你可以用内核模块接管所有中断处理程序并拥有系统,这实际上是一个有趣的项目.
负环
虽然英特尔手册中实际上没有引用负环,但实际上CPU模式还具有比环0本身更多的功能,因此非常适合"负环"名称.
一个例子是虚拟化中使用的管理程序模式.
有关详细信息,请参阅:https://security.stackexchange.com/questions/129098/what-is-protection-ring-1
臂
在ARM中,环被称为异常级别,但主要思想保持不变.
ARMv8中存在4个异常级别,通常用作:
EL0:userland
EL1:内核
管理程序是操作系统,操作系统是用户空间.
例如,Xen允许您在同一系统上同时运行多个操作系统(如Linux或Windows),并且它将操作系统彼此隔离,以确保安全性和调试的简便性,就像Linux对用户程序一样.
管理程序是当今云基础架构的关键部分:它们允许多个服务器在单个硬件上运行,使硬件使用率始终接近100%并节省大量资金.
例如,AWS使用Xen直到2017年才转向KVM发布消息.
EL3:又一个级别.TODO的例子.
在ARMv8架构参考模型DDI 0487C.a - D1章-的AArch64系统级编程模型-图D1-1说明了这美丽的:
请注意,ARM可能由于后见之明的优势而具有比x86更好的命名约定,而不需要负级别:0表示较低级别,3表示最高级别.较高级别往往比较低级别更频繁地创建.
可以使用以下/init指令查询当前EL :当前执行模式/异常级别等是什么?
ARM不要求存在所有异常级别,以允许不需要该功能的实现来节省芯片区域.ARMv8"异常级别"说:
实现可能不包括所有异常级别.所有实现必须包括EL0和EL1.EL2和EL3是可选的.
例如,QEMU默认为EL1,但可以使用命令行选项启用EL2和EL3:qemu-system-aarch64在模拟a53上电时输入el1
Dav*_*ger 10
内核空间和用户空间是特权操作系统功能和受限用户应用程序的分离.分离是必要的,以防止用户应用程序洗劫您的计算机.如果任何旧的用户程序可以开始将随机数据写入硬盘驱动器或从另一个用户程序的内存空间读取内存,那将是一件坏事.
用户空间程序无法直接访问系统资源,因此操作系统内核代表程序处理访问.用户空间程序通常通过系统调用向操作系统发出此类请求.
内核线程,进程,堆栈并不意味着相同的事情.它们是内核空间的类似结构,与用户空间中的对应物相似.
每个进程都有自己的4GB虚拟内存,通过页表映射到物理内存.虚拟内存大多分为两部分:3 GB用于进程,1 GB用于内核.您创建的大多数变量都位于地址空间的第一部分.那部分称为用户空间.最后一部分是内核所在的位置,并且对于所有进程都是通用的.这称为内核空间,大部分空间都映射到启动时加载内核映像的物理内存的起始位置.
地址空间的最大大小取决于CPU上地址寄存器的长度.
在具有32位地址寄存器的系统上,地址空间的最大大小为2 32字节或4 GiB.同样,在64位系统上,可以寻址2 64个字节.
这种地址空间称为虚拟内存或虚拟地址空间.它实际上与物理RAM大小无关.
在Linux平台上,虚拟地址空间分为内核空间和用户空间.
特定于体系结构的常量称为任务大小限制,或TASK_SIZE标记分割发生的位置:
地址范围从0到TASK_SIZE-1分配给用户空间;
TASK_SIZE最多2 32 -1(或2 64 -1)的余数被分配给内核空间.
例如,在特定的32位系统上,可以为用户空间占用3 GiB,为内核空间占用1 GiB.
类Unix操作系统中的每个应用程序/程序都是一个过程; 每个都有一个称为Process Identifier的唯一标识符(或简称Process ID,即PID).Linux提供了两种创建进程的机制:1.fork()系统调用,或2. exec()调用.
内核线程是一个轻量级进程,也是一个正在执行的程序.单个进程可能包含多个共享相同数据和资源但通过程序代码采用不同路径的线程.Linux提供了一个clone()生成线程的系统调用.
内核线程的示例用法是:RAM的数据同步,帮助调度程序在CPU之间分配进程等.
| 归档时间: |
|
| 查看次数: |
114063 次 |
| 最近记录: |