用户态和内核态

1.概念

1)特权级:对于任何操作系统来说,创建一个进程是核心功能。创建进程要做很多工作,会消耗很多物理资源。比如分配物理内存,父子进程拷贝信息,拷贝设置页目录页表等等,这些工作得由特定的进程去做,所以就有了特权级别的概念。最关键的工作必须交给特权级最高的进程去执行,这样可以做到集中管理,减少有限资源的访问和使用冲突。inter x86架构的cpu一共有四个级别,0-3级,0级特权级最高,3级特权级最低

2)用户态:当一个进程在执行用户自己的代码时处于用户态,此时特权级最低,为3

3)内核态:当一个进程进入内核内核空间执行内核代码时处于内核态,此时特权级最高,为0

2.用户态切换到内核态的3种方式

  这3种方式是系统在运行时由用户态转到内核态的最主要方式,其中系统调用可以认为是用户进程主动发起的,异常和外围设备中断则是被动的。

2.1系统调用

1)在计算机中,系统调用(system call,syscall),又称为系统呼叫,指用户态程序向操作系统内核请求需要更高权限运行的服务。系统调用提供了用户程序与内核交互之间的一组接口,用户态进程通过这些接口申请使用内核提供的服务程序来完成工作

2)访问系统调用,用户态程序使用C库函数传入系统调用号中断(linux的int 80h中断),于是进程进入内核态,内核中的中断处理函数根据系统调用号,调用对应的内核函数

2.2异常

  当CPU在执行运行在用户态下的程序时,发生了某些事先不可知的异常,这时会触发由当前运行进程切换到处理此异常的内核相关程序中,也就转到了内核态,比如缺页异常。

2.3外围设备的中断

  当外围设备完成用户请求的操作后,会向CPU发出相应的中断信号,这时CPU会暂停执行下一条即将要执行的指令转而去执行与中断信号对应的处理程序,如果先前执行的指令是用户态下的程序,那么这个转换的过程自然也就发生了由用户态到内核态的切换。比如硬盘读写操作完成,系统会切换到硬盘读写的中断处理程序中执行后续操作等。

3.内核层与用户层通信的方法

3.1系统调用

  见上

3.2虚拟文件系统

1)虚拟文件系统并不实际存储在硬盘上,而是linux内核运行起来后才建立起来

2)procfs:是一种虚拟文件系统,挂载在/proc下,内核通过文件的形式将内核内部信息导出到文件上,procfs文件主要用于导出只读信息

3)sysctl:也是一种虚拟文件系统,procfs用于导出只读信息,而sysctl导出的信息是可写的(root用户才可写,ubuntu下/etc/sysctl.conf)

4)debugs:是一种用于内核调试的虚拟文件系统,内核开发者通过debugfs和用户空间交换数据

3.3ioctl接口

3.4netlink套接口

1)netlink是一种特殊的socket,是一种在内核与用户应用间进行双向数据传输的非常强大的方式

2)netlink支持全双工(允许数据在两个方向同时传输)、异步通信(同步也支持),在内核与用户态应用之间传递的消息保存在socket缓存队列中,如:发送消息只是把消息保存在接收者的socket的接收队列,而不需要等待接收者收到消息,系统调用与 ioctl 是同步通信机制

3)netlink 支持多播,内核模块或应用可以把消息多播给一个netlink组,属于该neilink 组的任何内核模块或应用都能接收到该消息,内核事件向用户态的通知机制就使用了这一特性

4)用户层使用netlink时直接调用标准的 socket API,因此很容易使用

5)内核层也可以使用 netlink 首先发起会话,而系统调用和 ioctl 只能由用户层发起调用

6)netlink 的内核部分可以采用模块的方式实现,使用 netlink 的应用部分和内核部分都没有编译时依赖,但系统调用就有依赖,而且新的系统调用的实现必须静态地连接到内核中,它无法在模块中实现,使用系统调用需要重新编译内核

原文地址:https://www.cnblogs.com/Joezzz/p/10442160.html