http://www.cnblogs.com/bakari/p/5520860.html

内核从本质上看是一种软件——控制计算机的硬件资源,并提供上层应用程序运行的环境。

系统调用是操作系统的最小功能单位,这些系统调用根据不同的应用场景可以进行扩展和裁剪,现在各种版本的Unix实现都提供了不同数量的系统调用,如Linux的不同版本提供了240-260个系统调用,FreeBSD大约提供了320个(reference:UNIX环境高级编程)。

Intel的X86架构的CPU提供了0到3四个特权级,数字越小,特权越高,Linux操作系统中主要采用了0和3两个特权级,分别对应的就是内核态和用户态。

一些操作需要在内核权限下才能执行,这就涉及到一个从用户态切换到内核态的过程。比如C函数库中的内存分配函数malloc(),它具体是使用sbrk()系统调用来分配内存,当malloc调用sbrk()的时候就涉及一次从用户态到内核态的切换,类似的函数还有printf(),调用的是wirte()系统调用来输出字符串,等等。

在什么情况下会发生从用户态到内核态的切换,一般存在以下三种情况:

1)当然就是系统调用:原因如上的分析。

2)异常事件: 当CPU正在执行运行在用户态的程序时,突然发生某些预先不可知的异常事件,这个时候就会触发从当前用户态执行的进程转向内核态执行相关的异常事件,典型的如缺页异常。

3)外围设备的中断:当外围设备完成用户的请求操作后,会像CPU发出中断信号,此时,CPU就会暂停执行下一条即将要执行的指令,转而去执行中断信号对应的处理程序,如果先前执行的指令是在用户态下,则自然就发生从用户态到内核态的转换。

  注意:系统调用的本质其实也是中断,相对于外围设备的硬中断,这种中断称为软中断,这是操作系统为用户特别开放的一种中断,如Linux int 80h中断。所以,从触发方式和效果上来看,这三种切换方式是完全一样的,都相当于是执行了一个中断响应的过程。但是从触发的对象来看,系统调用是进程主动请求切换的,而异常和硬中断则是被动的。

(注:补充一下:Linux进程空间,也分成内核空间和用户空间,执行内核空间中的内容要在内核态)

内核与用户态的通信

http://www.cnblogs.com/gaiwen/articles/3002774.html

在一台运行 Linux 的计算机中,CPU 在任何时候只会有如下四种状态:

【1】 在处理一个硬中断。

【2】 在处理一个软中断,如 softirq、tasklet 和 bh。(softirq、tasklet和workqueue,貌似都是bh, bottom-half的机制,tasklet可以说是一种扩展,支持更多的软中断)

【3】 运行于内核态,但有进程上下文,即与一个进程相关。

【4】 运行一个用户态进程。

Unix的两大分支AT&T Unix和BSD Unix在进程通信实现机制上的各有所不同,前者形成了运行在单个计算机上的System V IPC,后者则实现了基于socket的进程间通信机制。

同时Linux也遵循IEEE制定的Posix IPC标准,在三者的基础之上实现了以下几种主要的IPC机制:管道(Pipe)及命名管道(Named Pipe),信号(Signal),消息队列(Message queue),共享内存(Shared Memory),信号量(Semaphore),套接字(Socket)。

为了完成内核空间与用户空间通信,Linux提供了基于socket的Netlink通信机制,可以实现内核与用户空间数据的及时交换。

到目前Linux提供了9种机制完成内核与用户空间的数据交换,分别是内核启动参数、模块参数与 sysfs、sysctl、系统调用、netlink、procfs、seq_file、debugfs和relayfs,

其中模块参数与sysfs、procfs、debugfs、relayfs是基于文件系统的通信机制,用于内核空间向用户控件输出信息;

sysctl、系统调用是由用户空间发起的通信机制。由此可见,以上均为单工通信机制,在内核空间与用户空间的双向互动数据交换上略显不足。

Netlink是基于socket的通信机制,由于socket本身的双共性、突发性、不阻塞特点,因此能够很好的满足内核与用户空间小量数据的及时交互,因此在Linux 2.6内核中广泛使用,例如SELinux,Linux系统的防火墙分为内核态的netfilter和用户态的iptables,netfilter与iptables的数据交换就是通过Netlink机制完成。

2 各种通信方式

本节说明各种通信方式是否适合内核空间和用户空间信息交互,以及如何使用。

2.1 信号

在进程中使用函数signal()或sigaction()安装信号时指定了关联的函数。在内核空间相进程发送信号,从内核空间返回进程空间时检查并执行相应的关联函数。

在进程中可以使用pause()函数进入睡眠,在有信号产生并执行了相应的关联函数后进程被唤醒,继续执行。可以使用这种方式实现内核空间和用户空间的同步。

pause()会使当前进程挂起,直到捕捉到一个信号,对指定为忽略的信号,pause()不会返回。只有执行了一个信号处理函数,并从其返回,pause()才返回-1,并将errno设为EINTR。

2.2 信号量

虽然原理一样,但内核空间和用户空间的信号量是完全两套系统,所以信号量不能用于内核空间和用户空间信息交互。

2.3 无名管道

无名管道只适用于有关系的进程之间通信。不能用于内核空间和用户空间信息交互。

2.4 get_user()/put_user()
2.5 copy_from_user()/copy_to_user()
都可以,略

2.6 共享内存(mmap)

使用mmap()函数通常映射一个普通文件实现进程之间内存共享,即多个进程打开同一个文件,将文件映射到各自进程的虚拟空间。这样各个进程就可以通过共享的内存进行大量的数据交互,当然需要我们自己设计互斥功能。

还可以使用mmap()函数实现内核空间和用户空间内存共享的功能。网上提到的方法基本都是proc文件+mmap。

大体过程如下

1、在模块中申请一些内存页面,作为共享的内存空间。

2、创建可读的proc文件,在其读函数中把上面申请的内存空间的物理地址返回给进程空间。

3、在进程空间open /dev/mem文件,并把从proc读取的物理地址(要共享的内存的物理地址)作为文件/dev/mem的offset,以此offset 把/dev/mem文件的若干空间用mmap映射到进程空间。

注意:

1、/dev/mem 不是一个普通的文件里面的内容是所有物理内存的内容信息。所以,在上面的过程中把共享空间的物理地址作为offset使用。

2、proc文件的作用就是提供一个读取的函数,把共享内存的地址从内核空间传递到用户空间。也可以用设备的ioctl 把该物理地址数值传给用户空间。

经典的内核与用户空间的通信(使用read和write系统调用)

1. 用户空间需要将某些数据传递给内核,并指定数据的处理函数。

2. 用户空间需要从内核读取数据,并指定数据的读取函数。

后面比较难懂了,略。

