用户空间与内核通信(二)

在这里插入图片描述

文章:用户空间与内核通信(一)介绍了系统调用(System Call),内核模块参数和sysfs,sysctl函数方式进行用户空间和内核空间的访问。本章节我将介绍使用netlink套接字和proc文件系统实现用户空间对内核空间的访问。

netlink套接字

netlink是一种基于socket的通信机制,用于在用户空间与内核空间之间进行小量数据的及时交互。netlink套接字允许用户空间程序与内核空间程序建立连接,并通过发送和接收消息来进行通信。

内核模块:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netlink.h>
#include <net/netlink.h>#define NETLINK_USER 31
#define MSG_LEN 1024struct sock *nl_sock = NULL;// 接收用户空间消息的回调函数
static void nl_recv_msg(struct sk_buff *skb) {struct nlmsghdr *nlh;char msg[MSG_LEN];// 从skb中获取消息头nlh = nlmsg_hdr(skb);if (nlh->nlmsg_len >= sizeof(struct nlmsghdr) &&netlink_skb_valid(skb, nlh->nlmsg_len)) {// 拷贝消息数据到msg缓冲区strncpy(msg, NLMSG_DATA(nlh), MSG_LEN);// 打印接收到的消息printk(KERN_INFO "Received message from user space: %s\n", msg);}
}// 模块初始化函数
static int __init init_netlink(void) {// 创建Netlink套接字nl_sock = netlink_kernel_create(&init_net, NETLINK_USER, 0, nl_recv_msg, NULL, THIS_MODULE);if (!nl_sock) {printk(KERN_ERR "Failed to create netlink socket\n");return -1;}printk(KERN_INFO "Netlink socket created\n");return 0;
}// 模块退出函数
static void __exit exit_netlink(void) {if (nl_sock)netlink_kernel_release(nl_sock);printk(KERN_INFO "Netlink socket released\n");
}module_init(init_netlink);
module_exit(exit_netlink);MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");

用户空间应用程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <linux/netlink.h>#define NETLINK_USER 31
#define MSG_LEN 1024int main() {int sockfd;struct sockaddr_nl src_addr, dest_addr;struct nlmsghdr *nlh = NULL;struct iovec iov;struct msghdr msg;sockfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_USER);if (sockfd < 0) {perror("socket");return -1;}memset(&src_addr, 0, sizeof(src_addr));src_addr.nl_family = AF_NETLINK;src_addr.nl_pid = getpid();  // This is the source's port numberbind(sockfd, (struct sockaddr*)&src_addr, sizeof(src_addr));memset(&dest_addr, 0, sizeof(dest_addr));dest_addr.nl_family = AF_NETLINK;dest_addr.nl_pid = 0;  // To kerneldest_addr.nl_groups = 0;nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MSG_LEN));memset(nlh, 0, NLMSG_SPACE(MSG_LEN));nlh->nlmsg_len = NLMSG_SPACE(MSG_LEN);nlh->nlmsg_pid = getpid();nlh->nlmsg_flags = 0;strcpy(NLMSG_DATA(nlh), "Hello from user space");iov.iov_base = (void *)nlh;iov.iov_len = nlh->nlmsg_len;memset(&msg, 0, sizeof(msg));msg.msg_name = (void *)&dest_addr;msg.msg_namelen = sizeof(dest_addr);msg.msg_iov = &iov;msg.msg_iovlen = 1;sendmsg(sockfd, &msg, 0);close(sockfd);free(nlh);return 0;
}

编译内核模块:

make -C /lib/modules/$(uname -r)/build M=$(pwd) modules

加载内核模块:

sudo insmod your_module.ko

编译用户空间程序:

gcc user_program.c -o user_program

运行用户空间程序:

sudo ./user_program

proc文件系统

proc是一个虚拟文件系统,用于导出内核和进程的状态信息。用户空间程序可以通过读取proc文件系统中的文件来获取内核和进程的信息,也可以通过写入proc文件来向内核发送指令或修改配置。

这些机制为用户空间与内核空间之间的通信提供了灵活和多样化的方式,使得用户程序能够与操作系统内核进行交互,获取系统服务并完成各种任务。

下面的示例,演示了如何使用proc文件系统在用户空间和内核空间之间进行通信。在此示例中,我们将创建一个proc文件,并使用它来向内核发送和接收数据。

