From: gmate.amit@gmail.com (Kumar amit mehta)
To: kernelnewbies@lists.kernelnewbies.org
Subject: kernel panic in sample block device driver
Date: Wed, 1 May 2013 01:27:18 -0400 [thread overview]
Message-ID: <20130501052650.GA1355@gmail.com> (raw)
Hi,
I'm new to block layer in linux and to learn the same, I'm trying to
come up with a sample memory based block device driver, with which I can
experiment and learn along the way. I'm referring to sample code from
the linux tree [1] and assorted information available over the internet.
My current module is causing system crash as soon I load it. Please take a
look.
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/blkdev.h>
#include <linux/fs.h>
/*
* 1: register the major number
* 2: register callback functions for various capabilities
* 3: register a request function
* 4: disks characteristics information; gendisk
*/
#define RAMDK_MAJOR 166 //unique but static on my current machine as of now
#define BLKDEV_NAME "ramdk"
#define RAMDK_MINOR_NR 1
#define DISKSIZE 256*1024
#define NSECTORS 512
char buffer[DISKSIZE];
static struct gendisk *rdk = NULL;
static DEFINE_SPINLOCK(ramdk_sp_lock);
static struct request_queue *ramdk_queue = NULL;
int ramdk_open(struct block_device *, fmode_t);
int ramdk_release(struct gendisk *, fmode_t);
int ramdk_open(struct block_device *blk, fmode_t mode)
{
printk(KERN_INFO "place holder for ramdisk's open method");
return 0;
}
int ramdk_release(struct gendisk *gdk, fmode_t mode)
{
printk(KERN_INFO "place holder for ramdisk's release method");
return 0;
}
static const struct block_device_operations ramdk_op = {
.owner = THIS_MODULE,
.open = ramdk_open,
.release = ramdk_release,
};
/*
* block devices do not provide read()/write() routines like the char
* devices, instead they use request callback.
*/
static void rdk_request(struct request_queue *q)
{
struct request *rq;
/*
* look at a request and then dequeue it
*/
rq = blk_fetch_request(q);
while (rq) {
unsigned long offset = blk_rq_pos(rq);
unsigned long nbytes = blk_rq_cur_bytes(rq);
int err = 0;
while (nbytes) {
if (rq_data_dir(rq) == READ) {
memcpy(rq->buffer, (char *)offset, nbytes);
} else if (rq_data_dir(rq) == WRITE) {
memcpy((char *)offset, rq->buffer, nbytes);
} else {
printk(KERN_ERR "unknown operation\n");
}
nbytes -= offset;
}
if (!__blk_end_request_cur(rq, err))
rq = blk_fetch_request(q);
}
return;
}
static int __init ramdk_init(void)
{
int ret = -1;
/*
* blocking call. On success, assign an unused major number and add a entry in
* /proc/devices.
*/
if (register_blkdev(RAMDK_MAJOR, BLKDEV_NAME))
return -EBUSY;
printk(KERN_INFO "registered block device %s with major: %d",
BLKDEV_NAME, RAMDK_MAJOR);
rdk = alloc_disk(RAMDK_MINOR_NR);
if (!rdk) {
ret = -ENOMEM;
goto disk_alloc_fail;
}
rdk->fops = &ramdk_op;
/*
* HW perform I/O in the multiples of sectors(512Bytes, typically), whereas SW(FS, etc)
* will work on block size(4k, typically). Therefore we need to tell the upper layers
* about the capability of the hardware. This also sets the maximum number of sectors
* that my hardware can receive per request.
*/
set_capacity(rdk, DISKSIZE*2); //Capacity, in terms of sectors
/*
* returns request queue for the block device. protected using spin lock
*/
ramdk_queue = blk_init_queue(rdk_request, &ramdk_sp_lock);
if (!ramdk_queue)
goto queue_fail;
rdk->queue = ramdk_queue;
rdk->major = RAMDK_MAJOR;
rdk->first_minor = 0;
sprintf(rdk->disk_name, BLKDEV_NAME);
rdk->private_data = buffer;
/*
* Going live now!!!
*/
add_disk(rdk);
return 0;
queue_fail:
printk(KERN_ERR "failed to allocate queue for %s",BLKDEV_NAME);
disk_alloc_fail:
unregister_blkdev(RAMDK_MAJOR, BLKDEV_NAME);
return ret;
}
static void __exit ramdk_exit(void)
{
del_gendisk(rdk);
put_disk(rdk);
blk_cleanup_queue(ramdk_queue);
unregister_blkdev(RAMDK_MAJOR, BLKDEV_NAME);
printk(KERN_INFO "%s is offline now!!!",BLKDEV_NAME);
}
module_init(ramdk_init);
module_exit(ramdk_exit);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("goon");
Once this issue is fixed, I plan to add support for filesystem related
operations such as mkfs, mount, etc.
[1] drivers/block/z2ram.c
-Amit
next reply other threads:[~2013-05-01 5:27 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-05-01 5:27 Kumar amit mehta [this message]
2013-05-01 11:14 ` kernel panic in sample block device driver anish singh
2013-05-01 16:54 ` Pranay Srivastava
2013-05-02 3:35 ` Kumar amit mehta
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130501052650.GA1355@gmail.com \
--to=gmate.amit@gmail.com \
--cc=kernelnewbies@lists.kernelnewbies.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.