本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫。

Linux 用户态和内核态由于 CPU 权限的限制,通信并不像想象中的使用进程间通信方式那么简单,今天这篇文章就来看看 Linux 用户态和内核态究竟有哪些通信方式。

我们平常在写代码时,一般是在用户空间,通过系统调用函数来访问内核空间,这是最常用的一种用户态和内核态通信的方式。(关于 Linux 用户态和内核态可以参考 xx)

除此之外,还有以下四种方式:

  • procfs(/proc)
  • sysctl(/proc/sys)
  • sysfs(/sys)
  • netlink 套接口

procfs(/proc)

procfs进程文件系统 的缩写,它本质上是一个伪文件系统,为什么说是 文件系统呢?因为它不占用外部存储空间,只是占用少量的内存,通常是挂载在 /proc 目录下。

我们在该目录下看到的一个文件,实际上是一个内核变量。内核就是通过这个目录,以文件的形式展现自己的内部信息,相当于 /proc 目录为用户态和内核态之间的交互搭建了一个桥梁,用户态读写 /proc 下的文件,就是读写内核相关的配置参数。

比如常见的 /proc/cpuinfo/proc/meminfo/proc/net 就分别提供了 CPU、内存、网络的相关参数。除此之外,还有很多的参数,如下所示:

  1. root@ubuntu:~# ls /proc/
  2. 1 1143 1345 1447 2 2292 29 331 393 44 63 70 76 acpi diskstats irq locks sched_debug sysvipc zoneinfo
  3. 10 1145 1357 148 20 23 290 332 396 442 64 7019 77 asound dma kallsyms mdstat schedstat thread-self
  4. 1042 1149 1361 149 2084 2425 291 34 398 45 65 7029 8 buddyinfo driver kcore meminfo scsi timer_list
  5. 1044 1150 1363 15 2087 25 3 3455 413 46 66 7079 83 bus execdomains keys misc self timer_stats
  6. 1046 1151 1371 16 2090 256 30 35 418 47 6600 7080 884 cgroups fb key-users modules slabinfo tty
  7. 1048 1153 1372 17 21 26 302 36 419 5 67 71 9 cmdline filesystems kmsg mounts softirqs uptime
  8. 11 1190 1390 18 22 27 31 37 420 518 6749 72 96 consoles fs kpagecgroup mtrr stat version
  9. 1126 12 143 182 2214 28 32 373 421 524 68 73 97 cpuinfo interrupts kpagecount net swaps version_signature
  10. 1137 1252 1434 184 2215 280 327 38 422 525 69 74 98 crypto iomem kpageflags pagetypeinfo sys vmallocinfo
  11. 1141 13 144 190 2262 281 33 39 425 5940 7 75 985 devices ioports loadavg partitions sysrq-trigger vmstat

可以看到,这里面有很多的数字表示的文件,这些其实是当前系统运行的进程文件,数字表示进程号(PID),每个文件包含该进程所有的配置信息,包括进程状态、文件描述符、内存映射等等,我们可以看下:

  1. root@ubuntu:~# ls /proc/1/
  2. attr/ cmdline environ io mem ns/ pagemap schedstat stat timers
  3. autogroup comm exe limits mountinfo numa_maps personality sessionid statm uid_map
  4. auxv coredump_filter fd/ loginuid mounts oom_adj projid_map setgroups status wchan
  5. cgroup cpuset fdinfo/ map_files/ mountstats oom_score root/ smaps syscall
  6. clear_refs cwd/ gid_map maps net/ oom_score_adj sched stack task/

综上,内核通过一个个的文件来暴露自己的系统配置信息,这些文件,有些是只读的,有些是可写的,有些是动态变化的,比如进程文件,当应用程序读取某个 /proc/ 文件时,内核才会去注册这个文件,然后再调用一组内核函数来处理,将相应的内核参数拷贝到用户态空间,这样用户读这个文件就可以获取到内核的信息。一个大概的图示如下所示:

sysctl

