内核空间和用户空间有什么区别?

内核空间和用户空间有什么区别? 内核空间,内核线程,内核进程和内核堆栈意味着什么? 另外,为什么我们需要这种差异?

真正简单的答案是内核运行在内核空间,正常的程序运行在用户空间。 用户空间基本上是一种沙盒(sandboxing)的forms,它限制了用户程序,所以它们不能混淆其他程序或操作系统内核拥有的内存(和其他资源)。 这限制了(但通常不能完全消除)他们做坏事的能力,比如崩溃机器。

内核是操作系统的核心。 它通常可以完全访问所有内存和机器硬件(以及机器上的其他所有内容)。 为了使机器尽可能地保持稳定,通常只需要最可靠,经过严格testing的代码在内核模式/内核空间中运行。

堆栈只是内存的另一部分,所以很自然地和其余的内存一起分离。

随机存取存储器 (RAM)在逻辑上可以划分为两个不同的区域,即内核空间和用户空间( RAM的物理地址实际上并不仅仅是虚拟地址 , 而是由MMU实现的)

内核运行在有权使用的内存部分。 这部分内存不能被普通用户的进程直接访问,而内核可以访问内存的所有部分。 要访问内核的某些部分,用户进程必须使用预定义的系统调用,即openreadwrite等。同样, C库函数(如printf依次调用系统调用write

系统调用充当用户进程和内核进程之间的接口。 访问权限放置在内核空间,以防止用户在不知情的情况下搞乱内核。

所以,当系统调用发生时,软件中断被发送到内核。 CPU可以暂时将控制交给相关的中断处理程序。 在中断处理程序完成其工作之后,由中断暂停的内核进程恢复。

内核空间和虚拟空间是虚拟内存的概念….它并不意味着RAM(你的实际内存)被分成内核和用户空间。 每个进程都被分配了内核和用户空间的虚拟内存。

所以说“随机存取存储器(RAM)可以分为两个不同的区域,即内核空间和用户空间。 是错的。

关于“内核空间vs用户空间”的事情

当一个进程被创build并且它的虚拟内存被分为用户空间和内核空间,其中用户空间区域包含数据,代码,堆栈,进程和内核空间空间的堆包含诸如进程,内核数据结构和内核代码等。为了运行内核空间代码,控制必须转换到内核模式(对于系统调用使用0x80软件中断),内核堆栈基本上是当前在内核空间中执行的所有进程之间共享的。

内核空间和用户空间是特权操作系统function与受限用户应用程序的分离。 分离是必要的,以防止用户的应用程序来洗劫你的电脑。 如果任何旧用户程序可能开始将随机数据写入硬盘或从另一个用户程序的内存空间读取内存,那将是一件坏事。

用户空间程序不能直接访问系统资源,因此操作系统内核代表程序处理访问。 用户空间程序通常通过系统调用来提供操作系统的这种请求。

内核线程,进程,堆栈并不意味着同样的事情。 它们是内核空间的类似结构,与用户空间中的对应结构类似。

每个进程都有自己的4GB虚拟内存,通过页表映射到物理内存。 虚拟内存大致分为两部分:使用进程3 GB和使用内核1 GB。 你创build的大部分variables都在地址空间的第一部分。 这部分被称为用户空间。 最后一部分是内核驻留的地方,在所有进程中都是常见的。 这被称为内核空间,这个空间的大部分映射到启动时加载内核映像的物理内存的起始位置。

地址空间的最大大小取决于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类操作系统中的每个应用程序/程序都是一个进程; 每一个都有一个称为进程标识符(或简称进程ID ,即PID)的唯一标识符。 Linux提供了两种创build进程的机制:1. fork()系统调用,或者2. exec()调用。

内核线程是一个轻量级进程,也是一个正在执行的程序。 一个进程可能由几个线程组成,这些线程共享相同的数据和资源,但在程序代码中采用不同的path。 Linux提供了一个clone()系统调用来生成线程。

内核线程的使用示例如下:RAM的数据同步,帮助调度程序在CPU之间分配进程等。

简而言之:内核运行在内核空间,内核空间可以完全访问所有的内存和资源,可以说内存分为两部分,一部分为内核,一部分为用户自己的进程,(用户空间)运行正常的程序,用户空间不能直接访问内核空间,所以它要求内核使用资源。 通过系统调用(在glibc中预定义的系统调用)

有一个声明,简化了不同的“ 用户空间只是一个内核的testing负载 ”…

要非常清楚:处理器架构允许CPU以两种模式运行,即内核模式和用户模式 ,硬件指令允许从一种模式切换到另一种模式。

内存可以被标记为用户空间或内核空间的一部分。

当CPU运行在用户模式下时,CPU只能访问正在用户空间的内存,而CPU则尝试访问内核空间的内存,结果是“硬件exception”,当CPU运行在内核模式下时,CPU可以直接访问到内核​​空间和用户空间…

内核空间意味着内存空间只能被内核触及。 在32位linux上,它是1G(从0xC0000000到0xFFFFFFFF作为虚拟内存地址)。内核创build的每个进程也是一个内核线程。因此,对于一个进程,有两个堆栈:用户空间中的一个堆栈,内核线程的空间。

内核堆栈占用2页(32位linux 8k),包括一个task_struct(约1k)和真正的堆栈(约7k)。 后者用于在内核函数中存储一些自动variables或函数调用参数或函数地址。 这里是代码(Processor.h(linux \ include \ asm-i386)):

 #define THREAD_SIZE (2*PAGE_SIZE) #define alloc_task_struct() ((struct task_struct *) __get_free_pages(GFP_KERNEL,1)) #define free_task_struct(p) free_pages((unsigned long) (p), 1) 

__get_free_pages(GFP_KERNEL,1))表示将内存分配为2 ^ 1 = 2页。

