IO Virtualization with Virtio.part 1 [十二]

久等了各位!

本篇开始讲解 IO 虚拟化中的 virtio,我会以 Linux 的 IIC 驱动为例,从 IIC 驱动的非虚拟化实现,到 IIC 驱动的半虚拟化实现,再到最后 X-Hyper 中如何通过 virtio 来实现前后端联系,一步步把 virtio 讲清楚。所以我一共会分为4个子篇幅来介绍virtio,内容有点多,需要一点点消化。

本篇我们以 RK 板的 IIC 控制器为例,先讲解 Linux 下的 IIC 驱动框架。

设备树创建 i2c 设备的节点,在设备树遍历时会创建一个 i2c 的 platform 设备出来:

    i2c@fdd40000 {compatible = "rockchip,rk3399-i2c";reg = <0x00 0xfdd40000 0x00 0x1000>;clocks = <0x32 0x07 0x32 0x2d>;clock-names = "i2c\0pclk";interrupts = <0x00 0x2e 0x04>;pinctrl-names = "default";pinctrl-0 = <0x35>;#address-cells = <0x01>;#size-cells = <0x00>;status = "okay";phandle = <0x17a>;}

设备包含如下信息:

  • compatible:兼容性,用于匹配可以用于该设备的驱动;
  • reg:该设备的寄存器基地址和范围;
  • interrupts:i2c 中断控制器使用的中断配置;

这个 platform device 在被放入平台总线时,会匹配对应的 platform driver,那么先来看一下 platform bus 是什么:

struct bus_type platform_bus_type = {.name		= "platform",.dev_groups	= platform_dev_groups,.match		= platform_match,.uevent		= platform_uevent,.dma_configure	= platform_dma_configure,.pm		= &platform_dev_pm_ops,
};

我们只关注其中的 match 函数,它是当一个新的设备或者一个新的驱动被添加到该总线时会被调用的匹配函数,当一个新的设备被加入时,使用 match 来匹配对应的驱动,当一个新的驱动被添加到该总线时,也会使用这个 match 来匹配设备。

我们以 rk 板的 i2c 平台总线驱动为例,首先我们找到 rk 板的 i2c 平台总线驱动:

static struct platform_driver rk3x_i2c_driver = {.probe   = rk3x_i2c_probe,.remove  = rk3x_i2c_remove,.driver  = {.name  = "rk3x-i2c",.of_match_table = rk3x_i2c_match,.pm = &rk3x_i2c_pm_ops,},
};

使用of_match_table 来匹配对应的的设备,使用probe 来初始化设备。

整体流程如下:

在深入分析 IIC 的驱动代码前,先简单看一下 IIC 的整个数据发送和接受流程,这里不会涉及底层硬件的时序,需要读者自己去学习。

IIC 主机向从机写数据:

IIC 主机向从机读数据:

当然IIC的发送接收不止上述两种模式,这里只讨论常用的两种发送和接收数据的方法。

然后我们开始分析 IIC platform driver 的代码了:

我们以 RK board 为例,其总线驱动代码在:drivers\i2c\busses\i2c-rk3x.c 中,具体实现可以参考我之前的文章,这里只给出一个整体框图。最终 i2c 的控制器也会以字符设备节点暴露给用户态,我们可以通过 i2c 控制器的字符设备给相应的 i2c 外设通信。

然后看一下用户层打开一个 i2c 控制器对应的字符设备节点的整体流程图:

整个流程如下:

当应用程序打开一个设备文件时,通过系统调用 sys_open 进入内核,在内核空间中由 do_sys_open 负责发起整个设备文件的打开操作,首先获得该设备文件所对应的 inode,然后调用其中的 i_fop 函数,对字符设备而言,i_fop 函数就是 chrdev_open,后者通过 inode 中的 i_rdev 成员在 cdev_map 中查找该设备所对应的设备对象 cdev,在成功找到了该设备对象后,将 inode 的 cdev 成员指向该字符设备对象,这样下次再对该设备文件节点进行打开操作时,就可以直接通过 i_cdev 成员得到设备节点所对应的字符设备对象了。内核在每次打开一个设备文件时,会产生一个整形的文件描述符 fd 和一个新的 struct file 对象 filp 来跟踪对该文件的这一次操作,在打开设备文件时,内核会将 filp 和 fd 关联起来,同时会将 cdev 中的 ops 赋值给 filp->f_op,同时创建 i2c_client,关联 i2c_adapter,并将 filp 的 private_data 和 i2_client 关联起来。最后 sys_open 系统调用将设备文件描述符 fd 返回到用户空间。

接下来用一个实际的例子去理解一下 IIC 的完成一次 Combined R/W 的流程:

用户侧示例代码如下:

int main(void)
{int fd = 0;int ret = 0;const char *path_name ="/dev/i2c-0";uint8_t buf[8] = {0};uint8_t start_reg = 0x0;struct i2c_msg read_msg[2] = {{0x20,               /* slave addr */0,                  /* operate flags */1,                  /* data len */&start_reg          /* data buf */},{0x20,               /* slave addr */I2C_M_RD,           /* operate flags */8,                  /* data len */&buf[0]   			/* data buf */},};struct i2c_rdwr_ioctl_data rdwr = {.msgs = read_msg,.nmsgs = 2};fd  = open(path_name, O_RDWR);ret = ioctl(fd, I2C_SLAVE_FORCE, 0x20);ret = ioctl(fd, I2C_RDWR, (unsigned long)&rdwr);return 0;
}

这是一次 Combined 的从机数据读取操作,由两部分i2c_msg 组成,第一个 msg 向从机写设备寄存器地址,表示要读取的设备寄存器,然后再发送读数据请求,向从机请求 8 个字节的 data。

对应整个 IIC 的协议段如下:

然后我们通过 ioctl 进入内核,并最终调用 i2cdev_fops->i2cdev_ioctl。

static const struct file_operations i2cdev_fops = {....compat_ioctl	= compat_i2cdev_ioctl,...
};static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{struct i2c_client *client = file->private_data;...switch (cmd) {...case I2C_RDWR: {...return i2cdev_ioctl_rdwr(client, rdwr_arg.nmsgs, rdwr_pa);}...return 0;
}static noinline int i2cdev_ioctl_rdwr(struct i2c_client *client,unsigned nmsgs, struct i2c_msg *msgs)
{...res = i2c_transfer(client->adapter, msgs, nmsgs);...return res;
}int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{...ret = __i2c_transfer(adap, msgs, num);return ret;
}int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{...ret = adap->algo->master_xfer(adap, msgs, num);...return ret;
}

可以看到最后就是调用了i2c_adapter 中的master_xfer。

static int rk3x_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg *msgs, int num)
{struct rk3x_i2c *i2c = (struct rk3x_i2c *)adap->algo_data;...for (i = 0; i < num; i += ret) {ret = rk3x_i2c_setup(i2c, msgs + i, num - i);...rk3x_i2c_start(i2c);...}...
}

rk3x_i2c_xfer 中初始化MRXADDR 和 MRXRADDR 寄存器并初始化 i2c 的初始化状态机状态。然后通过rk3x_i2c_start 发送 start 信号开始 i2c 的整个流程,并在rk3x_i2c_irq 中维护整个 i2c 数据发送和接受的状态机:

static irqreturn_t rk3x_i2c_irq(int irqno, void *dev_id)
{...switch (i2c->state) {case STATE_START:rk3x_i2c_handle_start(i2c, ipd);break;case STATE_WRITE:rk3x_i2c_handle_write(i2c, ipd);break;case STATE_READ:rk3x_i2c_handle_read(i2c, ipd);break;case STATE_STOP:rk3x_i2c_handle_stop(i2c, ipd);break;case STATE_IDLE:break;}...
}

在 Combined W/R 模式下的流程图和状态机如下所示:

流程图:

IIC 驱动状态机:

到这里我们简单的介绍了Linux下的IIC驱动框架和其工作流程,如果要深入理解还需自己阅读驱动代码,下一篇幅将介绍IIC半虚拟化的Virtio前端驱动。

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

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

相关文章

HTML——26.像素单位

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>像素</title></head><body><!--像素&#xff1a;1.指设备屏幕上的一个点&#xff0c;单位px&#xff0c;如led屏上的小灯朱2.当屏幕分辨率固定时&…

uniapp不能直接修改props的数据原理浅析

uniapp不能直接修改props的数据 Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the props value. Prop being mutated: "expectDeliveryAt" 避…

基于FISCO BCOS的电子签署系统

概述 本项目致力于构建一个安全、高效且功能完备的电子签署系统&#xff0c;通过整合区块链技术与传统数据库管理&#xff0c;为用户提供了可靠的电子签署解决方案&#xff0c;有效应对传统电子签署系统的数据安全隐患&#xff0c;满足企业和个人在数字化办公环境下对电子文档…

HackMyVM-Adria靶机的测试报告

目录 一、测试环境 1、系统环境 2、使用工具/软件 二、测试目的 三、操作过程 1、信息搜集 2、Getshell 3、提权 四、结论 一、测试环境 1、系统环境 渗透机&#xff1a;kali2021.1(192.168.101.127) 靶 机&#xff1a;debian/linux(192.168.101.226) 注意事项&…

STM32-笔记23-超声波传感器HC-SR04

一、简介 HC-SR04 工作参数&#xff1a; • 探测距离&#xff1a;2~600cm • 探测精度&#xff1a;0.1cm1% • 感应角度&#xff1a;<15 • 输出方式&#xff1a;GPIO • 工作电压&#xff1a;DC 3~5.5V • 工作电流&#xff1a;5.3mA • 工作温度&#xff1a;-40~85℃ 怎么…

win32汇编环境下,对话框程序中生成listview列表控件,点击标题栏自动排序的示例

;;启动后的效果 ;点击性别后的效果 ;把代码抄进radasm里面&#xff0c;可以直接编译运行。重要的地方加了备注。 ;这个有点复杂&#xff0c;重要的地方加了备注 ;以下是ASM文件 ;>>>>>>>>>>>>>>>>>>>>>>>…

工业以太网交换机怎么挑选?

在现代工业中&#xff0c;工业以太网交换机是网络的核心设备。正确选择适合的交换机&#xff0c;直接关系到工业网络的运行稳定性和系统的可靠性。接下来&#xff0c;我们将围绕选型时需要重点考虑的几个方面展开讨论&#xff0c;并为您提供一些实用建议。 性能与传输速度 选择…

如何在 Ubuntu 22.04 上安装并开始使用 RabbitMQ

简介 消息代理是中间应用程序&#xff0c;在不同服务之间提供可靠和稳定的通信方面发挥着关键作用。它们可以将传入的请求存储在队列中&#xff0c;并逐个提供给接收服务。通过以这种方式解耦服务&#xff0c;你可以使其更具可扩展性和性能。 RabbitMQ 是一种流行的开源消息代…

Zabbix企业级分布式监控系统

第一章&#xff1a;监控概念及Zabbix部署 监控概述 对于监控系统在企业架构中不是新的技术&#xff0c;但却是必不可少的重要组成部分&#xff0c;所谓无监控&#xff0c;不运维&#xff01; 监控系统可以帮助运维、开发、测试等人员及时的发现服务器出现的故障&#xff0c;…

前端安全措施:接口签名、RSA加密、反调试、反反调试、CAPTCHA验证

文章目录 引言I 设置防爬虫功能使用robots.txt文件通过配置HTTP头部中的X-Robots-TagII 禁止打开开发者工具反复清空控制台无限debugger反调试检查是否按下了F12或其他调试快捷键禁用右键监听调试快捷键例子III 屏蔽粘贴/复制/剪切/选中IV 知识扩展: javascript内置命令调试分…

ThinkPHP 8高效构建Web应用-第一个简单的MVC应用示例

【图书介绍】《ThinkPHP 8高效构建Web应用》-CSDN博客 《2025新书 ThinkPHP 8高效构建Web应用 编程与应用开发丛书 夏磊 清华大学出版社教材书籍 9787302678236 ThinkPHP 8高效构建Web应用》【摘要 书评 试读】- 京东图书 使用VS Code开发ThinkPHP项目-CSDN博客 我们先实现一…

Visual Studio 中增加的AI功能

前言&#xff1a; 人工智能的发展&#xff0c;在现在&#xff0c;编程技术的IDE里面也融合了AI的基本操做。本例&#xff0c;以微软的Visual Studio中的人工智能的功能介绍例子。 本例的环境&#xff1a; Visual Studio 17.12 1 AI 智能变量检测&#xff1a; 上图展示了一…

理解生成协同促进?华为诺亚提出ILLUME,15M数据实现多模态理解生成一体化

多模态理解与生成一体化模型&#xff0c;致力于将视觉理解与生成能力融入同一框架&#xff0c;不仅推动了任务协同与泛化能力的突破&#xff0c;更重要的是&#xff0c;它代表着对类人智能&#xff08;AGI&#xff09;的一种深层探索。通过在单一模型中统一理解与生成&#xff…

TTL 传输中过期问题定位

问题&#xff1a; 工作环境中有一个acap的环境&#xff0c;ac的wan口ip是192.168.186.195/24&#xff0c;ac上lan上有vlan205&#xff0c;其ip子接口地址192.168.205.1/24&#xff0c;ac采用非nat模式&#xff0c;而是路由模式&#xff0c;在上级路由器上有192.168.205.0/24指向…

015-spring-动态原理、AOP的xml和注解方式

强制使用cglib动态代理 spring-AOP的使用

Postman测试big-event

报错500。看弹幕&#xff0c;知道可能是yml或sql有问题。 所以检查idea工作台&#xff0c; 直接找UserMapper检查&#xff0c;发现完全OK。 顺着这个error发现可能是sql有问题。因为提示是sql问题&#xff0c;而且是有now()的那个sql。 之后通过给的课件&#xff0c;复制课件…

CPT203 Software Engineering 软件工程 Pt.1 概论和软件过程(中英双语)

文章目录 1.Introduction1.1 What software engineering is and why it is important&#xff08;什么是软件工程&#xff0c;为什么它很重要&#xff09;1.1 We can’t run the modern world without software&#xff08;我们的世界离不开软件&#xff09;1.1.1 What is Soft…

基于SpringBoot的题库管理系统的设计与实现(源码+SQL+LW+部署讲解)

文章目录 摘 要1. 第1章 选题背景及研究意义1.1 选题背景1.2 研究意义1.3 论文结构安排 2. 第2章 相关开发技术2.1 前端技术2.2 后端技术2.3 数据库技术 3. 第3章 可行性及需求分析3.1 可行性分析3.2 系统需求分析 4. 第4章 系统概要设计4.1 系统功能模块设计4.2 数据库设计 5.…

Mac 12.1安装tiger-vnc问题-routines:CRYPTO_internal:bad key length

背景&#xff1a;因为某些原因需要从本地mac连接远程linxu桌面查看一些内容&#xff0c;必须使用桌面查看&#xff0c;所以ssh无法满足&#xff0c;所以决定安装vnc客户端。 问题&#xff1a; 在mac上通过 brew install tiger-vnc命令安装, 但是报错如下&#xff1a; > D…

《探秘开源大模型:AI 世界的“超级引擎”》

《探秘开源大模型:AI 世界的“超级引擎”》 一、开源大模型崛起之路二、开源大模型发展历程回顾(一)早期奠基:理论突破与初步实践(二)快速发展:百花齐放的模型格局(三)当下态势:走向成熟与多元融合三、开源大模型核心技术剖析(一)Transformer 架构:基石之稳(二)…