我们熟悉的 sysctl 是一个 Linux 命令,man sysctl 可以看到它的功能和用法。它主要是被用来修改内核的运行时参数,换句话说,它可以在内核运行过程中,动态修改内核参数。

它本质上还是用到了文件的读写操作,来完成用户态和内核态的通信。它使用的是 /proc 的一个子目录 /proc/sys。和 procfs 的区别在于:

procfs 主要是输出只读数据,而 sysctl 输出的大部分信息是可写的。

例如,我们比较常见的是通过 cat /proc/sys/net/ipv4/ip_forward 来获取内核网络层是否允许转发 IP 数据包,通过 echo 1 > /proc/sys/net/ipv4/ip_forward 或者 sysctl -w net.ipv4.ip_forward=1 来设置内核网络层允许转发 IP 数据包。

同样的操作,Linux 也提供了文件 /etc/sysctl.conf 来让你进行批量修改。

sysfs

sysfs 是 Linux 2.6 才引入的一种虚拟文件系统,它的做法也是通过文件 /sys 来完成用户态和内核的通信。和 procfs 不同的是,sysfs 是将一些原本在 procfs 中的,关于设备和驱动的部分,独立出来,以 “设备树” 的形式呈现给用户。

sysfs 不仅可以从内核空间读取设备和驱动程序的信息,也可以对设备和驱动进行配置。

我们看下 /sys 下有什么:

  1. # ls /sys
  2. block bus class dev devices firmware fs hypervisor kernel module power

可以看到这些文件基本上都跟计算机的设备和驱动等息息相关的。更多关于这些文件的解释大家可以自行了解,这里就不过多展开了。

netlink

netlink 是 Linux 用户态与内核态通信最常用的一种方式。Linux kernel 2.6.14 版本才开始支持。它本质上是一种 socket,常规 socket 使用的标准 API,在它身上同样适用。比如创建一个 netlink socket,可以调用如下的 socket 函数:

  1. #include <asm/types.h>
  2. #include <sys/socket.h>
  3. #include <linux/netlink.h>
  4. netlink_socket = socket(AF_NETLINK, socket_type, netlink_family);

netlink 这种灵活的方式,使得它可以用于内核与多种用户进程之间的消息传递系统,比如路由子系统,防火墙(Netfilter),ipsec 安全策略等等。

引申:

net-tools 工具通过 procfs(/proc) 和 ioctl 系统调用去访问和改变内核网络参数配置,而 iproute2 则通过 netlink 套接字接口与内核通信,前者已经被淘汰了,后者逐步成为标准。

总结

Linux 用户态和内核态通信主要的四种方式,其中 netlink 和 procfs 是最常见的方式。


后台回复“加群”,带你进入高手如云交流群

我的公众号 「Linux云计算网络」(id: cloud_dev) ,号内有 10T 书籍和视频资源,后台回复 「1024」 即可领取,分享的内容包括但不限于 Linux、网络、云计算虚拟化、容器Docker、OpenStack、Kubernetes、工具、SDN、OVS、DPDK、Go、Python、C/C++编程技术等内容,欢迎大家关注。

参考:

https://www.ibm.com/developerworks/cn/linux/l-kerns-usrs/index.html

https://fasionchan.com/blog/2017/06/16/procfs-wei-wen-jian-xi-tong-yuan-li/

https://zh.wikipedia.org/wiki/Netlink

