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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).