- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个外部 FPGA 设备,它通过 PCIe 将大量数据转储到保留的(使用引导加载程序参数)连续内存区域。该内存区域将始终从同一位置开始。
我现在想尽快通过 UDP 转储该数据。我不关心检查这些数据,所以没有必要将它带入用户空间。因此,我的研究表明使用零拷贝是最快/最好的方法。
我正在尝试 int memFd = open("/dev/mem", O_RDONLY);
,然后在 sendfile
中使用 memFd
和splice
函数调用,但这些都失败了。
花了几天时间,但我终于在 sendfile
源代码中看到输入文件描述符必须是一个常规文件(据我所知,手册页中遗漏了一个令人沮丧的细节), /dev/mem
不是常规文件。不管怎样,我又四处看了看,现在确信 splice
是我想要使用的调用。
但是,这也失败了,错误号为 14-EFAULT,意思是“地址错误”(同样令人沮丧的是,splice
手册页中未提及此错误代码)。我查看了 splice
的源代码,可以看到几次返回 EFAULT 的地方,但我只是看不出我传递的参数是如何导致问题的。
我的简化、无错误检查代码如下;
int filedes[2];
int memFd = open("/dev/mem", O_RDONLY);
int fileFd = open("myTestFile.txt", O_RDONLY);
loff_t offset = START_OF_MEM_REGION;
int sockFd = ConfigureMySocket();
pipe(filedes); // this returns 0, so the pipes are good
int ret = splice(memFd, &offset, filedes[1], NULL, 128, SPLICE_F_MOVE); // this fails with EFAULT
//int ret = splice(memFd, NULL, filedes[1], NULL, 128, 0); // this also fails with EFAULT
//int ret = splice(fileFd, NULL, filedes[1], NULL, 128, 0); // this works just fine
// this is never reached because the splice call above hangs. If I run the
// fileFd splice call instead this works just fine
ret = splice(filedes[0], NULL, sockFd, NULL, 128, 0);
我的系统信息:
CONFIG_STRICT_DEVMEM
编译其他有趣的事实:
CONFIG_STRICT_DEVMEM
编译的,因此我将 1MB 的限制归因于此。mmap
到内存区域并查看 FPGA 正在写入的数据。我的问题是:
splice
是执行此操作的正确方法吗?有人认为有更好的方法吗?splice
是正确的,那么有人知道这里会发生什么吗?是否有一个内核编译器标志阻止它工作?我正在阅读 splice.c
的源代码,但它不是 3.1.10 版本,所以也许有什么变化?无论哪种方式,看到这项工作在 VM 中运行良好,但在嵌入式环境中运行良好,都是令人遗憾的。编辑:我已经从 kernal.org 下载了 3.1.10 源代码,不幸的是,我发现与我在 free-electrons.com 上看到的不同版本没有重大差异。在我看来,所有拼接代码都在/fs/splice.c 中。 do_splice(...)
必须是要执行的代码。我对 splice
的第一次调用(使用 memFd
和 filedes[1]
)应该下降到 if (opipe) {
... 在这里你可以看到如果 copy_from_user
或 copy_to_user
失败返回 EFAULT
..这些怎么会失败?我的 &offset
变量没有任何问题,因为如果这是 NULL
我会得到同样的错误,或者如果我将 fileFd
替换为没有错误memFd
的位置。同样有趣的是,如果我用 0(要写入的字节数)替换 128,则没有错误。返回 EFAULT
的地方,我只是看不到文件描述符是如何影响该逻辑的,除非 EFAULT
被一些更深层次的函数调用返回。 .
这些是 splice.c
SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in,
int, fd_out, loff_t __user *, off_out,
size_t, len, unsigned int, flags)
{
long error;
struct file *in, *out;
int fput_in, fput_out;
if (unlikely(!len))
return 0;
error = -EBADF;
in = fget_light(fd_in, &fput_in);
if (in) {
if (in->f_mode & FMODE_READ) {
out = fget_light(fd_out, &fput_out);
if (out) {
if (out->f_mode & FMODE_WRITE)
error = do_splice(in, off_in,
out, off_out,
len, flags);
fput_light(out, fput_out);
}
}
fput_light(in, fput_in);
}
return error;
}
static long do_splice(struct file *in, loff_t __user *off_in,
struct file *out, loff_t __user *off_out,
size_t len, unsigned int flags)
{
struct pipe_inode_info *ipipe;
struct pipe_inode_info *opipe;
loff_t offset, *off;
long ret;
ipipe = get_pipe_info(in);
opipe = get_pipe_info(out);
if (ipipe && opipe) {
if (off_in || off_out)
return -ESPIPE;
if (!(in->f_mode & FMODE_READ))
return -EBADF;
if (!(out->f_mode & FMODE_WRITE))
return -EBADF;
/* Splicing to self would be fun, but... */
if (ipipe == opipe)
return -EINVAL;
return splice_pipe_to_pipe(ipipe, opipe, len, flags);
}
if (ipipe) {
if (off_in)
return -ESPIPE;
if (off_out) {
if (!(out->f_mode & FMODE_PWRITE))
return -EINVAL;
if (copy_from_user(&offset, off_out, sizeof(loff_t)))
return -EFAULT;
off = &offset;
} else
off = &out->f_pos;
ret = do_splice_from(ipipe, out, off, len, flags);
if (off_out && copy_to_user(off_out, off, sizeof(loff_t)))
ret = -EFAULT;
return ret;
}
if (opipe) {
if (off_out)
return -ESPIPE;
if (off_in) {
if (!(in->f_mode & FMODE_PREAD))
return -EINVAL;
if (copy_from_user(&offset, off_in, sizeof(loff_t)))
return -EFAULT;
off = &offset;
} else
off = &in->f_pos;
ret = do_splice_to(in, off, opipe, len, flags);
if (off_in && copy_to_user(off_in, off, sizeof(loff_t)))
ret = -EFAULT;
return ret;
}
return -EINVAL;
}
最佳答案
mmap
内存区域,然后使用常规的write
或 vmsplice
关于c - 如何拼接/dev/mem?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35420286/
.splice() 方法的基本问题,以及如何最好地从数组中删除元素。 我想使用 .splice() 从数组中删除一个项目,但是当我这样做时,我希望返回原始数组 减去 删除的元素。 .splice()
我正在过滤同位素库。单击按钮会添加到称为过滤器的数组中。这是正常工作的,但是当用户单击事件按钮时,我希望从数组中删除过滤的类别。由于某种原因,事实并非如此。 这是特定的代码: if($(this).h
几个月前,我将一个 Subversion 存储库转换为 Mercurial,结果在我的修订历史中留下了两个毫无意义的空白。我试图弄清楚我是否可以拼接间隙,但我一直无法让工具精确地完成我想要的。 在项目
我制作简单的射击游戏,但有一个问题(有时): GIF Game problem 3颗子弹被移除(但只有一颗子弹相撞)。子弹和敌人(蓝色方 block )位于一个数组中(var objects = []
假设我们在 JavaScript 中有两个数组,[3,4,7] 和 [5,6]。 在不排序或使用 .apply 的情况下,将 [5,6] 插入索引 2 处的 [3,4,7] 的最佳方式是什么实现结果数
我试图在从数组中删除项目时添加纸质警报对话框,但我似乎无法理解这是如何工作的。 我现在可以使用以下功能,无需对话框: _delete(e) { var index = this.t
我正在尝试使用 splice() 从 jQuery 对象中删除元素. 但是,最终发生的情况是所有其他项目都被删除。我假设这是由于使用 splice 重新索引造成的。 我要淡入每个 所以我需要从顶部开始
这是我尝试从数组中动态删除一个值的尝试 $('.btn-remove').click(function() { var players = ["compare","13076","13075"
我正在考虑在 Visual Studio 2008 上使用 OpenCV 2.3.1 实时拼接来自 2 个或更多(目前可能是 3 或 4 个)摄像头的图像。 但是,我很好奇它是如何完成的。 最近研究了
我在将两个数组拼接在一起时遇到问题。假设我有两个数组: a = array([1,2,3]) b = array([4,5,6]) 当我执行 vstack((a,b)) 时,我得到了 [[1,2,3]
我拼接 css 文件以提高性能。 现在我想包含一个 minify 函数,如下所示。我该如何合并它? function minify( $css ) { $css = preg_replace(
我有两个 matlab 向量。第一个有 N 个元素,另一个有 k*N。我知道 k 是什么,我想拼接列表,使第一个向量中的每个元素出现在下一个向量中相应的 k 元素之前。例如: k = 3 x = [1
我有以下上下文: https://jsfiddle.net/eqntaqbt/2/ obj.forEach(function(user, index){ var userName = user
假设你有一个像这样的数组: var arr= [{id:121, v:'a'}, {id:232, 'b'}]; 你需要找到 id: 232 并删除它,所以你可以这样做: for (var i = a
似乎是通过 建立报价语法非常低效。例如创建一个整数列表 let q1 = List.foldBack (fun n acc -> ) [1..100000] Real: 00:00:05.714,
我正在为一家希望为其用户创建服务的公司开发应用程序。该公司目前提供时长约为 1.5 小时的视频,他们想要集成的服务是让用户能够“录制”这个较大视频的剪辑,以创建本质上的精彩片段。此服务的最终结果将是
splice 当 OFFSET 在数组中但 LENGTH 的末尾超过数组末尾时,是否可以? 最佳答案 易于尝试。 $ perl -wE' my @a = "a".."e"; my @b =
以前从未使用过 Tkinter,我不太确定如何使用它或它是如何工作的。 Windows IDLE Shell。 import time from tkinter import * input("Pre
这里是 Javascript 新手 -- 我有以下数组: var group = ({ one: value1, two: value2, three:
我的屏幕上打印了以下行: Would you like to pay €xx to POS_ID Latte X 1....€2.50-Salad X 1....€4.00-Wrap X 1..
我是一名优秀的程序员,十分优秀!