Articles of linux device driver

在Linux上debugging一个简单的字符驱动程序在device_create()上失败

我写了一个简单的字符驱动程序,现在想在udev中使用类自动注册它。 我的代码由驱动程序加载时调用的init函数和驱动程序加载其设备时调用的probe函数组成(当然还有它们的等价的exit和remove )。 问题:一旦添加新设备,执行device_create命令时,我的probefunction失败。 现在我想知道为什么: 我怎么能得到更多的信息,为什么这个命令失败(除了失败)? 缺less任何参数(比如我的全局声明fooClass是否存在问题,是否应该将其移至probe函数,而不是在我眼中做出反应,但在许多示例中显示)? 还是其他监督错误? 我的代码我剥离了大多数返回validation(如IS_ERR() )和清理function的可读性。 这两个variables是全局定义的: static int foo_majNbr; static struct class *fooClass; init函数: static int __init foo_init(void) { int rv; dev_t devNbr; /* Registering driver */ rv = pci_register_driver(&foo_driver); /* —-> see answer below for correct order <—- */ /* Create device class */ fooClass = class_create(THIS_MODULE, CLASS_NAME); /* […]

Linux内核模块编程:makefile

在学习Linux内核模块的同时,我可以看到两种方式来编写Makefile。 第一个是这样的: ifneq ($(KERNELRELEASE),) obj-m := module.o else default: $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules endif 后者不那么复杂: obj-m := module.o all: $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules makefile编译导致成功编译模块 。 我的学习伴随着LDD3书,至今我读到的是下一个: 这个makefile在典型的版本上被读取两次。 当从命令行调用makefile时,会注意到KERNELRELEASEvariables没有被设置。 它通过利用已安装模块目录中的符号链接构build指向内核构build树的事实来定位内核源代码目录。 如果你实际上没有运行正在构build的内核,你可以在命令行提供一个KERNELDIR =选项,设置KERNELDIR环境variables,或者重写在makefile中设置KERNELDIR的行。 一旦find内核源代码树,makefile会调用默认:target,它将运行第二个make命令(在makefile中参数化为$(MAKE))来调用内核构build系统,如前所述。 在第二次阅读时,makefile设置obj-m,内核makefiles负责实际构build模块。 如果makefile被读取两次,那么第二种方法应该导致recursion,不是吗?

在设备驱动程序中使用stdlib.h

我试图写一个设备驱动程序,我需要在驱动程序中使用system()函数。 要使用system()我们需要包含<stdlib.h> ,这个dosnt似乎是从驱动程序中运行的。 它说没有find这样的文件或目录。 是否有替代stdlib.h设备驱动程序? 或system()的替代?

i2c驱动程序是否需要像其他字符设备驱动程序一样执行?

我是Linux设备驱动程序的noob,所以请耐心等待。 我试图实现一个i2c驱动程序(客户端)。 这是我可以insmod , .probe被调用(因为设备树条目),并在.probe我可以读/写设备。 大。 不过,我需要能够从用户空间启动读取/写入驱动程序。 为了做到这一点,一个i2c驱动程序应该像任何其他字符设备驱动程序的形状? 意思是有一个file_operations结构,所以用户空间可以open , close , read , write和ioctls ? 我在问,因为在我见过的所有i2c客户端例子中,没有人实现我提到的这些东西。 我想知道他们如何发起呼叫从用户空间没有file_operations结构设置。 也许这是如此明显,没有人提到它,我不知道…我想知道是不是因为i2c被称为平台设备驱动程序,它不需要这个? 如果有人可以证实,将帮助我第二次猜测自己。 如果你明白我在问什么,请忽略其余部分。 如果你对我的问题感到困惑,这里是我所问的更具体的解释: 我现在所拥有的: static int device_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device *dev = &client->dev; struct device_data *data; /* Check the functionality of the i2c-adapter for smbus byte read/write */ if (!i2c_check_functionality(client->adapter, […]

如何将matrix_keypad.h文件用于自定义键盘驱动程序?

我可以用input_dev来模拟一个自定义键盘(来自input.h) //an example with just one key. button_dev = input_allocate_device(); if (!button_dev) { printk(KERN_ERR "button.c: Not enough memory\n"); error = -ENOMEM; goto err_free_irq; } button_dev->evbit[0] = BIT_MASK(EV_KEY); button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); 或者我将不得不使用matrix_keypad头文件?如果是,那么如何?

从内核读取使用procfs的时间戳 – 从内核读取后存储在哪里?

当中断发生在内核和如果我正在读取内核中的时间戳。 我正在通过procfs从内核读取用户的时间戳。 中断时间值将被存储在哪里? 用户应该如何从用户空间读取该值? ssize_t dev_read(struct file *filp,const char *buf,size_t count,loff_t *offset) { if ( count < sizeof(InterruptTime) ) { // Not enough space provided. return 0; // Or some error code maybe. } if (copy_to_user(buf,&InterruptTime,sizeof(InterruptTime)) { return -EFAULT; } else { return sizeof(InterruptTime); // Number of bytes we copied. } } 这是我在/linuxversion/net/core/dev.c中修改的代码 int netif_rx(struct […]

何时使用linux内核的add_timer vs queue_delayed_work

要在Linux内核驱动程序中安排稍后的操作,我有两个选项: add_timer queue_delayed_work 我所知道的一个区别是:对于计时器,您需要指定计时器到期时的jiffies值,因为延迟工作,您需要指定jiffies的延迟。 我一直在阅读有关定时器和work_queue的其他问题 ,并提到定时器在stream程上下文之外运行。 这与延误工作有何不同? 另外我知道定时器有一个问题,在计算expires ,可能会发生数值溢出,所以计算的值比当前的jiffies小,定时器立即过期(纠正我,如果我在这里错了)。 迟到的工作是否遭受同样的问题? 如果是这样,怎么办 对我来说,使用延迟工作似乎更容易(因为工作不是定期的)。 但是使用定时器有什么缺点? 编辑我做了一些进一步的研究。 看来queue_delayed_work只是add_timer内部使用add_timer 。 所以我的新问题是,如何正确处理定时器的溢出问题? 例如,我如何设置一个计时器/ delayed_work延迟10分钟?

linux一次读取一个大于4KB的块(或每块4KB)是正常的吗?

我正在写一个networking连接的硬盘驱动器的设备驱动程序,我的问题是,我可以看到,Linux发送请求到我的块设备,超过了典型的4KB请求。 其实我可以注意到的是 它先发送一个4kB的请求,然后第二个请求的大小是8KB,然后是16KB,依此类推。 有什么办法可以禁止这种行为,限制Linux一次发送4KB的请求吗? 或者在我的代码中这是不好的? 我如何计算请求总大小:我有扇区大小设置为512字节。 当我根据任何请求调用blk_rq_sectors ,我会得到该请求中所述的扇区数。 有时,我看到请求包含8,16,32或64个扇区。 谢谢。

ioread32后跟iowrite32没有给出相同的价值

我已经开始学习Linux设备驱动程序。 我正在做一些示例程序作为我学习的一部分。 为了理解内存映射IO,我写了下面的代码(这里只显示init)。 没有硬件映射在基地址。 static unsigned long base = 0xfed00000; unsigned long device_base=0; unsigned long virtual_base=0; static int __init sharedirqmodule_init(void) { u32 register1=0; u32 value=0x23456789; device_base=base; void *address=0; if(!request_mem_region(device_base,8,"device")) return -ENODEV; virtual_base = (unsigned long) ioremap(device_base, 8); address=(void *)virtual_base; printk(KERN_ERR "Sharedirq : Address value: %lx\n",address); iowrite32(value,address); wmb(); register1=(u32)ioread32(address); rmb(); printk(KERN_ERR "Shared irq :value: %d \n",register1); […]

有关内核中的workqueue的一些标志

我正在处理Linux内核2.6.36中的并发pipe理工作队列。但是我对一些标志感到困惑。 WQ_HIGHPRI WQ_UNBOUND WQ_RESCUER WQ_CPU_INTENSIVE 我创build了一个带有标志WQ_HIGHPRI工作队列,并将一些工作项目(例如w1 w2 w3 w4,按顺序)排队,这四个工作项目都不会进入hibernate状态。 4个工作项是否由同一个线程执行,在这种情况下是否创build了任何线程? 在上面的情况下,如果使用WQ_UNBOUND ,是否有区别? 因为如果你设置了WQ_UNBOUND ,那么内核将设置WQ_HIGHPRI 。 先谢谢你。