Android内核之Binder通信写操作:binder_thread_write用法实例(七十一)

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

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

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

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

欢迎关注Android系统攻城狮

🍉🍉🍉文章目录🍉🍉🍉

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

🌻1.前言

本篇目的:Android内核之Binder通信写操作:binder_thread_write用法实例

🌻2.Android内核之binder_thread_write介绍

  • binder_thread_write函数是Android内核中用于Binder线程通信的关键函数之一。Binder是Android系统中用于进程间通信(IPC)的机制,它通过驱动程序实现。在Binder机制中,每个进程都有一个专门的Binder线程,用于处理与其他进程的通信请求。

  • binder_thread_write函数主要负责向目标Binder线程发送消息。它接受参数包括目标线程的信息、要发送的数据、数据的大小等,并将这些信息封装成一个Binder交易数据结构,最终通过驱动程序发送给目标线程。

  • 该函数的关键步骤如下:

  1. 参数验证: 首先,函数会验证传入的参数,确保它们的有效性和合法性,包括目标线程的有效性、发送数据的大小等。

  2. 构造Binder交易数据: 接下来,函数会根据传入的参数构造一个Binder交易数据结构。这个数据结构包含了要发送的消息内容、目标线程的标识符等信息。

  3. 调用Binder驱动发送消息: 函数将构造好的Binder交易数据结构传递给Binder驱动程序,通过驱动程序实现消息的发送。Binder驱动会负责将消息传递给目标线程,并处理相关的错误情况。

  4. 返回结果: 最后,函数根据发送结果返回相应的错误码或成功状态,通知调用者发送消息的结果。

  • binder_thread_write函数的调用通常发生在Android系统的内核空间,例如系统服务或驱动程序中。它允许不同的进程之间进行通信,实现了Android系统中各个组件之间的协作与交互。作为Android系统中IPC机制的核心之一,Binder机制在实现高效稳定的进程通信方面发挥着重要作用,而binder_thread_write函数则是其中的关键环节之一。

🌻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设备的write操作
static ssize_t binder_write(struct file *file, const char __user *buffer, size_t count, loff_t *offset) {struct binder_transaction_data *transaction_data;// 从用户空间拷贝数据到内核空间if (copy_from_user(&transaction_data, buffer, sizeof(struct binder_transaction_data)) != 0) {return -EFAULT;}// 使用binder_thread_write发送Binder消息binder_thread_write(transaction_data);return count;
}// 初始化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设备的write操作
static ssize_t binder_write(struct file *file, const char __user *buffer, size_t count, loff_t *offset) {struct binder_event *event;// 从用户空间拷贝数据到内核空间if (copy_from_user(&event, buffer, sizeof(struct binder_event)) != 0) {return -EFAULT;}// 使用binder_thread_write发送Binder事件通知binder_thread_write(event);return count;
}// 初始化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设备的write操作
static ssize_t binder_write(struct file *file, const char __user *buffer, size_t count, loff_t *offset) {struct binder_thread *thread;// 从用户空间拷贝数据到内核空间if (copy_from_user(&thread, buffer, sizeof(struct binder_thread)) != 0) {return -EFAULT;}// 使用binder_thread_write发送Binder异步消息binder_thread_write(thread);return count;
}// 初始化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");

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

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

相关文章

终端安全管理措施有哪些?好用终端安全管理软件推荐(建议收藏)

在当今数字化时代&#xff0c;信息安全已成为企业运营不可或缺的一部分。其中&#xff0c;终端安全为您详细介绍&#xff0c;并推荐几款好用的终端安全管理软件&#xff0c;帮助您更好地保护企业信息安全。管理是确保企业信息安全的重要环节。那么&#xff0c;终端安全管理措施…

Kettle连接Mysql数据库时报错——Driver class ‘org.gjt.mm.mysql.Driver‘ could not be found

一、问题描述 当我们使用ETL工具Kettle需要连接Mysql数据库进行数据清洗操作,在配置好Mysql的连接串内容后,点击【测试】按钮时报错【错误连接数据库 [MysqlTestConnection] : org.pentaho.di.core.exception.KettleDatabaseException: Error occurred while trying to conne…

搭建Springboot的基础开发框架-01

本系列专题虽然是按教学的深度来定稿的&#xff0c;但在项目结构和代码组织方面是按公司系统的要求来书定的。在本章中主要介绍下基础开发框架的功能。后续所有章节的项目全是在本基础框架的基础上演进的。 工程结构介绍 SpringbootSeries&#xff1a;父工程&#xff0c;定义一…

MyBatis高级扩展

五、MyBatis高级扩展 5.1 Mapper批量映射优化 需求Mapper 配置文件很多时&#xff0c;在全局配置文件中一个一个注册太麻烦&#xff0c;希望有一个办法能够一劳永逸。 配置方式Mybatis 允许在指定 Mapper 映射文件时&#xff0c;只指定其所在的包&#xff1a; <mappers&…

SystemVerilog/Verilog中的仿真延时建模之门延时

提到门延时,就必须重提分布延迟。 分布延迟指模块内信号从(逻辑门的输入到输出)或者(线网的延迟)。这里虽然简短一句话,却涵盖非常大的信息量。 一 门延迟种类 今天我们着重看门延迟。常见门延迟主要有三种: 注意!:如果信号从0/1/z变化到x,那么此时的门传输延迟为上…

C语言 函数概述

好 接下来 我们来讲函数 构建C程序的最佳方式 就是模块化程序设计 C语言中 最基本的程序模块被称为 函数 所以 这个知识点的重要性不言而喻 这里 我们讲个故事 诸葛亮六出祁山时 为了逼司马懿出战 派人送给力司马懿一件女人衣服 司马懿只是为使者 诸葛亮的饮食起居 使者感叹…