首先,让我们创建一个名为"proc_example"的内核模块,该模块将在/proc目录下创建一个名为"proc_example"的文件。用户可以通过读取和写入此文件来与内核通信。

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/uaccess.h>#define PROC_ENTRY_NAME "proc_example"
#define BUFFER_SIZE 1024static struct proc_dir_entry *proc_entry;
static char proc_buffer[BUFFER_SIZE];// 读取proc文件的回调函数
static ssize_t proc_read(struct file *file, char __user *buffer, size_t count, loff_t *offset) {ssize_t len = strlen(proc_buffer);if (*offset >= len) {return 0; // 已经读取完毕}if (count > len - *offset) {count = len - *offset; // 如果请求的数据超过了剩余的数据量,则只读取剩余的数据量}if (copy_to_user(buffer, proc_buffer + *offset, count) != 0) {return -EFAULT; // 复制数据失败}*offset += count; // 更新偏移量return count;
}// 写入proc文件的回调函数
static ssize_t proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *offset) {if (count >= BUFFER_SIZE) {return -EINVAL; // 写入的数据过大}if (copy_from_user(proc_buffer, buffer, count) != 0) {return -EFAULT; // 复制数据失败}proc_buffer[count] = '\0'; // 添加字符串结束符return count;
}// 模块初始化函数
static int __init init_proc_example(void) {proc_entry = proc_create(PROC_ENTRY_NAME, 0666, NULL, &proc_fops);if (!proc_entry) {printk(KERN_ERR "Failed to create /proc/%s\n", PROC_ENTRY_NAME);return -ENOMEM;}printk(KERN_INFO "/proc/%s created\n", PROC_ENTRY_NAME);return 0;
}// 模块退出函数
static void __exit exit_proc_example(void) {if (proc_entry) {remove_proc_entry(PROC_ENTRY_NAME, NULL);printk(KERN_INFO "/proc/%s removed\n", PROC_ENTRY_NAME);}
}// 定义proc文件操作结构体
static const struct file_operations proc_fops = {.read = proc_read,.write = proc_write,
};module_init(init_proc_example);
module_exit(exit_proc_example);MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");

编译和加载模块后,你可以在/sys/kernel/debug/proc_example中读取和写入数据。例如,你可以使用cat和echo命令:

$ echo "Hello from user space" > /proc/proc_example
$ cat /proc/proc_example
Hello from user space

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/260555.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.NET Core WebAPI中使用Log4net记录日志

一、安装NuGet包 二、添加配置 // log4net日志builder.Logging.AddLog4Net("CfgFile/log4net.config");三、配置log4net.config文件 <?xml version"1.0" encoding"utf-8"?> <log4net><!-- Define some output appenders -->…

机器学习8-决策树

决策树&#xff08;Decision Tree&#xff09;是一种强大且灵活的机器学习算法&#xff0c;可用于分类和回归问题。它通过从数据中学习一系列规则来建立模型&#xff0c;这些规则对输入数据进行递归的分割&#xff0c;直到达到某个终止条件。 决策树的构建过程&#xff1a; 1.…

【知识整理】简述 Code Review - 代码审查

一、Code Review 简述 为保证上线代码质量&#xff0c;经研究决定0412版本起实行Code Review 。具体操作方式为组织 review 会。提出的优化点需立即执行更改&#xff0c;Review会要求给出调整方式方法。同时为了确保项目或迭代版本的时间&#xff0c;请各开发同学提前做好时间…

Linux系统安全:安全技术和防火墙

目录 一、安全技术和防火墙 1.安全技术 2.防火墙的分类 二、防火墙 1.iptables四表五链 2.黑白名单 3.iptables基本语法 4.iptables选项 5.控制类型 6.隐藏扩展模块 7.显示扩展模块 8.iptables规则保存 9.自定义链使用 一、安全技术和防火墙 1.安全技术 入侵检测系…

【PyQt】12-滑块、计数控件

文章目录 前言一、滑块控件 QSlider运行结果 二、计数器控件 QSpinBox运行结果 总结 前言 1、滑块控件 2、计数控件 一、滑块控件 QSlider #Author &#xff1a;susocool #Creattime:2024/2/15 #FileName:28-滑块控件 #Description: 通过滑块选择字体大小 import sys from PyQ…

【JavaEE】_HTTP请求首行

目录 1. URL 2. 方法 2.1 GET方法 2.2 POST方法 2.3 GET与POST的区别 2.4 低频使用方法 1. URL 在mysql JDBC中已经提到过URL的相关概念&#xff1a; 如需查看有关JDBC更多内容&#xff0c;原文链接如下&#xff1a; 【MySQL】_JDBC编程-CSDN博客 URL用于描述某个资源…

移动通信相关知识学习笔记

一、移动通信架构简图 移动无线的接入网是专指各种基站设备。核心网就是各种交换机。 二、无线信号基本原理 无线网络中&#xff0c;使用AP设备和天线来实现有线和无线信号互相转换。如上图所示&#xff0c;有线网络侧的数据从AP设备的有线接口进入AP后&#xff0c;经AP处理为…

代码随想录算法训练营第十八天|235.二叉搜索树的最近公共祖先,701.二叉搜索树中的插入操作,450.删除二叉搜索树节点

235.二叉搜索树的最近公共祖先 701.二叉搜索树中的插入操作 450.删除二叉搜索树节点 235.二叉搜索树的最近公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个结点 p、q&#xff0c;最近…

基于shp数据制作3DTiles建筑白膜

经纬管网建模系统MagicPipe3D&#xff0c;本地离线参数化构建地下管网、建筑三维模型&#xff0c;输出标准3DTiles服务、Obj模型等格式&#xff0c;支持Cesium、Unreal、Unity、Osg等引擎加载进行三维可视化、语义查询、专题分析。欢迎下载试用&#xff1a;http://www.magic3d.…

Spring Boot 笔记 023 注册页面

1.1 request.js请求工具 //定制请求的实例//导入axios npm install axios import axios from axios; //定义一个变量,记录公共的前缀 , baseURL const baseURL /api; const instance axios.create({baseURL})//添加响应拦截器 instance.interceptors.response.use(result…

npm ERR! code CERT_HAS_EXPIRED:解决证书过期问题

转载&#xff1a;npm ERR! code CERT_HAS_EXPIRED&#xff1a;解决证书过期问题_npm err! code cert_has_expired npm err! errno cert-CSDN博客 npm config set registry http://registry.cnpmjs.org npm config set registry http://registry.npm.taobao.org

JVM-JVM中对象的结构

对象内存布局 对象里的三个区&#xff1a; 对象头&#xff08;Header&#xff09;&#xff1a;Java对象头占8byte。如果是数组则占12byte。因为JVM里数组size需要使用4byte存储。 标记字段MarkWord&#xff1a; 用于存储对象自身的运行时数据&#xff0c;它是synchronized实现轻…

内核移植学习

内核移植 内核移植就是指将RT-Thread内核在不同的芯片架构、不同的板卡上运行起来。 移植可分为CPU架构移植和BSP板级支持包移植两部分。 CPU架构移植 在嵌入式领域有多种不同CPU架构&#xff0c;例如Cortex-M、ARM920T、MIPS32、RISC-V等等。 为了使RT-Thread能够在不同C…

最新 Vue3、TypeScript、组合式API、setup语法糖 学习笔记

最新 Vue3、TypeScript、组合式API、setup语法糖 学习笔记 1、创建 Vue3 工程基于 `vue-cli` 创建(基于webpack实现)基于 `vite` 创建(推荐)2、Vue3 项目开发 `vscode` 插件推荐3、`Vue3` 核心语法【optionsAPI】与【CompositionAPI】Options API 的弊端Composition API 的…

提取游戏音频文件.bnk

提取游戏音频文件.bnk 什么是.bnk准备Wwise-Unpacker工具使用Wwise-Unpacker工具总结 什么是.bnk .bnk其实是一种对音频的加密方式&#xff0c;一个.bnk文件中通常包含了多个语音文件&#xff0c;一般可以使用Wwise-Unpacker来解码.bnk格式文件 准备Wwise-Unpacker工具 Wwis…

《Go 简易速速上手小册》第7章:包管理与模块(2024 最新版)

文章目录 7.1 使用 Go Modules 管理依赖 - 掌舵向未来7.1.1 基础知识讲解7.1.2 重点案例&#xff1a;Web 服务功能描述实现步骤扩展功能 7.1.3 拓展案例 1&#xff1a;使用数据库功能描述实现步骤扩展功能 7.1.4 拓展案例 2&#xff1a;集成 Redis 缓存功能描述实现步骤扩展功能…

OpenAI 发布文生视频大模型 Sora,AI 视频要变天了,视频创作重新洗牌!AGI 还远吗?

一、一觉醒来&#xff0c;AI 视频已变天 早上一觉醒来&#xff0c;群里和朋友圈又被刷屏了。 今年开年 AI 界最大的震撼事件&#xff1a;OpenAI 发布了他们的文生视频大模型 Sora。 OpenAI 文生视频大模型 Sora 的横空出世&#xff0c;预示着 AI 视频要变天了&#xff0c;视…

python 笔记:shapely(形状篇)

主要是点&#xff08;point&#xff09;、线&#xff08;linestring&#xff09;、面&#xff08;surface&#xff09; 1 基本方法和属性 object.area 返回对象的面积&#xff08;浮点数&#xff09; object.bounds 返回一个&#xff08;minx, miny, maxx, maxy&#xff09;元…

MySQL - 增量同步和全量同步

增量同步和全量同步是数据同步过程中常用的两种方式&#xff0c;它们在定义、区别以及适用场景上有一些明显的差异。 一、定义 增量同步是指在数据同步中仅同步更新或新增的数据&#xff0c;而不包括已经同步过的数据。全量同步则是指将所有数据进行一次完整的同步&#xff0c…

网络原理 - HTTP/HTTPS(3)

HTTP请求 认识请求"报头" header的整体的格式也是"键值对"的结构. 每个键值对占一行,键和值之间使用分号进行分割. 报头的种类有很多,此处仅介绍几个常见的. Host 表示服务器主机的地址和端口.(Host和URL中的ip地址端口啥的,绝大部分情况下都是一样的,少…