当前位置: 首页 > news >正文

Android内核之Binder读写通信:binder_ioctl_write_read用法实例(七十)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀
优质专栏:多媒体系统工程师系列原创干货持续更新中……】🚀
优质视频课程:AAOS车载系统+AOSP14系统攻城狮入门实战课原创干货持续更新中……】🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

🍉🍉🍉文章目录🍉🍉🍉

    • 🌻1.前言
    • 🌻2.Android内核之binder_ioctl_write_read介绍
    • 🌻3.代码实例
      • 🐓3.1 发送Binder消息
      • 🐓3.2 接收Binder消息
      • 🐓3.3 Binder事件通知

🌻1.前言

本篇目的:Android内核之IPC通信:binder_ioctl_write_read用法实例

🌻2.Android内核之binder_ioctl_write_read介绍

  • binder_ioctl_write_read是Android系统中Binder驱动的关键函数之一,用于在用户空间和内核空间之间进行进程间通信(IPC)。Android的Binder机制是一种高效的IPC机制,用于在Android系统中进行进程间通信,特别是在应用程序和系统服务之间。

  • 该函数的主要作用是通过ioctl系统调用在用户空间和内核空间之间传递数据。在Binder中,进程可以通过Binder节点向Binder驱动发送请求消息,而Binder驱动负责将这些消息传递到目标进程。在内核空间中,这些请求消息和响应消息被表示为数据结构,并通过binder_ioctl_write_read函数进行读写。

  • 具体而言,binder_ioctl_write_read函数的作用包括:

  1. 消息传递: 通过该函数,应用程序可以向Binder驱动发送请求消息,例如调用远程服务的请求或发送数据给其他进程。

  2. 数据交换: 该函数允许应用程序和内核空间之间交换数据,实现进程间通信。数据可以是任何形式的信息,如函数调用、参数、返回值等。

  3. 事件通知: Binder机制还支持事件通知,例如进程间的状态变化或系统服务的可用性。binder_ioctl_write_read函数可以用于发送和接收这些事件通知。

  4. 错误处理: 除了消息传递外,该函数还负责处理可能发生的错误情况。例如,当发送消息失败或接收到无效的消息时,函数会返回相应的错误码,应用程序可以据此进行错误处理。

  • 使用binder_ioctl_write_read函数需要一定的内核编程知识和经验。开发者需要了解Binder驱动的工作原理以及消息传递的机制,同时要熟悉ioctl系统调用的使用方法。在实际开发中,通常会使用高级别的API和框架来进行Binder通信,这些API和框架会封装底层的细节,简化开发过程。

  • binder_ioctl_write_read函数在Android系统中扮演着至关重要的角色,它为应用程序提供了一种强大的IPC机制,支持应用程序之间和应用程序与系统服务之间的通信,促进了Android系统的功能丰富和性能优化。

🌻3.代码实例