Linux用户态与内核态通信的几种方式的更多相关文章

  1. linux用户态和内核态通信之netlink机制【转】

    本文转载自:http://blog.csdn.net/zcabcd123/article/details/8272360 这是一篇学习笔记,主要是对<Linux 系统内核空间与用户空间通信的实现 ...

  2. Linux 用户态与内核态的交互【转载】

    Linux 用户态与内核态的交互  在 Linux 2.4 版以后版本的内核中,几乎全部的中断过程与用户态进程的通信都是使用 netlink 套接字实现的,例如iprote2网络管理工具,它与内核的交 ...

  3. Linux用户态和内核态

    究竟什么是用户态,什么是内核态,这两个基本概念以前一直理解得不是很清楚,根本原因个人觉得是在于因为大部分时候我们在写程序时关注的重点和着眼的角度放在了实现的功能和代码的逻辑性上,先看一个例子: 1)例 ...

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

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

  5. Linux 用户态和内核态

    1.特权级特权级用来管理和控制程序执行.如Intel x86架构的CPU,有0~3四个特权级,0级最高,3级最低.硬件在执行每条指令时都会检查指令具有的特权级.硬件提供了特权级使用机制,对操作系统来说 ...

  6. 【转载】 Linux用户态和内核态

    [说明]转载自 http://my.oschina.net/liubin/blog/27795 究竟什么是用户态,什么是内核态,这两个基本概念以前一直理解得不是很清楚,根本原因个人觉得是在于因为大部分 ...

  7. Linux操作系统学习_用户态与内核态之切换过程

    因为操作系统的很多操作会消耗系统的物理资源,例如创建一个新进程时,要做很多底层的细致工作,如分配物理内存,从父进程拷贝相关信息,拷贝设置页目录.页表等,这些操作显然不能随便让任何程序都可以做,于是就产 ...

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

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

  9. (转)linux用户态和内核态理解

    原文:https://blog.csdn.net/buptapple/article/details/21454167 Linux探秘之用户态与内核态-----------https://www.cn ...

随机推荐

  1. day47_9_6(前端之js)

    一.js发展. 1996年11月,JavaScript的创造者--Netscape公司,决定将JavaScript提交给国际标准化组织ECMA,希望这门语言能够成为国际标准.次年,ECMA发布262号 ...

  2. MySQL学习笔记4——DQL

    DQL(数据查询语言) 一.基本查询 1.字段(列)控制1)查询所有列SELECT * FROM 表名; ->"*"表示查询所有列 2)查询指定列SELECT 列1 [, 列 ...

  3. 对比3种接口测试的工具:jmeter+ant;postman;python的requests+unittest或requests+excel

    这篇随笔主要是对比下笔者接触过的3种接口测试工具,从实际使用的角度来分析下3种工具各自的特点 分别为:jmeter.postman.python的requests+unittest或requests+ ...

  4. 【ECNU3542】神奇的魔术(二分交互题)

    点此看题面 大致题意: 有一个\(1\sim 2^n\)的排列,\(n\le7\),每次交互告诉你有几个位置上的数是正确的,让你在\(1000\)轮以内猜出每个位置上的数. 二分 显然,我们可以通过二 ...

  5. usb设备在sysfs中的命名规范

    "root-hub的编号"-"设备(或者hub)插入的端口号"[."设备(或者hub)插入的端口号"]:"USB设备配置号&quo ...

  6. 全面理解UE4委托

    UE4中的delegate(委托)常用于解耦不同对象之间的关联:委托的触发者不与监听者有直接关联,两者通过委托对象间接地建立联系 监听者通过将响应函数绑定到委托上,使得委托触发时立即收到通知,并进行相 ...

  7. netstat查看端口状态

    netstat netstat -tunlp 用于显示 tcp,udp 的端口和进程等相关情况. netstat 查看端口占用语法格式: netstat -tunlp | grep 端口号 -t (t ...

  8. 四、Srping之Bean的初始化和销毁

    Srping之Bean的初始化和销毁方法 通常,bean的初始化和销毁方法我们有三个地方可以入手,分别是: 自定义初始化,销毁方法 实现spring提供的InitializingBean(初始化逻辑) ...

  9. jQuery 源码分析(五) map函数 $.map和$.fn.map函数 详解

    $.map() 函数用于使用指定函数处理数组中的每个元素(或对象的每个属性),并将处理结果封装为新的数组返回,该函数有三个参数,如下: elems Array/Object类型 指定的需要处理的数组或 ...

  10. JVM的监控工具之jinfo

    参考博客:https://www.jianshu.com/p/8d8aef212b25 jinfo(ConfigurationInfoforJava)的作用是实时地查看和调整虚拟机各项参数,使用jps ...