Skip to main content
 首页 » 编程设计

crash之简单的 linux 设备驱动程序打开调用崩溃

2025年12月25日39JeffreyZhao

根据google和ldd3的一些引用,我正在尝试学习如何在linux中编写设备驱动程序。我可以在下面插入模块,但是当我尝试在应用程序中打开设备时,内核崩溃了。

代码和构建步骤如下:

#include <linux/module.h>       /* Needed by all modules */ 
#include <linux/kernel.h>       /* Needed for KERN_INFO */ 
#include <linux/init.h>         /* Needed for the macros */ 
#include <linux/ioport.h> 
#include <asm/io.h> 
#include <linux/interrupt.h> 
#include <linux/sched.h> 
#include <linux/string.h> 
#include <linux/delay.h> 
#include <linux/errno.h> 
#include <linux/types.h> 
#include <asm/uaccess.h> 
#include <asm/irq.h> 
#include <asm/param.h> 
#include <linux/fs.h> 
/* =============== Constant Definitions ============ */ 
#define SERIAL_IRQ 4 
/* =============== Variable Definitions ============ */ 
static int SER_MAJOR =  0; 
int ser_open(struct inode *inode, struct file *filp); 
int ser_release(struct inode *inode, struct file *filp); 
 
irqreturn_t my_ser_dev_isr(int irq,void *ser_data,struct pt_regs * pt_reg_var) 
{ 
printk("\n\n -------   INTR raised   -----------\n\n"); 
return 0; 
} 
 
int ser_open(struct inode *inode, struct file *filp) 
{ 
if(request_irq(SERIAL_IRQ,&my_ser_dev_isr,1,"my_ser_dev_intr",NULL)) 
{ 
printk("\n interrupt req failed\n"); 
} 
else 
{ 
enable_irq(SERIAL_IRQ); 
printk("\n!!!!  ..obtained the requested interrupt and enabled\n"); 
} 
} 
int ser_release(struct inode *inode, struct file *filp) 
{ 
disable_irq(SERIAL_IRQ); 
free_irq(SERIAL_IRQ,NULL)   ; 
} 
static struct file_operations ser_fops = { 
open: ser_open, 
release: ser_release 
}; 
 
void *p = NULL; 
irqreturn_t my_ser_dev_isr (int, void *, struct pt_regs *); 
static int __init hello_start(void) 
{ 
int ret_val=-1; 
int result; 
printk(KERN_INFO "Loading hello module...\n"); 
printk(KERN_INFO "Hello world\n"); 
result = register_chrdev(SER_MAJOR,"SER_DEV",&ser_fops); 
if(result < 0)  
{ 
printk(KERN_WARNING"Can't get major %d\n",SER_MAJOR); 
return result; 
} 
if(SER_MAJOR == 0) 
{ 
SER_MAJOR = result; 
printk("SER DEV Major Number : %d",SER_MAJOR );  
}    
return 0;    
} 
 
static void __exit hello_end(void) 
{ 
//  free_irq(SERIAL_IRQ,NULL); 
//release_region(0x0031,1); 
printk(KERN_INFO "Goodbye Mr.\n"); 
} 
module_init(hello_start); 
module_exit(hello_end); 

模块的生成文件:
obj-m := hello.o 
default: 
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 

用于访问的应用程序如下:
#include <stdio.h> /* test.c */ 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <errno.h> 
static int dev; 
int main(void) 
{ 
char buff[40]; 
dev = open("/dev/my_ser_dev",O_RDONLY); 
if(dev < 0)  
{ 
printf( "Device Open ERROR!\n"); 
exit(1); 
} 
printf("Please push the GPIO_16 port!\n"); 
//read(dev,buff,40); 
// scanf("%s",buff);     
printf("%s\n",buff); 
close(dev); 
return 0; 
} 

insmod 给了
[ 3837.312140] Loading hello module... 
[ 3837.312147] Hello world 
[ 3837.312218] SER DEV Major Number : 251 

然后我使用 mknod/dev/my_ser_dev c 251 0 创建了特殊文件
执行应用程序导致内核崩溃。我正在使用 UBUNTU 3.2.0-23-generic-pae。

请您参考如下方法:

您注册为 IRQ 处理程序的函数有错误的原型(prototype) - 它应该像

irqreturn_t irq_handler(int, void *); 

也许您指的是旧文档。