在操作系统中,虚拟内存通常会被分成用户空间(又称使用者空间),与核心空间这两个区块。
用户空间概述Linux系统将自身划分为两部分,一部分为核心软件,即是kernel,也称作内核空间,另一部分为普通应用程序,这部分称为用户空间。
用户空间中的代码运行在较低的特权级别上,只能看到允许它们使用的部分系统资源,并且不能使用某些特定的系统功能,也不能直接访问内核空间和硬件设备,以及其他一些具体的使用限制。
定义在操作系统中,虚拟内存通常会被分成用户空间(英语:User space,又译为使用者空间),与核心空间(英语:Kernel space,又译为内核空间)这两个区块1。
这是存储器保护机制中的一环。
内核、核心扩充(kernel extensions)、以及驱动程序,运行在核心空间上。
而其他的应用程序,则运行在用户空间上。
所有运行在用户空间的应用程序,都被统称为用户级(userland)。
linux中的用户空间与内核空间linux驱动程序一般工作在内核空间,但也可以工作在用户空间。
Linux简化了分段机制,使得虚拟地址与线性地址总是一致,因此,Linux的虚拟地址空间也为0~4G。Linux内核将这4G字节的空间分为两部分:
将最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF),供内核使用,称为“内核空间”;
而将较低的3G字节(从虚拟地址 0x00000000到0xBFFFFFFF),供各个进程使用,称为“用户空间2)。
因为每个进程可以通过系统调用进入内核,因此,Linux内核由系统内的所有进程共享。于是,从具体进程的角度来看,每个进程可以拥有4G字节的虚拟空间。
Linux使用两级保护机制:0级供内核使用,3级供用户程序使用。每个进程有各自的私有用户空间(0~3G),这个空间对系统中的其他进程是不可见的。最高的1GB字节虚拟内核空间则为所有进程以及内核所共享。
内核空间中存放的是内核代码和数据,而进程的用户空间中存放的是用户程序的代码和数据。不管是内核空间还是用户空间,它们都处于虚拟空间中。
虽然内核空间占据了每个虚拟空间中的最高1GB字节,但映射到物理内存却总是从最低地址(0x00000000)开始。对内核空间来说,其地址映射是很简单的线性映射,0xC0000000就是物理地址与线性地址之间的位移量,在Linux代码中就叫做PAGE_OFFSET。
内核空间和用户空间之间如何进行通讯?内核空间和用户空间一般通过系统调用进行通信。
用户模式驱动内核模式驱动的判断及标准用户空间模式的驱动一般通过系统调用来完成对硬件的访问,如通过系统调用将驱动的io空间映射到用户空间等。
因此,主要的判断依据就是系统调用。
内核空间和用户空间上不同太多了,比如用户态的链表和内核链表不一样;用户态用printf,内核态用printk;用户态每个应用程序空间是虚拟的,相对独立的,内核态中却不是独立的,所以编程要非常小心等等。
还有用户态和内核态程序通讯的方法很多,不单单是系统调用,实际上系统调用是个不好的选择,因为需要系统调用号,这个需要统一分配。可以通过ioctl、sysfs、proc等来完成。
本词条内容贡献者为:
李嘉骞 - 博士 - 同济大学