在32位操作系统下,虚拟地址空间为4G,也就是说一个进程的最大的地址空间为4G。操作系统的核心是内核,它独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。为了保证内核的安全,现在的操作系统一般都强制用户进程不能直接操作内核。具体的实现方式基本都是由操作系统将虚拟地址空间划分为两部分,一部分为内核空间,另一部分为用户空间。对Linux操作系统而言,最高的 1G字节由内核使用。低3G字节由各个进程使用。
换句话说,最高1G内核空间是被所有进程共享,剩余3G才归进程自己使用。
区分内核空间与用户空间的意义
CPU的所有指令中,有些指令是非常危险的,如果错用,将导致系统崩溃,比如清内存、设置时钟等。如果允许所有的程序都可以使用这些指令,那么系统崩溃的概率将大大增加。所以,CPU将指令分为特权指令和非特权指令,对于那些危险的指令,只允许操作系统及其相关模块使用,普通应用程序只能使用那些不会造成灾难的指令。
内核态与用户态
Linux系统只使用了Ring0和Ring3两个运行级别。当进程运行在 Ring3 级别时被称为运行在用户态,而运行在 Ring0 级别时被称为运行在内核态。运行在Ring3级别时被称为运行在用户态,运行在Ring0级别时被称为运行在内核态。
在内核态下,进程运行在内核地址空间中,此时 CPU 可以执行任何指令。运行的代码也不受任何的限制,可以自由地访问任何有效地址,也可以直接进行端口的访问。
在用户态下,进程运行在用户地址空间中,被执行的代码要受到CPU的检查,它们只能访问映射其地址空间的页表项中规定的在用户态下可访问页面的虚拟地址,且只能对任务状态段中I/O许可位图中规定的可访问端口进行直接访问。
我们可以将每个处理器在任何指定时间点上的活动概括为下列三者之一:
- 运行于用户空间,执行用户进程。
- 运行于内核空间,处于进程上下文,代表某个特定的进程执行。
- 运行于内核空间,处于中断上下文(保证中断服务程序能够在第一时间响应和处理中断请求,然后快速地退出),与任何进程无关,处理某个特定的中断。
用户态到内核态的转换概况来说有三种方式分别为系统调用、软中断和硬件中断。
Linux系统结构图
从内核空间和用户空间的角度看整个Linux系统的结构,从下往上依次为:硬件 -> 内核空间 -> 用户空间