我们知道每种cpu都有所属的指令集架构,指令集与硬件架构息息相关,这块知识展开又如海洋般浩瀚,自然不是我的能力所及,仅将指令集抽象类理解为软件控制硬件的媒介。本文一切就由指令集这一软硬件分界说起。
1. cpu指令集权限
硬件设备商直接提供了硬件级别的支持,将cpu指令集
设置权限分级,不同级别能使用的指令集是有限的,以Intel CPU为例,Intel将指令集由高到低分为:
- ring 0
- ring 1
- ring 2
- ring 3
其中 ring 0 可以使用所有指令集,ring 3 只能使用长阔指令集,不能使用操作硬件资源的指令,比如 IO 读写,网卡访问,内存申请都不行,Linux系统仅采用 ring 0 和 ring 3 这两个权限
2. 内核态与用户态
高情商:
- ring 0 被叫做内核态,完全在操作系统内核中执行
- ring 3 被叫做用户态,在应用程序中运行
低情商 - 执行内核空间的代码,具有ring 0保护级别,有对硬件的所有操作权限,可以执行所有
cpu指令集
,访问任意地址的内存,在内核模式下的任何异常都是灾难性的,将会导致整台机器停机。 - 在用户模式下,具有ring 3保护级别,代码没有对硬件的直接控制权限,也不能直接访问地址的内存,程序是通过调用系统接口(System Call APIs)来达到访问硬件和内存,在这种保护模式下,即使程序发生崩溃也是可以恢复的,大多数程序运行于用户模式。
3. 用户态和内核态的空间
每个进程都有两个栈,分别是用户栈和内核栈, 对应用户态和内核态的使用
以linux32位操作系用为例,它的寻址空间是4G,每个进程会分配4G的虚拟空间地址,操作系统会把高位 1G划为内核空间,仅由内核访问, 低位 3G为用户空间,由用户和内核共享,所有进程的内核空间是共享的。
4. 内核态与用户态的切换
三种情况会导致切换:
- 系统调用(int 80h)
- 异常
- 中断
5. 内核态与用户态的通信
- procfs(/proc) 是进程文件系统的缩写,完全位于内存之中,通常挂载与/proc目录下。内核通过这个目录以文件的形式展现自己的内部信息,这些文件具有不同的读写权限,是用户态和内核态间交互的一个桥梁。
- sysfs(/sys) Linux 2.6才引入的一种虚拟文件系统,类似procfs, 区别在于sysfs是将一些原本在procfs中的关于设备和驱动的部分独立出来,以设备树的形式呈现给用户,不仅可以从内核空间读取设备和驱动程序的信息,也可以对设备和驱动进行配置。
- sysctl, 一个linux命令,本质上通过修改/proc/sys目录进行用户态和内核态的通信,支持使用/etc/sysctl.conf进行批量修改
- netlink 是linux用户态和内核态通信最常用的一种方式。 本质上是一种socket。