但是进程栈是另一回事,它的地址就是0xC0000000(32位linux),它的大小可以相当大,用于用户空间函数的调用。

所以这里是系统调用的一个问题,它在内核空间运行,但是在用户空间被进程调用,它是如何工作的? Linux会把它的参数和函数地址放在内核栈或进程栈中吗? Linux的解决scheme:所有的系统调用都是由软件中断INT 0x80触发的。 在entry.S(linux \ arch \ i386 \ kernel)中定义,下面是一些行例如:

 ENTRY(sys_call_table) .long SYMBOL_NAME(sys_ni_syscall) /* 0 - old "setup()" system call*/ .long SYMBOL_NAME(sys_exit) .long SYMBOL_NAME(sys_fork) .long SYMBOL_NAME(sys_read) .long SYMBOL_NAME(sys_write) .long SYMBOL_NAME(sys_open) /* 5 */ .long SYMBOL_NAME(sys_close) 

通过Quora的Sunil Yadav:

Linux内核是指在内核模式下运行的所有内容,由几个不同的层组成。 在最底层,内核通过HAL与硬件交互。 在中间层,UNIX内核分为4个不同的区域。 四个区域中的第一个处理字符设备,生和熟TTY和terminal处理。 第二个区域处理networking设备驱动程序,路由协议和套接字。 第三个区域处理磁盘设备驱动程序,页面和缓冲区高速caching,文件系统,虚拟内存,文件命名和映射。 第四个和最后一个区域处理进程调度,调度,创build和终止以及信号处理。 最重要的是,我们拥有内核的顶层,包括系统调用,中断和陷阱。 这个级别作为每个下级function的接口。 程序员使用各种系统调用和中断来与操作系统的function进行交互。

在短内核空间是linux内核运行的内存部分(linux下最高1GB的虚拟空间),用户空间是运行用户应用程序的内存部分(Linux下是3GB的虚拟内存),如果你想知道更多的见下面的链接:)

http://learnlinuxconcepts.blogspot.in/2014/02/kernel-space-and-user-space.html

试图给出一个非常简单的解释

虚拟内存分为内核空间和用户空间。 内核空间是运行内核进程的虚拟内存区域,用户空间是用户进程将运行的虚拟内存区域。

