[root@linux /var]# ./port
open snesor_port driver OK !
Unable to handle kernel NULL pointer dereference at virtual address 0000002b
pgd = c2e48000
[0000002b] *pgd=33d26031, *pte=00000000, *ppte=00000000
Internal error: Oops: 13 [#1]
Modules linked in:
CPU: 0
PC is at sys_open+0x6c/0xd0
LR is at dput+0x24/0x2d0
pc : [
] lr : [] Not tainted
sp : c0701f80 ip : c0701ee4 fp : c0701fa4
r10: c394a000 r9 : c0700000 r8 : 00000023
r7 : 00000000 r6 : 00000003 r5 : bec63ebc r4 : 00000002
r3 : 0000000b r2 : 00000000 r1 : c0700000 r0 : 00000003
Flags: nZCv IRQs on FIQs on Mode SVC_32 Segment user
Control: 317F Table: 32E48000 DAC: 00000015
Process port (pid: 808, stack limit = 0xc0700194)
Stack: (0xc0701f80 to 0xc0702000)
1f80: bec63eb4 4001c2dc 00008538 00000005 c00350e4 4013e6bc 00000000 c0701fa8
1fa0: c0034f60 c0089a44 bec63eb4 c003c9e8 0000861c 00000002 bec63ebc 00000000
1fc0: bec63eb4 4001c2dc 00008538 00000001 4013fb5c 00008400 4013e6bc bec63e84
1fe0: 00000000 bec63e64 00001920 400de230 60000010 0000861c 00000000 00000000
Backtrace:
[] (sys_open+0x0/0xd0) from [] (ret_fast_syscall+0x0/0x2c)
Code: 0a000002 ebffffad e1a06008 ea000011 (e5980008)
Segmentation fault
自己做的一个电平检测驱动 ,加入到内核没有问题,但是一调用就出现上面的错误:
解决:
查驱动代码,发现open没有return ;加上就OK了
代码很简单,如下:
/------------code -------------------/
#include
#include
#include
#include
#include
#include /* printk() */
#include /* everything... */
#include
#include /* request_irq() */
#include
#include
#include
#include /* copy_to_user() */
#include /* mdelay() */
#define DEVICE_NAME "sensor_port"
#define PORT_MINOR 237
#define DEBUG_LVL KERN_DEBUG
//#define PORT_DEBUG
MODULE_LICENSE("GPL");
/* 中断号 IO脚 键号 配置成输入脚 配置成中断脚 */
/* { IRQ_EINT0, S3C2410_GPF0, 1 , S3C2410_GPF0_INP, S3C2410_GPF0_EINT0},*/
static struct key_info {
unsigned int irq_no; /*中断号*/
unsigned int gpio_port; /*IO脚*/
unsigned int key_no; /*键号*/
unsigned int IN; /*配置成输入IO脚*/
unsigned int EINT; /*配置成中断脚*/
} key_info_tab[5] = {
{ IRQ_EINT1, S3C2410_GPF1, 2 , S3C2410_GPF1_INP, S3C2410_GPF1_EINT1},
{ IRQ_EINT2, S3C2410_GPF2, 3 , S3C2410_GPF2_INP, S3C2410_GPF2_EINT2},
{ IRQ_EINT3, S3C2410_GPF3, 4 , S3C2410_GPF3_INP, S3C2410_GPF3_EINT3},
{ IRQ_EINT11, S3C2410_GPG3, 5 , S3C2410_GPG3_INP, S3C2410_GPG3_EINT11},
{ IRQ_EINT19, S3C2410_GPG11, 6 , S3C2410_GPG11_INP,S3C2410_GPG11_EINT19},
#if 0
{ IRQ_EINT4, S3C2410_GPF4, 7, S3C2410_GPF4_INP, S3C2410_GPF4_EINT4},
{ IRQ_EINT5, S3C2410_GPF5, 8, S3C2410_GPF5_INP, S3C2410_GPF5_EINT5},
{ IRQ_EINT6, S3C2410_GPF6, 9, S3C2410_GPF6_INP, S3C2410_GPF6_EINT6},
{ IRQ_EINT7, S3C2410_GPF7, 10, S3C2410_GPF7_INP, S3C2410_GPF7_EINT7},
#endif
};
struct key_info *k;
int ready=0;
static int s3c2440_sensor_port_open(struct inode *inode,struct file *filp)
{
#ifdef PORT_DEBUG
printk("<1>open snesor_port driver OK !\n");
#endif
return 0;
}
static int s3c2440_sensor_port_ioctl(struct inode *inode,struct file *file,unsigned int cmd, unsigned long arg)
{
if(cmd>6||cmd<0)
return -EINVAL;
k=key_info_tab+cmd;
#ifdef PORT_DEBUG
printk("<1>cmd=%d k->key_no=%d\n",cmd,k->key_no);
#endif
ready=1;
return 0;
}
static int GetSensorID(int channel)
{
int id=0x4;
return id;
}
static ssize_t s3c2440_sensor_port_read(struct file *filp,char *buffer,size_t count ,loff_t *ppos)
{
unsigned long flags;
int up,id=0,channel=0;
int uiValue=0;
if(!ready)
return 0;
ready=0;
local_irq_save(flags);
// s3c2410_gpio_cfgpin(k->gpio_port,k->IN);
up = s3c2410_gpio_getpin(k->gpio_port);
local_irq_restore(flags);
id=0;
channel=0;
uiValue=0;
if(!up)
{
id=GetSensorID(k->gpio_port);
channel=k->key_no;
uiValue=((channel&0xff)<<8)|id;
#ifdef PORT_DEBUG
printk("<1> id = 0x%x, channel = 0x%x ,uiValue=0x%x \n",id,channel,uiValue);
#endif
copy_to_user(buffer,&uiValue,sizeof uiValue);
}
#ifdef PORT_DEBUG
printk("sizeof uiValue = 0x%x \n",sizeof uiValue);
#endif
return sizeof uiValue;
}
static struct file_operations s3c2440_sensor_port_fops =
{
.owner = THIS_MODULE,
.read = s3c2440_sensor_port_read,
.open = s3c2440_sensor_port_open,
.ioctl = s3c2440_sensor_port_ioctl,
};
static struct miscdevice s3c2440_sensor_port_dev=
{
PORT_MINOR,
DEVICE_NAME,
&s3c2440_sensor_port_fops,
};
static int __init s3c2440_sensor_port_init(void)
{
misc_register(&s3c2440_sensor_port_dev);
printk("<1>add s3c2440 sensor port driver success!\n");
return 0;
}
static void __exit s3c2440_sensor_port_exit(void)
{
misc_deregister(&s3c2440_sensor_port_dev);
printk(KERN_ALERT"s3c2440_adc driver unregister \n");
}
module_init(s3c2440_sensor_port_init);
module_exit(s3c2440_sensor_port_exit);
/------------------------ end code ----------------------------/