【70】NTB的地址映射和地址转换

2024-03-23 05:10

本文主要是介绍【70】NTB的地址映射和地址转换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  NTB有两个重要的应用
  (1)PCI于隔离,即可以隔离出两个或者多个PCI系统
  (2)实现地址翻译。
  这篇文章注重说一下地址翻译,关于NTB一些介绍和应用见:
https://blog.csdn.net/linjiasen/article/details/104532342
https://mp.weixin.qq.com/s/0Ais2S-GnFfsWRnoWhjRzw
https://mp.weixin.qq.com/s/-AAxGslLt0nZkVCn3KWI7Q
https://mp.weixin.qq.com/s/VBRDnpJG5EmI8O2Ple1Xeg
  下图就是用PCIe switch NTB+DMA组建的NTB back to back的框图
在这里插入图片描述
  对于NTB的来说,可以做地址映射的BAR0、BAR1、BAR2/3、BAR4/5(看芯片设计到底用哪些BAR做reg映射,哪些BAR做address映射)在Primary端(virtual端)和Secondary端(link端)各有3个寄存器(有些芯片是2个寄存器,其实BAR CTRL和BAR LMT可以合成一个reg,没有道理说你弄一个很大的BAR,只开一个小的窗口,不用也是浪费)
  (1)BAR CTRL reg决定了BAR SIZE。和base address reg共同组成NTB BARx的memory窗口。
  (2)BAR LMT reg决定了NTB的转发窗口,一般转发窗口和大小和BAR SIZE一样大。
  (3)BAR XLAT reg决定往对端映射时的起始地址。
  这样DMA或者CPU写NTB BARx对应的offset,就会被NTB转发到对控映射的起始地址+offset的位置,这样就构成了一个简单存储系统的镜像模型了。当然实际工程中存储的镜像远比这个复杂,不过原理是一样的,只是有很多可靠性的问题需要解决。
在这里插入图片描述
  举个例子吧,我使用的单NTB系统,即一控提供NTB,一控提供TB,为了方便区分,提供NTB的我们叫主控,提供TB的我们叫从控。逻辑上主控的CPU只能枚举到NTB primary端,NTB的secondary端是从控的CPU枚举的(单NT在实际产品中有很多问题,因为需要主控起来了,从控再启动,这样从控才能枚举到NTB secondary端,或者自己写driver来枚举NTB 设备)
NTB PRI的NTB BAR的地址如下:
Region 0: Memory at dce00000 (32-bit, non-prefetchable) [size=32K]
Region 1: Memory at dcd00000 (32-bit, non-prefetchable) [size=1M]
Region 2: Memory at 1be00000000 (64-bit, prefetchable) [size=4G]
Region 4: Memory at 1bc00000000 (64-bit, prefetchable) [size=8G]
我把primary端NTB BAR23(1be00000000~1be00000000+4G-1)映射到从控的0x5cd00000这个地址(下图的XLAT23),这地址其实是NTB SEC端的NTB BAR0(dcd00000)减2G的位置。也就是说我们把primary端的NTB BAR23映射到secondary端的BAR0-2G的位置(这个地址可以随意改)。 这样映射完毕后,主端NTB BAR23就映射到从控NTB BAR0减2G的位置了。
NTB SEC的NTB BAR的地址如下:
Region 0: Memory at dcd00000 (32-bit, non-prefetchable) [size=32K]
Region 1: Memory at dcc00000 (32-bit, non-prefetchable) [size=1M]
Region 2: Memory at fc00000000 (64-bit, prefetchable) [size=4G]
Region 4: Memory at fa00000000 (64-bit, prefetchable) [size=8G]
在这里插入图片描述
注意关闭IOMMU功能,目前linux 中对于AMD和intel的IOMMU的支持都有点问题,开了IOMMU访问NTB是有问题的。
在这里插入图片描述
这里为啥0x438寄出器的值修改成0x123456后读取出来是0x123000呢,是因为这个reg的低12bit是RO的,默认值就是0.
在这里插入图片描述
  上面主从控的值是对应的,也证明我们成功把主端NTB BAR23映射到从控NTB BAR0减2G的位置了。
  NTB的地址转换其实就是这么简单,你可以把对控任何一个地址映射过来,只要这个地址是可以访问的。如果是X86系统下,其实最简单的方式是把对控的0地址映射过来测试一下NTB是否正常,因为X86前面的4K的地址是reserved,是可以正常读写的。
在这里插入图片描述
  如果对控的地址是host的main memory地址,你去对控用busybox devmem访问main memory则需要hack系统把限制访问给拿掉。hack系统有两种方法,一种是你写个ko把busybox devmem在内核态的那个限制给override掉,一种是重新编译内核把限制给拿掉