内存访问保护需要此分区。

只要引导加载程序在将内核加载到RAM中的某个位置(通常在基于ARM的控制器上)时启动内核,就需要确保控制器处于FIQ和IRQ禁用的pipe理程序模式。

戒指是最明显的区别

在x86中,CPU运行在四个环之一中。 Linux内核只使用0和3:

  • 0为内核
  • 3为用户

这是内核vs用户空间的最难和最快的定义。

为什么Linux不使用环1和2: CPU权限环:为什么环1和2不使用?

CPU是这样做的:

  • 响0可以做任何事情

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

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

      换句话说,不能修改当前段描述符 ,这决定了当前的环。

    • 不能修改页表: x86分页如何工作?

      换句话说,不能修改CR3寄存器,并且分页本身可以防止修改页表。

      这防止了一个进程为了安全性/易于编程的原因而看见其他进程的内存。

    • 不能注册中断处理程序。 这些通过写入到内存位置进行configuration,这也是通过分页阻止的。

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

      换句话说,不能使用LGDT和LIDT指令。

    • 不能像out进行IO指令,因此有任意的硬件访问。

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

这是程序之间如何转换的过程:

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

  • 当使用exec系统调用时,它会在ring 3中启动一个userland进程

  • 当一个用户态进程需要内核为写入文件做某些事情时,它使用一个产生中断的指令,例如int 0x80来发信号给内核。

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

    这个处理程序在ring 0中运行,它决定了内核是否允许这个动作,执行这个动作,然后在ring 3中重新启动userland程序。

  • 如果程序试图做一些顽皮的事情,如写入禁止的寄存器或内存地址(因为分页),CPU也会调用ring 0中的一些内核callback处理程序。

    但是由于用户区太顽皮了,内核可能会在这个时候终止进程,或者给出一个警告信号。

  • 内核启动时,它设置一个固定频率的硬件时钟,周期性地产生中断。

    这个硬件时钟产生运行环0的中断,并允许它调度哪些用户态进程被唤醒。

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

分离内核和用户空间有两大优势:

  • 制作节目比较容易,因为你更确定不会干扰对方。 例如,一个用户级进程不必担心因分页而覆盖另一个程序的内存,也不必担心硬件进入另一个进程的无效状态。
  • 它更安全。 例如,文件权限和内存分离可以防止黑客应用程序读取您的银行数据。 这当然假设你相信内核。

正确答案是:内核空间和用户空间都没有。 处理器指令集具有特殊的权限来设置破坏性的东西,比如页表格图的根,或者访问硬件设备存储器等等。

内核代码具有最高级别的权限,用户代码最低。 这可以防止用户代码崩溃系统,修改其他程序等。

通常,内核代码保存在与用户代码不同的内存映射下(就像用户空间保存在不同的内存映射中一样)。 这是“内核空间”和“用户空间”术语的来源。 但这不是一条硬性规定。 例如,由于x86间接要求其中断/陷阱处理程序始终被映射,因此内核的部分(或部分操作系统)必须映射到用户空间。 同样,这并不意味着这样的代码具有用户权限。

为什么内核/用户需要划分? 有些devise师不同意这实际上是必要的。 微内核体系结构的基础是这样的思想:代码的最高特权部分应尽可能小,所有重要的操作都在用户特权代码中完成。 你需要研究为什么这可能是一个好主意,这不是一个简单的概念(并因其优点和缺点而闻名)。

在Linux中有两个空间,第一个是用户空间,另一个是内核空间。 用户空间只包含你想运行的用户应用程序。 作为核心服务,存在进程pipe理,文件pipe理,信号处理,内存pipe理,线程pipe理等等。 如果你从用户空间运行应用程序只与核心服务交互。 并且该服务与存在于硬件和内核之间的设备驱动程序交互。 核心空间和用户空间分离的主要好处是我们可以通过用户空间中所有用户应用程序的病毒来实现安全性,而服务则存在于核心空间中。 这就是为什么Linux不会影响病毒。