AI绘图神器!InstantStyle保留风格进行文本到图像生成

在今天的数字化时代&#xff0c;我们可以看到AI技术的应用已经渗透到生活的各个角落&#xff0c;尤其是在视觉艺术领域。最近&#xff0c;一个名为InstantStyle的全新框架引起了广泛关注&#xff0c;它是一个创新的文本到图像生成框架&#xff0c;其核心功能在于能够有效地分离…

【JVM】类加载机制及双亲委派模型

目录 一、类加载过程 1. 加载 2. 连接 a. 验证 b. 准备 c. 解析 3. 初始化 二、双亲委派模型 类加载器 双亲委派模型的工作过程 双亲委派模型的优点 一、类加载过程 JVM的类加载机制是JVM在运行时&#xff0c;将 .class 文件加载到内存中并转换为Java类的过程。它…

全面升级企业网络安全 迈入SASE新时代

随着数字化业务、云计算、物联网和人工智能等技术的飞速发展&#xff0c;企业的业务部署环境日渐多样化&#xff0c;企业数据的存储由传统的数据中心向云端和SaaS迁移。远程移动设备办公模式的普及&#xff0c;企业多分支机构的加速设立&#xff0c;也使得企业业务系统的用户范…

神器:jQuery一键转换为纯净JavaScript代码

我的新书《Android App开发入门与实战》已于2020年8月由人民邮电出版社出版&#xff0c;欢迎购买。点击进入详情 该工具将 jQuery 代码转换为现代、高效的 JavaScript。它允许您用纯 JavaScript 替换 jQuery&#xff0c;同时保持原始代码不变。 虽然 jQuery 一直是 Web 开发中…

【自动驾驶|毫米波雷达】初识毫米波雷达射频前端硬件

第一次更新&#xff1a;2024/5/4 目录 整体概述 混频器&#xff08;MIXER&#xff09; 低通滤波器&#xff08;LPF&#xff1a;Low-Pass filter&#xff09; 数模转换器&#xff08;ADC&#xff1a;Analog to Digital Converter&#xff09; 毫米波雷达功能框图 整体概述 完…

ctfshow web入门 sql注入 web224--web233

web224 扫描后台&#xff0c;发现robots.txt&#xff0c;访问发现/pwdreset.php &#xff0c;再访问可以重置密码 &#xff0c;登录之后发现上传文件 检查发现没有限制诶 上传txt,png,zip发现文件错误了 后面知道群里有个文件能上传 <? _$GET[1]_?>就是0x3c3f3d60245…

echars 的一些运用

基础图形 // 支架压力数据量统计 let splitLine { // 网格线设置show:true,lineStyle:{color:#E2E7EC,width:1,}, } let itemStyle { // 柱形图颜色color:#5B9BD5, } let axisLine { // 轴线样式lineStyle:{color:#E2E7EC,}, } let axisLabel { // 轴刻度字-样式fontSize:…

STM32快速入门(串口传输之USART)

STM32快速入门&#xff08;串口传输之USART&#xff09; 前言 USART串口传输能实现信息在设备之间的点对点传输&#xff0c;支持单工、半双工、全全双工&#xff0c;一般是有三个引脚&#xff1a;TX、RX、SW_RX&#xff08;共地&#xff09;。不需要一根线来同步时钟。最大优…

停车场收费管理系统winfrom

停车场收费管理系统winfrom 管理员登陆后可以费用设置 修改密码 开户 充值 注销 入库 出库 退出 本项目通过dat文件格式存储数据 public static void Load() { string path Application.StartupPath "\data\data2.dat"; if (File.Exists(path)) …

4diacIDE同时编译不同版本踩坑记录

4diac不同版本依赖插件版本及jdk版本是不同的&#xff0c;当你需要搭建不同版本4diacIDE开发环境时&#xff0c;就会出现各种问题。最近一个月github上项目提交记录比较多&#xff0c;出现了不少坑。以下记录下此背景下的解决方法&#xff1a; 1、首先由于.target依赖的eclipse…

探索大语言模型在信息提取中的应用与前景

随着人工智能技术的快速发展&#xff0c;大语言模型&#xff08;LLMs&#xff09;在自然语言处理&#xff08;NLP&#xff09;领域取得了显著的进展。特别是在信息提取&#xff08;IE&#xff09;任务中&#xff0c;LLMs展现出了前所未有的潜力和优势。信息提取是从非结构化文本…

【Linux】网络接口绑定和组合的操作实例

网络接口绑定和组合的操作实例 &#xff08;一&#xff09;网卡1. 增2. 查3. 激活——设置网络接口 &#xff08;二&#xff09;网络接口绑定1. 概述2. 实验操作3. 删除绑定 &#xff08;三&#xff09;网络接口组合1. 概述2. 实验操作 &#xff08;一&#xff09;网卡 1. 增 …

122. Kafka问题与解决实践

文章目录 前言顺序问题1. 为什么要保证消息的顺序&#xff1f;2.如何保证消息顺序&#xff1f;3.出现意外4.解决过程 消息积压1. 消息体过大2. 路由规则不合理3. 批量操作引起的连锁反应4. 表过大 主键冲突数据库主从延迟重复消费多环境消费问题后记 前言 假如有家公司是做餐饮…

web安全day03

MYSQL注入&#xff1a; SQL 注入的原理、危害及防御措施 SQL 注入的原理&#xff1a;原本的 SQL 语句在与用户可控的参数经过了如拼接、替换等字符串操作后&#xff0c;得到一个新的 SQL 语句并被数据库解析执行&#xff0c;从而达到非预期的效果。 SQL 注入的危害&#xff…