hack系统的方法https://blog.csdn.net/linjiasen/article/details/103408631?ops_request_misc=&request_id=91b4390998ce4875a5daa6a57a380fce&biz_id=&utm_medium=distribute.pc_search_result.none-task-blog-2blogkoosearch~default-1-103408631-null-null.268v1control&utm_term=%E6%89%80%E6%9C%89%E7%9A%84&spm=1018.2226.3001.4450
如果NTB转到对控的的地址是个MMIO,则需要用setpci -s bus:dev.fun 0x4=0x7把对应设备的memory access enable给打开

  你可以通过NTB访问对控任意你映射的地址,如果做过工程,你就会懂得这句话杀伤力有多大了。NTB可以映射任何一个地址,是典型性的双刃剑,DMA+NTB的形式就可以访问对控的任何地址,用的好的话可以实现很多需求,用的不好,可能把对控搞死,比如踩内存啥的,由于是对控DMA发起的,到时候非常难定位。

这篇关于【70】NTB的地址映射和地址转换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/837238

相关文章

Ubuntu固定虚拟机ip地址的方法教程

《Ubuntu固定虚拟机ip地址的方法教程》本文详细介绍了如何在Ubuntu虚拟机中固定IP地址,包括检查和编辑`/etc/apt/sources.list`文件、更新网络配置文件以及使用Networ... 1、由于虚拟机网络是桥接,所以ip地址会不停地变化,接下来我们就讲述ip如何固定 2、如果apt安

Java数字转换工具类NumberUtil的使用

《Java数字转换工具类NumberUtil的使用》NumberUtil是一个功能强大的Java工具类,用于处理数字的各种操作,包括数值运算、格式化、随机数生成和数值判断,下面就来介绍一下Number... 目录一、NumberUtil类概述二、主要功能介绍1. 数值运算2. 格式化3. 数值判断4. 随机

C语言中自动与强制转换全解析

《C语言中自动与强制转换全解析》在编写C程序时,类型转换是确保数据正确性和一致性的关键环节,无论是隐式转换还是显式转换,都各有特点和应用场景,本文将详细探讨C语言中的类型转换机制,帮助您更好地理解并在... 目录类型转换的重要性自动类型转换(隐式转换)强制类型转换(显式转换)常见错误与注意事项总结与建议类型

查询SQL Server数据库服务器IP地址的多种有效方法

《查询SQLServer数据库服务器IP地址的多种有效方法》作为数据库管理员或开发人员,了解如何查询SQLServer数据库服务器的IP地址是一项重要技能,本文将介绍几种简单而有效的方法,帮助你轻松... 目录使用T-SQL查询方法1:使用系统函数方法2:使用系统视图使用SQL Server Configu

Python实现视频转换为音频的方法详解

《Python实现视频转换为音频的方法详解》这篇文章主要为大家详细Python如何将视频转换为音频并将音频文件保存到特定文件夹下,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. python需求的任务2. Python代码的实现3. 代码修改的位置4. 运行结果5. 注意事项

使用Java实现获取客户端IP地址

《使用Java实现获取客户端IP地址》这篇文章主要为大家详细介绍了如何使用Java实现获取客户端IP地址,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 首先是获取 IP,直接上代码import org.springframework.web.context.request.Requ

使用Python实现图片和base64转换工具

《使用Python实现图片和base64转换工具》这篇文章主要为大家详细介绍了如何使用Python中的base64模块编写一个工具,可以实现图片和Base64编码之间的转换,感兴趣的小伙伴可以了解下... 简介使用python的base64模块来实现图片和Base64编码之间的转换。可以将图片转换为Bas

Linux环境变量&&进程地址空间详解

《Linux环境变量&&进程地址空间详解》本文介绍了Linux环境变量、命令行参数、进程地址空间以及Linux内核进程调度队列的相关知识,环境变量是系统运行环境的参数,命令行参数用于传递给程序的参数,... 目录一、初步认识环境变量1.1常见的环境变量1.2环境变量的基本概念二、命令行参数2.1通过命令编程

C++实现获取本机MAC地址与IP地址

《C++实现获取本机MAC地址与IP地址》这篇文章主要为大家详细介绍了C++实现获取本机MAC地址与IP地址的两种方式,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 实际工作中,项目上常常需要获取本机的IP地址和MAC地址,在此使用两种方案获取1.MFC中获取IP和MAC地址获取

C/C++通过IP获取局域网网卡MAC地址

《C/C++通过IP获取局域网网卡MAC地址》这篇文章主要为大家详细介绍了C++如何通过Win32API函数SendARP从IP地址获取局域网内网卡的MAC地址,感兴趣的小伙伴可以跟随小编一起学习一下... C/C++通过IP获取局域网网卡MAC地址通过win32 SendARP获取MAC地址代码#i