"unable to handle kernel NULL pointer dereference" while opening a device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



hi kernel'ers :

i have a kernel module in which i am trying to implement a simple device driver following the LDD3 book.

currently i am only trying to open and close the device node. the module compiles fine and when insmod'ed it sets up the hooks using cdev_init() and cdev_add().

then i create the device node in the /dev directory as per the major and minor number.

but when i try to open() the device node i get the following Oops message : (/var/log/messages)

====================================================================================================================

Aug 9 19:30:05 linux-ujq3 kernel: BUG: unable to handle kernel NULL pointer dereference at virtual address 00000005

Aug 9 19:30:05 linux-ujq3 kernel: printing eip:

Aug 9 19:30:05 linux-ujq3 kernel: c017340a

Aug 9 19:30:05 linux-ujq3 kernel: *pde = 00000000

Aug 9 19:30:05 linux-ujq3 kernel: Oops: 0002 [#1]

Aug 9 19:30:05 linux-ujq3 kernel: SMP

Aug 9 19:30:05 linux-ujq3 kernel: last sysfs file: /devices/system/cpu/cpu1/online

Aug 9 19:30:05 linux-ujq3 kernel: Modules linked in: skull snd_pcm_oss snd_mixer_oss snd_seq snd_seq_device iptable_filter ip_tables ip6table_filter ip6_tables x_tables ipv6 micr

ocode firmware_class apparmor nls_iso8859_1 nls_cp437 vfat fat fuse loop dm_mod snd_hda_intel snd_pcm ohci1394 8139cp snd_timer ieee1394 8139too snd parport_pc ati_agp rtc_cmos mi

i agpgart i2c_piix4 button rtc_core usb_storage soundcore sr_mod cdrom snd_page_alloc i2c_core ide_core rtc_lib parport sg sd_mod ohci_hcd ehci_hcd usbcore edd ext3 mbcache jbd fa

n pata_atiixp sata_sil libata scsi_mod thermal processor

Aug 9 19:30:05 linux-ujq3 kernel: CPU: 1

Aug 9 19:30:05 linux-ujq3 kernel: EIP: 0060:[<c017340a>] Tainted: G N VLI

Aug 9 19:30:05 linux-ujq3 kernel: EFLAGS: 00210246 (2.6.22.17-0.1-default #1)

Aug 9 19:30:05 linux-ujq3 kernel: EIP is at chrdev_open+0x79/0x133

Aug 9 19:30:05 linux-ujq3 kernel: eax: 00000001 ebx: f3f6de44 ecx: f3f6de44 edx: f3d51f64

Aug 9 19:30:05 linux-ujq3 kernel: esi: f3f6de44 edi: 00000000 ebp: f3d51e60 esp: f3f99ee0

Aug 9 19:30:05 linux-ujq3 kernel: ds: 007b es: 007b fs: 00d8 gs: 0033 ss: 0068

Aug 9 19:30:05 linux-ujq3 kernel: Process a.out (pid: 4364, ti=f3f98000 task=dff8b570 task.ti=f3f98000)

Aug 9 19:30:05 linux-ujq3 kernel: Stack: f421a3c0 00000000 f421a3c0 f3d51e60 f3f99f30 c0173391 c016f8b7 dfbf13c0

Aug 9 19:30:05 linux-ujq3 kernel: f3e8dc6c f421a3c0 ffffff9c f3f99f30 00000003 c016f9e8 f421a3c0 00000000

Aug 9 19:30:05 linux-ujq3 kernel: 0804855b c016fa2e bfa9f9d8 f3f99f30 f3e8dc6c dfbf13c0 13645c10 00000005

Aug 9 19:30:05 linux-ujq3 kernel: Call Trace:

Aug 9 19:30:05 linux-ujq3 kernel: [<c0173391>] chrdev_open+0x0/0x133

Aug 9 19:30:05 linux-ujq3 kernel: [<c016f8b7>] __dentry_open+0xc1/0x178

Aug 9 19:30:05 linux-ujq3 kernel: [<c016f9e8>] nameidata_to_filp+0x24/0x33

Aug 9 19:30:05 linux-ujq3 kernel: [<c016fa2e>] do_filp_open+0x37/0x3e

Aug 9 19:30:05 linux-ujq3 kernel: [<c016f79b>] get_unused_fd+0x57/0xb2

Aug 9 19:30:05 linux-ujq3 kernel: [<c016fa77>] do_sys_open+0x42/0xc8

Aug 9 19:30:05 linux-ujq3 kernel: [<c016fb36>] sys_open+0x1c/0x1e

Aug 9 19:30:05 linux-ujq3 kernel: [<c0104e22>] sysenter_past_esp+0x6b/0xa9

Aug 9 19:30:05 linux-ujq3 kernel: [<c02c0000>] unix_find_other+0x75/0x161

Aug 9 19:30:05 linux-ujq3 kernel: =======================

Aug 9 19:30:05 linux-ujq3 kernel: Code: c3 2d 15 00 8b b5 0c 01 00 00 85 f6 75 36 89 9d 0c 01 00 00 8b 44 24 04 8d 95 04 01 00 00 89 de 31 ff 89 85 10 01 00 00 8b 43 48 <89> 50 0

4 89 85 04 01 00 00 8d 43 48 89 53 48 31 db 89 85 08 01

Aug 9 19:30:05 linux-ujq3 kernel: EIP: [<c017340a>] chrdev_open+0x79/0x133 SS:ESP 0068:f3f99ee0

========================================================================================================================

the line : "Aug 9 19:30:05 linux-ujq3 kernel: BUG: unable to handle kernel NULL pointer dereference at virtual address 00000005" comes from mm/fault.c (do_page_fault()), but i am unable to find what is causing the problem (may be a very very silly one :)).

after this the system hangs and the only solution is a hard reboot.

where am i going wrong or am i missing something.

i am running : Linux linux-ujq3 2.6.22.17-0.1-default #1 SMP 2008/02/10 20:01:04 UTC i686 i686 i386 GNU/Linux

source is attached : skull.c and skull.h

thanks in advance.

-Venky

# include "skull.h"
#include <linux/cdev.h>

MODULE_LICENSE("Dual BSD/GPL");

static char *device_name = "skull";
static dev_t device_number;
static int no_of_device_nodes = 1;

/*
 This is the device structure that skull uses to store data structures.
 currently only 2 members for testing.
 */

struct skull_dev {
        unsigned long amt; /* amount of data */
        struct cdev cdev;  /* the actual cdev structure */
};


/*
 These are the actual fops functions, open, release, read and write.
 */

/*
 Open the device.
 Get the acutal skull_dev structure from the cdev structure and save it in file->private_data.
 Print the device number for debug.
 */

int skull_open(struct inode *inode, struct file *filp) {
/*
	struct skull_dev *dev;

	dev = container_of(inode->i_cdev, struct skull_dev, cdev);
	filp->private_data = dev;
	printk(KERN_ALERT "Device number : %d.%d calling skull_open\n", imajor(inode), iminor(inode));
*/
	printk(KERN_ALERT "Opening skull device\n");

	return 0;
}

/*
 Remove the device.
 */
int skull_release(struct inode *inode, struct file *filp) {

	return 0;
}

/*
 This is skull's file operations structure.
 */


struct file_operations skull_fops = {
	.owner	 = THIS_MODULE,
	.open	 = skull_open,
	.read	 = NULL,
	.write	 = NULL,
	.release = skull_release,
};

/*
 Now we actually hand over the driver to the kernel.
 index - now 0, will be used when we have more than 1 device nodes.
 */

static int setup_skull_and_hand_over(struct skull_dev *sk_dev, int index) {
	int error;

	cdev_init(&sk_dev->cdev, &skull_fops);
	sk_dev->cdev.owner = THIS_MODULE;
	sk_dev->cdev.ops = &skull_fops;

	error = cdev_add(&sk_dev->cdev, device_number, 1);

	if(error) {
		printk(KERN_ALERT "blah, something is wrong, no entry\n");
		return 0;
	}
	printk(KERN_ALERT "skull_fops added to cdev list\n");
	return 1;
}

/*
 initializaton function
 */

static int skull_init(void) {
	
	int skull_registered;
	struct skull_dev skull_devel;

	if(skull_major) {
		device_number = MKDEV(skull_major, skull_minor);
		skull_registered = register_chrdev_region(device_number, no_of_device_nodes, device_name);
	}
	else {
		skull_registered = alloc_chrdev_region(&device_number, skull_minor, no_of_device_nodes, device_name);
	}

	if(skull_registered < 0)
		return 1;

	/*
	 else continue here with the adding of the driver into the kernel
	 */

	memset(&skull_devel, 0, sizeof(skull_devel));
	if (!setup_skull_and_hand_over(&skull_devel, 0))
		return 1;

	printk(KERN_ALERT "skull driver installed successfully with dev no : %d.%d\n", MAJOR(device_number), MINOR(device_number));
	return 0;

}

/* 
 dtor function
 */
static void skull_exit(void) {

	printk(KERN_ALERT "Skull removedn\n");
	unregister_chrdev_region(device_number, no_of_device_nodes);

}

module_init(skull_init);
module_exit(skull_exit);

/*
 This ths is skull header file to choose
 between dynamic/static device no.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/kdev_t.h>
#include <linux/sched.h>
#include <linux/moduleparam.h>

/*
 non zero major means static device number allocation 
 */
 
static dev_t skull_major = 0;
static dev_t skull_minor = 0;


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux