Tag: linux device driver

尽管在Linux内核模块中使用EXPORT_SYMBOL,如何防止“错误:’符号’未声明”?

当我收到此错误时,我将一些驱动程序嵌入到Linux内核中(我在板文件中添加设备并注册它): error: ‘kxtf9_get_slave_descr’ undeclared here (not in a function) 我将上面的函数放在驱动程序文件中 struct ext_slave_descr *kxtf9_get_slave_descr(void) { return &kxtf9_descr; } EXPORT_SYMBOL(kxtf9_get_slave_descr); 它不应该由EXPORT_SYMBOL“可见”吗? 包含上面代码的C文件没有头文件(我没有写它,我只是在这里找到它并且我正在实现。他们说它已经过测试所以我假设不需要头文件? 其余代码编译完美(因此它“看到”文件夹中的代码),包含上面代码的文件也编译完成!

copy_to_user vs memcpy

我一直被告知(在书籍和教程中),在将数据从内核空间复制到用户空间时,我们应该使用copy_to_user()并使用memcpy()会给系统带来问题。 最近我错误地使用了memcpy(),它可以很好地解决任何问题。 为什么我们应该使用copy_to_user而不是memcpy() 我的测试代码(内核模块)是这样的: static ssize_t test_read(struct file *file, char __user * buf, size_t len, loff_t * offset) { char ani[100]; if (!*offset) { memset(ani, ‘A’, 100); if (memcpy(buf, ani, 100)) return -EFAULT; *offset = 100; return *offset; } return 0; } struct file_operations test_fops = { .owner = THIS_MODULE, .read = test_read, }; static […]

哪里用volatile?

我读过volatile关键字,但我不知道在什么情况下我应该使用它。 当内存(变量)得到更新并且进程没有意识到这一点? 在什么情况下驱动程序应该使用volatile变量?

在编写linux驱动程序时,ERESTARTSYS使用了什么?

我正在学习用于编写linux设备驱动程序的阻塞I / O函数,我想知道ERESTARTSYS的用法是ERESTARTSYS 。 考虑以下: 全局变量: wait_queue_head_t my_wait_q_head; int read_avail = 0; device_init(): init_waitqueue_head(&my_wait_q_head); device_read(): printk(“I’m inside driver read!\n”); wait_event_interruptible(&my_wait_q_head, read_avail != 0); printk(“I’m awaken!\n”); device_write(): read_avail = 1; wake_up_interruptible(&my_wait_q_head); 当我从用户空间调用read() ,命令提示符挂起,直到我按预期调用write() 。 printk消息也相应地出现在dmesg 。 但是,我看到一些像这样编写的驱动程序: 另一个版本的device_read(): printk(“I’m inside driver read!\n”); if(wait_event_interruptible(&my_wait_q_head, read_avail != 0)) {return -ERESTARTSYS;} printk(“I’m awaken!\n”); 我在用户空间中使用相同的方法测试了第二个版本的device_read() ,结果完全相同,那么,ERESTARTSYS的用途是什么? p / s:我已经阅读了这本书上的Linux设备驱动程序,但是我没有得到它,有人可以举例来说明吗?: 一旦我们通过那个电话,有些东西唤醒了我们,但我们不知道是什么。 […]

Linux设备驱动程序中的静态函数

为什么大多数设备驱动程序中的每个function都是静态的? 由于静态函数在文件范围之外不可见。 然后,这些驱动程序函数如何被用户空间应用程序调用?

如何使用net_dev_add()API过滤和拦截Linux数据包?

我正在为linux编写以太网网络驱动程序。 我想接收数据包,编辑并重新发送它们。 我知道如何在packet_interceptor函数中编辑数据包,但是如何在此函数中丢弃传入的数据包? #include #include #include #include struct packet_type my_proto; int packet_interceptor(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) { // I dont want certain packets go to upper in net_devices for further processing. // How can I drop sk_buff here?! return 0; } static int hello_init( void ) { printk(KERN_INFO […]

device_register和driver_register之间的区别

我正在写一个UART驱动程序。 我在第14章.Linux设备模型中遇到了两个函数。 int device_register(struct device *dev); int driver_register(struct device_driver *drv); 由于UART是一个char驱动程序,我使用( alloc_chrdev_region)动态创建了主要数字,并使用cdevadd()将设备添加到内核。 我在omap-serial.c中遇到了uart_register_driver()和platform_driver_register() 。 我可以使用platform_driver_register()映射driver_register ,但是uart_register_driver与tty相关函数映射。因为我是初学者,我不想使用tty相关函数。 uart_register_driver与uart_register_driver device_driver()吗? 请解释。

如何在内核模块代码中包含C backtrace?

所以我试图找出哪些内核进程正在调用块驱动程序中的某些函数。 我认为在C库中包含backtrace()会让它变得简单。 但我无法加载回溯。 我复制了这个示例函数来显示回溯: http://www.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/063/6391/6391l1.html 所有编译尝试都在一个或另一个地方发生错误,导致无法找到文件或未定义函数。 这是最接近的。 在Makefile中我放了编译器指令: -rdynamic -I/usr/include 如果我省略第二个,-I / usr / include,那么编译器报告它找不到所需的头文件execinfo.h。 接下来,在我想要做回溯的代码中,我从示例中复制了该函数: //trying to include the c backtrace capability #include void show_stackframe() { void *trace[16]; char **messages = (char **)NULL; int i, trace_size = 0; trace_size = backtrace(trace, 16); messages = backtrace_symbols(trace, trace_size); printk(KERN_ERR “[bt] Execution path:\n”); for (i=0; i<trace_size; ++i) […]

以编程方式获取Linux平台上USB设备的供应商ID,产品ID

我一直在尝试编写一个简单的设备驱动程序,我在其中以编程方式获取供应商ID和产品ID。 经过几乎所有必要的头文件后,我得出结论,我可以通过以下结构访问USB设备的供应商ID,产品ID和制造商详细信息: struct usb_device{} ,其中包含成员struct usb_device_descriptor{} 。 这个嵌套结构有idVendor, idProduct和iManufacturer以及其他一些成员。 但不知何故,由于某种原因,我无法访问这些成员,所以当我插入我的模块后执行dmesg ,它会打印一些垃圾值。 我很乐意收到帮助或提示或任何回复。 以下是我到目前为止编写的代码: PS:已经制作了必要的内容。 经过几乎所有必要的头文件后,我知道我可以通过以下结构访问USB设备的供应商ID,产品ID和制造商详细信息: struct usb_device{} ,其中包含成员struct usb_device_descriptor{} 。 这个嵌套结构有idVendor, idProduct和iManufacturer以及其他一些成员。 //******************************************* struct usb_device udev; struct usb_bus *bus; ssize_t ret; static int __init usb_fun_init(void) { int result; __le16 idVendor = 0; __le16 idProduct = 0; __u8 iManufacturer = 0; printk(KERN_INFO “\n************************************ in init\n”); list_for_each_entry(bus, […]

request_mem_region()实际上做什么以及何时需要它?

我正在研究编写嵌入式Linux驱动程序,并决定开发一些GPIO以确保我正确理解本书(LDD3,第9.4.1节) 。 我可以按照预期控制正确的GPIO引脚(使其高低,用万用表探测); 但是,我测试了2个代码,一个是request_mem_region() ,另一个没有。 我期待一个没有失败的人,但两个都工作得很好。 代码为request_mem_region : if( request_mem_region( PIN3_CONF_PHYS, MAPPED_SIZE_GPIO_CONF,DEVICE_NAME ) == NULL ) { printk( KERN_ALERT “GPIO_140_141_conf_phys error:%s: unable to obtain I/O memory address 0x%08llX\n”, DEVICE_NAME, PIN3_CONF_PHYS ); return -EBUSY; } pin3_conf = (u32)ioremap( PIN3_CONF_PHYS, MAPPED_SIZE_GPIO_CONF); pin4_conf = (u32)ioremap( PIN4_CONF_PHYS, MAPPED_SIZE_GPIO_CONF); pin5_conf = (u32)ioremap( PIN5_CONF_PHYS, MAPPED_SIZE_GPIO_CONF); pin6_conf = (u32)ioremap( PIN6_CONF_PHYS, MAPPED_SIZE_GPIO_CONF); //—————————————————————– […]