Linux内核态用户态相关知识 & 相互通信的更多相关文章

  1. linux 内核与用户空间通信机制netlink初探

      1.Linux进程概述 Linux中的进程间通信机制源自于Unix平台上的进程通信机制.Unix的两大分支AT&T Unix和BSD Unix在进程通信实现机制上各有所不同,前者形成了运行 ...

  2. linux 内核与用户空间通信之netlink使用方法

    转自:http://blog.csdn.net/haomcu/article/details/7371835 Linux中的进程间通信机制源自于Unix平台上的进程通信机制.Unix的两大分支AT&a ...

  3. Linux内核和用户空间通信之netlink

    1. netlink Netlink套接字是用以实现用户进程与内核进程通信的一种特殊的进程间通信(IPC) ,也是网络应用程序与内核通信的最常用的接口. Netlink 是一种特殊的 socket,它 ...

  4. linux内核(一)基础知识

    1,linux内核的基础知识 1.1 linux内核版本 从内核源码顶层目录Makefile中可以看到: VERSION和PATCHLEVEL组成主版本号,比如2.4.2.5.2.6等,稳定版本的德主 ...

  5. linux 创建守护进程的相关知识

    linux 创建守护进程的相关知识 http://www.114390.com/article/46410.htm linux 创建守护进程的相关知识,这篇文章主要介绍了linux 创建守护进程的相关 ...

  6. 资源限制 ( resource limit 或 rlimit ),是 Linux 内核控制 用户 或 进程 资源占用的机制。

    ###### https://learn-linux.readthedocs.io/zh_CN/latest/administration/kernel/rlimit.html ########### ...

  7. Linux 内核参数 和 Oracle相关参数调整

    Linux 内核参数 和 Oracle相关参数调整 分类: Oracle Basic Knowledge2009-10-14 12:23 9648人阅读 评论(0) 收藏 举报 oraclelinux ...

  8. Linux探秘之用户态与内核态

    一. Unix/Linux的体系架构 如上图所示,从宏观上来看,Linux操作系统的体系架构分为用户态和内核态(或者用户空间和内核).内核从本质上看是一种软件——控制计算机的硬件资源,并提供上层应用程 ...

  9. 【Linux 系统】Linux探秘之用户态与内核态

    一. Unix/Linux的体系架构 如上图所示,从宏观上来看,Linux操作系统的体系架构分为用户态和内核态(或者用户空间和内核).内核从本质上看是一种软件——控制计算机的硬件资源,并提供上层应用程 ...

随机推荐

  1. csharp C#数字字符串排序orderby的问题解决

    一般情况下 您使用 strs.OrderBy(n=>n) 得出的结论是 1, 11,111,2,22,222想要得出 1,2,11,22,111,222 咋办?源码送上 static void ...

  2. find ctime 加减n时间范围

    看下atime的时间解释:-atime n File was last accessed n*24 hours ago. When find figures out how many 24-hour ...

  3. win10 Faster-RCNN训练自己数据集遇到的问题集锦 (转)

    题注: 在win10下训练实在是有太多坑了,在此感谢网上的前辈和大神,虽然有的还会把你引向另一个坑~~. 最近,用faster rcnn跑一些自己的数据,数据集为某遥感图像数据集——RSOD,标注格式 ...

  4. Android中的AlarmManager的使用

    AlarmManager是Android中的一种系统级别的提醒服务,它会为我们在特定的时刻广播一个指定的Intent.而使用Intent的时候,我们还需要它执行一个动作,如startActivity, ...

  5. AssetManager

    AssetManager用于获取assets下的资源. 1.getassets()得到AssetManager 2.AssetManager.close() 关闭AssetManager 3.Reso ...

  6. vs启动出错(chenlu-1):参数“basePath”不能是相对路径

    参数“basePath”不能是相对路径 原因: 1.调试路径下没有exe文件.没有生成exe文件. 2.项目属性->配置属性->调试->命令中的参数被设置为相对路径.

  7. RxAndroid防止内存泄露

    RxJava并不会自动防止这种情况发生,好在它可以很容易地防止内存泄露.Observable.subscribe()方法会返回一个Subscription对象,这个对象仅仅有两个方法:isSbscri ...

  8. Spring的Log4J配置器Log4jWebConfigurer介绍

    1. Logj4简介 Log4j是Apache大旗下的一个子项目,它可以用来重定向应用日志文件的输出流,无论我们想将日志文件输出到控制台还是网络还是其他地方,都可以通过logj4来配置,如果我们的应用 ...

  9. Cookiecutter: 更好的项目模板工具:(2)安装及基础使用

    安装 通过python包管理工具 命令行输入 $pip install cookiecutter 或者 # mac os经常会禁止用户全局安装python包 $pip install --user c ...

  10. Python __all__变量用法

    Python中一个py文件就是一个模块,“__all__”变量是一个特殊的变量,可以在py文件中,也可以在包的__init__.py中出现. 1.在普通模块中使用时,表示一个模块中允许哪些属性可以被导 ...