<div dir="ltr">kernel panic logs?</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, May 1, 2013 at 10:57 AM, Kumar amit mehta <span dir="ltr">&lt;<a href="mailto:gmate.amit@gmail.com" target="_blank">gmate.amit@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
I&#39;m new to block layer in linux and to learn the same, I&#39;m trying to<br>
come up with a sample memory based block device driver, with which I can<br>
experiment and learn along the way. I&#39;m referring to sample code from<br>
the linux tree [1] and assorted information available over the internet.<br>
My current module is causing system crash as soon I load it. Please take a<br>
look.<br>
<br>
#include &lt;linux/kernel.h&gt;<br>
#include &lt;linux/module.h&gt;<br>
#include &lt;linux/sched.h&gt;<br>
#include &lt;linux/blkdev.h&gt;<br>
#include &lt;linux/fs.h&gt;<br>
/*<br>
 * 1: register the major number<br>
 * 2: register callback functions for various capabilities<br>
 * 3: register a request function<br>
 * 4: disks characteristics information; gendisk<br>
 */<br>
<br>
#define RAMDK_MAJOR     166 //unique but static on my current machine as of now<br>
#define BLKDEV_NAME     &quot;ramdk&quot;<br>
#define RAMDK_MINOR_NR  1<br>
<br>
#define DISKSIZE 256*1024<br>
#define NSECTORS 512<br>
char buffer[DISKSIZE];<br>
<br>
static struct gendisk *rdk = NULL;<br>
static DEFINE_SPINLOCK(ramdk_sp_lock);<br>
static struct request_queue *ramdk_queue = NULL;<br>
<br>
int ramdk_open(struct block_device *, fmode_t);<br>
int ramdk_release(struct gendisk *, fmode_t);<br>
<br>
int ramdk_open(struct block_device *blk, fmode_t mode)<br>
{<br>
        printk(KERN_INFO &quot;place holder for ramdisk&#39;s open method&quot;);<br>
        return 0;<br>
}<br>
<br>
int ramdk_release(struct gendisk *gdk, fmode_t mode)<br>
{<br>
        printk(KERN_INFO &quot;place holder for ramdisk&#39;s release method&quot;);<br>
        return 0;<br>
}<br>
<br>
static const struct block_device_operations ramdk_op = {<br>
        .owner = THIS_MODULE,<br>
        .open = ramdk_open,<br>
        .release = ramdk_release,<br>
};<br>
<br>
/*<br>
 * block devices do not provide read()/write() routines like the char<br>
 * devices, instead they use request callback.<br>
 */<br>
static void rdk_request(struct request_queue *q)<br>
{<br>
        struct request *rq;<br>
<br>
        /*<br>
         * look at a request and then dequeue it<br>
         */<br>
        rq = blk_fetch_request(q);<br>
        while (rq) {<br>
                unsigned long offset = blk_rq_pos(rq);<br>
                unsigned long nbytes  = blk_rq_cur_bytes(rq);<br>
                int err = 0;<br>
                while (nbytes) {<br>
                        if (rq_data_dir(rq) == READ) {<br>
                                memcpy(rq-&gt;buffer, (char *)offset, nbytes);<br>
                        } else if (rq_data_dir(rq) == WRITE) {<br>
                                memcpy((char *)offset, rq-&gt;buffer, nbytes);<br>
                        } else {<br>
                                printk(KERN_ERR &quot;unknown operation\n&quot;);<br>
                        }<br>
                        nbytes -= offset;<br>
                }<br>
                if (!__blk_end_request_cur(rq, err))<br>
                        rq = blk_fetch_request(q);<br>
        }<br>
        return;<br>
}<br>
<br>
static int __init ramdk_init(void)<br>
{<br>
        int ret = -1;<br>
        /*<br>
         * blocking call. On success, assign an unused major number and add a entry in<br>
         * /proc/devices.<br>
         */<br>
        if (register_blkdev(RAMDK_MAJOR, BLKDEV_NAME))<br>
                return -EBUSY;<br>
<br>
        printk(KERN_INFO &quot;registered block device %s with major: %d&quot;,<br>
                BLKDEV_NAME, RAMDK_MAJOR);<br>
<br>
        rdk = alloc_disk(RAMDK_MINOR_NR);<br>
        if (!rdk) {<br>
                ret = -ENOMEM;<br>
                goto disk_alloc_fail;<br>
        }<br>
<br>
        rdk-&gt;fops = &amp;ramdk_op;<br>
        /*<br>
         * HW perform I/O in the multiples of sectors(512Bytes, typically), whereas SW(FS, etc)<br>
         * will work on block size(4k, typically). Therefore we need to tell the upper layers<br>
         * about the capability of the hardware. This also sets the maximum number of sectors<br>
         * that my hardware can receive per request.<br>
         */<br>
        set_capacity(rdk, DISKSIZE*2); //Capacity, in terms of sectors<br>
        /*<br>
         * returns request queue for the block device. protected using spin lock<br>
         */<br>
        ramdk_queue = blk_init_queue(rdk_request, &amp;ramdk_sp_lock);<br>
        if (!ramdk_queue)<br>
                goto queue_fail;<br>
<br>
        rdk-&gt;queue = ramdk_queue;<br>
        rdk-&gt;major = RAMDK_MAJOR;<br>
        rdk-&gt;first_minor = 0;<br>
        sprintf(rdk-&gt;disk_name, BLKDEV_NAME);<br>
        rdk-&gt;private_data = buffer;<br>
        /*<br>
         * Going live now!!!<br>
         */<br>
        add_disk(rdk);<br>
<br>
        return 0;<br>
<br>
queue_fail:<br>
        printk(KERN_ERR &quot;failed to allocate queue for %s&quot;,BLKDEV_NAME);<br>
<br>
disk_alloc_fail:<br>
        unregister_blkdev(RAMDK_MAJOR, BLKDEV_NAME);<br>
<br>
        return ret;<br>
}<br>
<br>
static void __exit ramdk_exit(void)<br>
{<br>
        del_gendisk(rdk);<br>
        put_disk(rdk);<br>
        blk_cleanup_queue(ramdk_queue);<br>
        unregister_blkdev(RAMDK_MAJOR, BLKDEV_NAME);<br>
        printk(KERN_INFO &quot;%s is offline now!!!&quot;,BLKDEV_NAME);<br>
}<br>
<br>
module_init(ramdk_init);<br>
module_exit(ramdk_exit);<br>
MODULE_LICENSE(&quot;GPL v2&quot;);<br>
MODULE_AUTHOR(&quot;goon&quot;);<br>
<br>
Once this issue is fixed, I plan to add support for filesystem related<br>
operations such as mkfs, mount, etc.<br>
<br>
[1] drivers/block/z2ram.c<br>
<br>
-Amit<br>
<br>
_______________________________________________<br>
Kernelnewbies mailing list<br>
<a href="mailto:Kernelnewbies@kernelnewbies.org">Kernelnewbies@kernelnewbies.org</a><br>
<a href="http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies" target="_blank">http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies</a><br>
</blockquote></div><br></div>