Articles of 驱动程序

有没有用PCIe for FPGA的DMA Linux内核驱动例子?

我想在内核空间编写一个驱动程序: 在embedded式系统中使用PCIe连接FPGA(使用powerPC)。 它使用DMA将信息从FPGA传输到RAM。 用户程序必须访问这些信息。 我需要一些类似的例子来指导我。 有没有人有任何想法,我可以find一些来源?

如何为具有未caching的DMA缓冲区的字符设备文件实现splice_read

我有一个字符设备驱动程序。 它包括一个4MB相干DMA缓冲区。 缓冲区实现为环形缓冲区。 我也执行splice_read调用驱动程序来提高性能。 但是这个实现不太好。 下面是使用示例:(1)将16页的设备缓冲区数据拼接到pipefd [1]。 (DMA缓冲区按照页面单位进行pipe理)。 (2)将pipefd [0]拼接到插槽。 (3)接收方(tcp client)接收数据,然后检查正确性。 我发现tcp客户端有错误。 splice_read的实现如下所示(我从vmsplice实现中窃取它): /* splice related functions */ static void rdma_ring_pipe_buf_release(struct pipe_inode_info *pipe, struct pipe_buffer *buf) { put_page(buf->page); buf->flags &= ~PIPE_BUF_FLAG_LRU; } void rdma_ring_spd_release_page(struct splice_pipe_desc *spd, unsigned int i) { put_page(spd->pages[i]); } static const struct pipe_buf_operations rdma_ring_page_pipe_buf_ops = { .can_merge = 0, .map = […]

Linux中的dmaengine – 如何检查一次SG传输中实际传输的字节数?

Linux中的dmaengine显着简化了使用DMA的设备驱动程序的编写,特别是在支持和使用分散 – 聚集(SG)传输的情况下。 但是,如果这种转移的时间不是事先知道的,则会有问题。 这种情况相当普遍。 这可能发生在USB传输的情况下,或者在AXIstream传输的情况下。 在AXI Stream连接设备的情况下,应通过将tlast信号设置为'1'来终止传输。 驱动程序应该准备缓冲区以尽可能长的传输,但传输完成后,它应该能够find实际传输的字节数。 不幸的是,似乎没有书面的方式来读取完成的转移的长度。 单次传输由一个SG表格表示 ,后者被转换成dma_async_tx_descriptor ,使用dmaengine_prep_slave_sg函数提交到DMA层(例如这里 ),最后通过dma_async_issue_pending调度执行。 之后,只能通过dmaengine_prep_slave_sg函数返回的dma_cookie来访问传输描述符。 USB传输报告了确定传输实际长度的问题,并提出了将transferred字段添加到dma_async_tx_descriptor的补丁 。 然而,该提议被拒绝,并讨论了基于使用dmaengine_tx_status的解决scheme ,并检查返回的dma_tx_state结构中的residue字段。 不幸的是,所提出的解决scheme似乎不适用于4.4内核(用于Xilinx SoC器件)和最新的4.7内核。 无论传输字节的实际数量如何,在完成传输的情况下, residue字段设置为0 。 所以我的问题是:如何在dmaengine兼容的驱动程序中可靠地确定完成的SG DMA传输中的实际传输字节数? PS。 Xilinx论坛上也提出了有关AXI DMA IP内核的更多Xilinx特定细节的问题。

内核如何在文件外部调用模块中的静态init和exit函数?

我正在读LDD3,并对__init和__exit函数调用中静态存储类的使用有疑问。 http://static.lwn.net/images/pdf/LDD3/ch02.pdf “初始化函数应该被声明为静态的,因为它们并不意味着在特定文件之外是可见的;但是没有关于这个的硬性规则,因为没有函数被导出到内核的其余部分,除非明确地请求” 但是内核可以使用insmod和rmmod系统调用来使用init和exit函数。 如果静态函数是仅对同一文件中的其他函数可见的函数,那么内核如何能够使用在我们的模块中定义为static的__init和__exit函数?

是__alloc_pages_slowpath()可重入安全吗?

对__alloc_pages_slowpath()的调用是否能够经历一个设备中断,该设备中断还会调用__alloc_pages_slowpath(),或者第二个调用是否会破坏第一个调用? 我在XFS文件系统上看到一个读取(2)常规文件的程序调用。 内核堆栈跟踪显示,最终__alloc_pages_slowpath()被调用,然后一个e1000e IRQ发生,最终还会调用__alloc_pages_slowpath(),然后一个日志消息“fooprog:page allocation failure.order:0,mode:0x4020”几乎立即发生。 整个堆栈跟踪可以在这里看到: https : //gist.github.com/790577

Linux Uart驱动程序修改

我想修改我的Linux内核的(2.6.32)UART驱动程序。 我使用ttyS2的标准uart驱动程序我不知道确切的文件。 问题很简单,在传输过程中将gpio引脚设置为高电平,同时接收电平必须很低。 我应该参考哪些文件? 任何有关从uart驱动程序跳出gpio的想法都是很好的… 问候。

如何在内核scsi_device结构中区分USB和(S)ATA设备?

根据SCSI驱动程序(内核2.6.23)使用的内核结构struct scsi_device : http://lxr.linux.no/linux+v2.6.23/include/scsi/scsi_device.h#L49 如果设备是USB设备还是ATA设备,有没有可靠的方法来区分?

Linux PCIe设备驱动程序读/写function对某些地址不起作用

我写了一个PCIe设备驱动程序,读/写function无法正常工作。 该器件有3个存储区,从0x10800000,0x0c000000和0x80000000开始。 仅用于testing目的,驱动程序中的读取和写入function将打印出传递的地址并返回。 如果我从用户空间应用程序调用pread()或者pwrite(),我会看到前两个内存区域的地址,但是如果我调用第三个内存区域,我什么也看不到,甚至可以input驱动程序的读取或写入function。 我的驱动程序在运行Linux版本2.6.32的64位机器上工作得很好。 这个不能工作的另一台机器是运行linux 2.6.25版的32位机器。 我的想法是,也许32位不喜欢0x80000000地址,但我不知道如何validation或如何解决这个问题。

SPI:Linux驱动程序模型

我是新来的SPI; Linux内核提供了用于声明SPI总线和设备的API,并根据标准的Linux驱动程序模型进行pipe理。 你可以在这里findstruct spi_master的描述: https ://www.kernel.org/doc/htmldocs/device-drivers/API-struct-spi-master.html 上面的链接描述说:“每个设备可能被configuration为使用不同的时钟频率,因为除非select芯片,否则这些共享信号将被忽略”。 要把这个句子放在比赛中,我不得不说,“设备”是指SPI从设备,而“那些共享信号”是指MOSI,MISO和SCK信号。 实际上,在struct spi_device( https://www.kernel.org/doc/htmldocs/device-drivers/API-struct-spi-device.html )中,有一个名为max_speed_hz的属性,它不存在于struct spi_master 。 所以我可以理解上面的声明的第一部分:“每个设备可能被configuration为使用不同的时钟频率”。 但是,第二部分是什么意思呢? 是否“因为这些共享信号被忽略,除非芯片被选中”意味着我可以使用不同的时钟速率,但只有一个时间通过启用/禁用不同速率的奴隶? 感谢您的帮助! 问候, – Matteo

无法将某些红外遥控钥匙代码传递给Android

我正尝试使用红外遥控器将某些键码传递给Android。 到目前为止,我可以通过数字键(0-9)和D-pad键(上,下,左,右,进入)。 现在我试图扩展键包括其他字符,如az。 我正在修改的代码是Android的Linux内核部分的IR驱动程序。 这与这个驱动程序相似。 但是,当我传递一个像KEY_A(在Linux的include / linux / input.h中定义的“a”到30:定义的值 )时,Android不会看到它。 传递命令的代码段如下: input_report_key(cir->input, cir->last_key, 1); input_report_key(cir->input, cir->last_key, 0); input_sync(cir->input); 当我打印cir-> last_key时,当按下“a”button时,可以看到数值30。 不过,我不知道如何跟踪从这里到Android的代码,以查看button被删除的位置。 在Android中,我有一个名为/system/usr/keylayout/qwerty.kl的文件,将值映射到30个映射到“a”。 问题是,当我按下“a”时,Android从未获得30的值。