🐓3.1 发送Binder消息

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/android/binder.h>#define DEVICE_NAME "binder_example"
#define BINDER_DEV_PATH "/dev/binder_example"static int major_number;
static struct class *binder_class = NULL;
static struct device *binder_device = NULL;// 打开Binder设备
static int binder_open(struct inode *inode, struct file *file) {printk(KERN_INFO "Binder device opened\n");return 0;
}// 释放Binder设备
static int binder_release(struct inode *inode, struct file *file) {printk(KERN_INFO "Binder device closed\n");return 0;
}// 实现Binder设备的ioctl操作
static long binder_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {int ret = 0;struct binder_write_read bwr;switch (cmd) {case BINDER_SEND_MESSAGE:// 发送Binder消息// 在这里构造消息数据,并使用binder_ioctl_write_read发送消息break;default:printk(KERN_ERR "Unknown command\n");ret = -EINVAL;break;}return ret;
}// 初始化Binder设备
static int __init binder_init(void) {// 分配主设备号major_number = register_chrdev(0, DEVICE_NAME, &binder_fops);if (major_number < 0) {printk(KERN_ALERT "Failed to register a major number\n");return major_number;}// 创建设备类binder_class = class_create(THIS_MODULE, DEVICE_NAME);if (IS_ERR(binder_class)) {unregister_chrdev(major_number, DEVICE_NAME);printk(KERN_ALERT "Failed to register device class\n");return PTR_ERR(binder_class);}// 创建设备节点binder_device = device_create(binder_class, NULL, MKDEV(major_number, 0), NULL, DEVICE_NAME);if (IS_ERR(binder_device)) {class_destroy(binder_class);unregister_chrdev(major_number, DEVICE_NAME);printk(KERN_ALERT "Failed to create the device\n");return PTR_ERR(binder_device);}printk(KERN_INFO "Binder module initialized\n");return 0;
}// 卸载Binder设备
static void __exit binder_exit(void) {device_destroy(binder_class, MKDEV(major_number, 0));class_unregister(binder_class);class_destroy(binder_class);unregister_chrdev(major_number, DEVICE_NAME);printk(KERN_INFO "Binder module exit\n");
}module_init(binder_init);
module_exit(binder_exit);
MODULE_LICENSE("GPL");

🐓3.2 接收Binder消息

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/android/binder.h>#define DEVICE_NAME "binder_example"
#define BINDER_DEV_PATH "/dev/binder_example"static int major_number;
static struct class *binder_class = NULL;
static struct device *binder_device = NULL;// 打开Binder设备
static int binder_open(struct inode *inode, struct file *file) {printk(KERN_INFO "Binder device opened\n");return 0;
}// 释放Binder设备
static int binder_release(struct inode *inode, struct file *file) {printk(KERN_INFO "Binder device closed\n");return 0;
}// 实现Binder设备的ioctl操作
static long binder_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {int ret = 0;struct binder_write_read bwr;switch (cmd) {case BINDER_RECEIVE_MESSAGE:// 接收Binder消息// 在这里构造消息数据,并使用binder_ioctl_write_read接收消息break;default:printk(KERN_ERR "Unknown command\n");ret = -EINVAL;break;}return ret;
}// 初始化Binder设备
static int __init binder_init(void) {// 分配主设备号major_number = register_chrdev(0, DEVICE_NAME, &binder_fops);if (major_number < 0) {printk(KERN_ALERT "Failed to register a major number\n");return major_number;}// 创建设备类binder_class = class_create(THIS_MODULE, DEVICE_NAME);if (IS_ERR(binder_class)) {unregister_chrdev(major_number, DEVICE_NAME);printk(KERN_ALERT "Failed to register device class\n");return PTR_ERR(binder_class);}// 创建设备节点binder_device = device_create(binder_class, NULL, MKDEV(major_number, 0), NULL, DEVICE_NAME);if (IS_ERR(binder_device)) {class_destroy(binder_class);unregister_chrdev(major_number, DEVICE_NAME);printk(KERN_ALERT "Failed to create the device\n");return PTR_ERR(binder_device);}printk(KERN_INFO "Binder module initialized\n");return 0;
}// 卸载Binder设备
static void __exit binder_exit(void) {device_destroy(binder_class, MKDEV(major_number, 0));class_unregister(binder_class);class_destroy(binder_class);unregister_chrdev(major_number, DEVICE_NAME);printk(KERN_INFO "Binder module exit\n");
}module_init(binder_init);
module_exit(binder_exit);
MODULE_LICENSE("GPL");

🐓3.3 Binder事件通知

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/android/binder.h>#define DEVICE_NAME "binder_example"
#define BINDER_DEV_PATH "/dev/binder_example"static int major_number;
static struct class *binder_class = NULL;
static struct device *binder_device = NULL;// 打开Binder设备
static int binder_open(struct inode *inode, struct file *file) {printk(KERN_INFO "Binder device opened\n");return 0;
}// 释放Binder设备
static int binder_release(struct inode *inode, struct file *file) {printk(KERN_INFO "Binder device closed\n");return 0;
}// 实现Binder设备的ioctl操作
static long binder_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {int ret = 0;struct binder_write_read bwr;switch (cmd) {case BINDER_RECEIVE_EVENT:// 接收Binder事件通知// 在这里构造事件数据,并使用binder_ioctl_write_read接收事件break;default:printk(KERN_ERR "Unknown command\n");ret = -EINVAL;break;}return ret;
}// 初始化Binder设备
static int __init binder_init(void) {// 分配主设备号major_number = register_chrdev(0, DEVICE_NAME, &binder_fops);if (major_number < 0) {printk(KERN_ALERT "Failed to register a major number\n");return major_number;}// 创建设备类binder_class = class_create(THIS_MODULE, DEVICE_NAME);if (IS_ERR(binder_class)) {unregister_chrdev(major_number, DEVICE_NAME);printk(KERN_ALERT "Failed to register device class\n");return PTR_ERR(binder_class);}// 创建设备节点binder_device = device_create(binder_class, NULL, MKDEV(major_number, 0), NULL, DEVICE_NAME);if (IS_ERR(binder_device)) {class_destroy(binder_class);unregister_chrdev(major_number, DEVICE_NAME);printk(KERN_ALERT "Failed to create the device\n");return PTR_ERR(binder_device);}printk(KERN_INFO "Binder module initialized\n");return 0;
}// 卸载Binder设备
static void __exit binder_exit(void) {device_destroy(binder_class, MKDEV(major_number, 0));class_unregister(binder_class);class_destroy(binder_class);unregister_chrdev(major_number, DEVICE_NAME);printk(KERN_INFO "Binder module exit\n");
}module_init(binder_init);
module_exit(binder_exit);
MODULE_LICENSE("GPL");

相关文章:

Android内核之Binder读写通信:binder_ioctl_write_read用法实例(七十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…...

【C语言/数据结构】经典链表OJ习题~第二期——链中寻环

&#x1f388;&#x1f388;&#x1f388;欢迎采访小残风的博客主页&#xff1a;残风也想永存-CSDN博客&#x1f388;&#x1f388;&#x1f388; &#x1f388;&#x1f388;&#x1f388;本人码云 链接&#xff1a;残风也想永存 (FSRMWK) - Gitee.com&#x1f388;&#x1f…...

MySQL日志机制【undo log、redo log、binlog 】

前言 SQL执行流程图文分析&#xff1a;从连接到执行的全貌_一条 sql 执行的全流程?-CSDN博客文章浏览阅读1.1k次&#xff0c;点赞20次&#xff0c;收藏12次。本文探讨 MySQL 执行一条 SQL 查询语句的详细流程&#xff0c;从连接器开始&#xff0c;逐步介绍了查询缓存、解析 S…...

SSL通信、证书认证原理和失败原因

目录 SSL通信SSL认证原理SSL证书认证失败的原因分析 SSL通信 SSL通信指的是使用SSL&#xff08;Secure Sockets Layer&#xff09;协议进行的加密通讯。SSL是一种标准的安全技术&#xff0c;用于建立一个加密链接&#xff0c;确保从用户的浏览器到服务器之间的数据传输是私密和…...

【MsSQL】数据库基础 库的基本操作

目录 一&#xff0c;数据库基础 1&#xff0c;什么是数据库 2&#xff0c;主流的数据库 3&#xff0c;连接服务器 4&#xff0c;服务器&#xff0c;数据库&#xff0c;表关系 5&#xff0c;使用案例 二&#xff0c;库的操作 1&#xff0c;创建数据库 2&#xff0c;创建…...

AI编码工具-通义灵码功能实测

AI编码工具-通义灵码功能实测 通义灵码功能介绍行级/函数级实时续写自然语言生成代码单元测试生成异常排错智能排查生成代码注释生成代码解释研发领域自由问答 在上一篇文章中&#xff0c;我介绍了通义灵码的功能以及支持的操作系统&#xff0c;主流IDE等&#xff0c;详细内容可…...

直接显示二进制图片

Option Explicit Private Type GUID Data1 As Long Data2 As Integer Data3 As Integer Data4(7) As Byte End Type Private Declare Function CreateStreamOnHGlobal Lib “ole32.dll” (ByRef hGlobal As Any, ByVal fDeleteOnResume As Long, ByRef ppstr As Any) As Long P…...

微软exchange邮箱发送

使用java发送exchange类型的邮件&#xff0c;foxmail中配置如下图&#xff1a; 需要的maven依赖如下&#xff1a; <dependency><groupId>com.microsoft.ews-java-api</groupId><artifactId>ews-java-api</artifactId><version>2.0</ve…...

AI绘画Stable Diffusion SDXL 超赞!高质量万能大模型,写实人像、时尚设计、建筑设计、电影制作—筑梦工业XLV4.0

大家好&#xff0c;我是阿威 今天为大家带来了一款多功能大模型——Dream Tech XL | 筑梦工业XL V4.0。该模型是大佬Dr_Dream基于V3.0训练而来的迭代版本&#xff0c;在提升画面质感的同时&#xff0c;对于提示词理解能力有跨越式提升&#xff0c;可以做到100%还原提示词。筑梦…...

数字人捕捉、建模与合成

在感知系统中&#xff0c;我们与外部合作者一起创建逼真的 3D 人类&#xff0c;其行为可以像虚拟世界中的真实人类一样。这项工作在今天有许多实际应用&#xff0c;并且对于元宇宙的未来至关重要。但是&#xff0c;在感知系统中&#xff0c;我们的目标是科学的——通过重现人类…...

Yarn:下一代JavaScript包管理器的安装与实战指南

当然&#xff0c;让我们深入探讨Yarn——一个高效、可靠的JavaScript包管理器&#xff0c;它为前端开发带来了新的速度和便利。Yarn由Facebook、Google、Exponent和Tilde公司共同推出&#xff0c;旨在解决npm&#xff08;Node.js包管理器&#xff09;存在的问题&#xff0c;如依…...

JVM进程缓存 Caffeine

JVM进程缓存 Caffeine 初识Caffeine Caffeine是一个基于Java8开发的&#xff0c;提供了近乎最佳命中率的高性能的本地缓存库。 ben-manes/caffeine: A high performance caching library for Java (github.com) 实例代码 Test void testBasicOps() {// 创建缓存对象Cache&…...

c++ 线程交叉场景试验

1.需求 处理一个列表的数据&#xff0c;要求按照列表的数据处理10个数据可以使用多线程处理&#xff0c;但是针对每个线程&#xff0c;1~10的处理顺序不能变。每个数据的处理必须原子&#xff0c;即只有一个线程可以针对某个数据进行处理&#xff0c;但是10个数据是可以由10个…...

Cell:如何升华你的单细胞数据——PCF空间单细胞蛋白组联合scRNA-seq解析骨髓微环境

骨髓微环境非常复杂&#xff0c;含有不同的细胞类型&#xff0c;包括了造血、间充质、内皮、血管平滑肌和神经谱系细胞等。非造血细胞对于骨髓造血非常关键。然而&#xff0c;这些细胞在人骨髓中的异质性和空间定位在很大程度上仍未被表征。来自佩雷尔曼医学院的研究者使用scRN…...

vue强制刷新组件

在Vue中强制刷新一个组件&#xff0c;通常不是一个推荐的做法&#xff0c;因为Vue的响应式系统设计就是为了自动处理依赖的更新。要强制重新渲染组件&#xff0c;以下是几种方法&#xff1a; 使用key属性&#xff1a; 最常见的方法是改变组件的key属性。当key发生变化时&#x…...

分享5款对工作学习有帮助的效率软件

​ 今天再来推荐5个超级好用的效率软件&#xff0c;无论是对你的学习还是办公都能有所帮助&#xff0c;每个都堪称神器中的神器&#xff0c;用完后觉得不好用你找我。 1.文件复制——ClipClip ​ ClipClip是一款功能强大、操作简便的文件复制与管理软件。它改变了传统的复制粘…...

redis秒杀(PHP版本)

前提提要 今天产品端提了个需求&#xff0c;院校组要求借调我去帮忙&#xff0c;因为我以前做过商城&#xff0c;现在他们需求做一个积分商城&#xff0c;需要做一个秒杀模块&#xff0c;结果毫无意外的我被借调过去了&#xff0c;刚好可以复习一下以前的知识&#xff0c;现在介…...

图形用户界面(GUI)在AI去衣技术中的作用与重要性

引言&#xff1a; 随着人工智能技术的不断进步&#xff0c;AI去衣这一概念逐渐进入公众视野。它指的是利用深度学习算法&#xff0c;从图片或视频中自动移除人物的衣物&#xff0c;生成相应的“裸体”图像。尽管这项技术在道德和隐私方面引发了诸多争议&#xff0c;但其背后的技…...

如何阅读:一个已被证实的低投入高回报的学习方法的笔记

系列文章目录 如何有效阅读一本书笔记 如何阅读&#xff1a;一个已被证实的低投入高回报的学习方法 麦肯锡精英高效阅读法笔记 读懂一本书笔记 文章目录 系列文章目录第一章 扫清阅读障碍破解读不快、读不进去的谜题一切为了阅读小学教师让你做&#xff0c;但中学老师阻止你做的…...

pycharm 安装“通义灵码“并测试

过程&#xff1a;“File>setting>Plugins” 提示&#xff1a; 翻译之后&#xff1a; 点击"接受"之后&#xff0c;提示一下图片&#xff0c;点击ok 安装完成&#xff1a; 安装完"通义灵码"之后&#xff0c;需要登陆&#xff0c;登陆后测试 参考…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么&#xff1f;1.1.2 感知机的工作原理 1.2 感知机的简单应用&#xff1a;基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

适应性Java用于现代 API:REST、GraphQL 和事件驱动

在快速发展的软件开发领域&#xff0c;REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名&#xff0c;不断适应这些现代范式的需求。随着不断发展的生态系统&#xff0c;Java 在现代 API 方…...