📄 basic_block_drivers.html
字号:
strcpy<span class="br0">(</span>sbd_device.<span class="me1">gendisk</span>-&gt;disk_name,DEVICE_NAME <span class="st0">"0"</span><span class="br0">)</span>; set_capacity<span class="br0">(</span>sbd_device.<span class="me1">gendisk</span>,num_sects*<span class="br0">(</span>sect_size/KERNEL_SECTOR_SIZE<span class="br0">)</span><span class="br0">)</span>; </pre></div><!-- SECTION [2078-2666] --><h3><a name="request_queue" id="request_queue">Request Queue</a></h3><div class="level3"><p> Get a Request Queue and add it to the gen disk</p><pre class="code c"> <span class="kw4">static</span> <span class="kw4">struct</span> request_queue * queue; queue = blk_init_queue<span class="br0">(</span>sbd_request, \\ the service <span class="kw2">function</span> &sbd_device.<span class="me1">lock</span> <span class="br0">)</span>; \\ the lock <span class="co1">// check for NULL and handle error</span> blk_queue_hardsect_size<span class="br0">(</span>queue,sect_size<span class="br0">)</span>; sbd_device.<span class="me1">gendisk</span>-&gt;queue = queue; add_disk<span class="br0">(</span>sbd_device.<span class="me1">gendisk</span><span class="br0">)</span>; </pre></div><!-- SECTION [2667-3090] --><h3><a name="data_transfer" id="data_transfer">Data Transfer</a></h3><div class="level3"><p> Specify the data transfer function </p><pre class="code c"> <span class="kw4">static</span> <span class="kw4">void</span> sbd_transfer <span class="br0">(</span> <span class="kw4">struct</span> simple_device * dev, <span class="kw4">unsigned</span> <span class="kw4">long</span> sector, <span class="kw4">unsigned</span> <span class="kw4">long</span> num_sects, <span class="kw4">char</span> * buffer, <span class="kw4">int</span> write<span class="br0">)</span><span class="br0">{</span> <span class="kw4">unsigned</span> <span class="kw4">long</span> offset = sector * sect_size; <span class="kw4">unsigned</span> <span class="kw4">long</span> num_bytes = num_sects * sect_size; <span class="co1">// check size</span> <span class="kw1">if</span> <span class="br0">(</span> <span class="br0">(</span>offset + num_bytes<span class="br0">)</span> &gt; dev-&gt;size <span class="br0">)</span> <span class="br0">{</span> printk<span class="br0">(</span>KERN_NOTICE DEVICE_NAME <span class="st0">":access error<span class="es0">\n</span>"</span><span class="br0">)</span>; <span class="kw1">return</span>; <span class="br0">}</span> <span class="kw1">if</span> <span class="br0">(</span> write <span class="br0">)</span> <span class="br0">{</span> memcpy<span class="br0">(</span>dev-&gt;data+offset, buffer, num_bytes<span class="br0">)</span>; <span class="br0">}</span> <span class="kw1">else</span> <span class="br0">{</span> memcpy<span class="br0">(</span>buffer, dev-&gt;data+offset, num_bytes<span class="br0">)</span>; <span class="br0">}</span><span class="br0">}</span></pre></div><!-- SECTION [3091-3843] --><h3><a name="request_function" id="request_function">Request Function</a></h3><div class="level3"><p> Specify the request function to handle entries in the request queue.</p><pre class="code c"><span class="kw4">static</span> <span class="kw4">void</span> sbd_request<span class="br0">(</span>request_queue_t *q<span class="br0">)</span> <span class="br0">{</span> <span class="kw4">struct</span> request * req; <span class="kw1">while</span><span class="br0">(</span><span class="br0">(</span>req = elv_next_request<span class="br0">(</span>q<span class="br0">)</span><span class="br0">)</span> != <span class="kw2">NULL</span><span class="br0">)</span> <span class="br0">{</span>\ <span class="kw1">if</span> <span class="br0">(</span> !blk_fs_request<span class="br0">(</span>req<span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span> end_request<span class="br0">(</span>req,<span class="nu0">0</span><span class="br0">)</span>; <span class="co1">// reject request</span> <span class="kw1">continue</span>; <span class="br0">}</span> sbd_transfer<span class="br0">(</span>&sbd_device, <span class="co1">//our read / write routine</span> req-&gt;sector, req-&gt;current_nr_sectors, req-&gt;buffer, rq_data_dir<span class="br0">(</span>req<span class="br0">)</span><span class="br0">)</span>; end_request<span class="br0">(</span>req,<span class="nu0">1</span><span class="br0">)</span>; <span class="co1">// consume request</span> <span class="br0">}</span><span class="br0">}</span></pre></div><!-- SECTION [3844-4493] --><h3><a name="basic_ioctl_function" id="basic_ioctl_function">Basic IOCTL function</a></h3><div class="level3"><p> Define a basic IOCTL function.</p><p>The Kernel now handles the default IOCTL calls and only passes the ones to the driver that it cannot handle. This IOCTL is used to get the (Imaginary) geometry of the system</p><pre class="code c"><span class="kw4">int</span> sbd_ioctl <span class="br0">(</span> <span class="kw4">struct</span> inode * inode, <span class="kw4">struct</span> file * file, <span class="kw4">unsigned</span> <span class="kw4">int</span> cmd , <span class="kw4">unsigned</span> <span class="kw4">long</span> arg<span class="br0">)</span> <span class="br0">{</span> <span class="kw4">long</span> size; <span class="kw4">struct</span> hd_geometry geom; <span class="kw1">switch</span> <span class="br0">(</span>cmd<span class="br0">)</span> <span class="br0">{</span> <span class="co1">// HDIO_ETGEO is all we need to supply</span> <span class="kw1">case</span> HDIO_GETGEO: size = sbd_device.<span class="me1">size</span>*<span class="br0">(</span>sect_size/KERNEL_SECTOR_SIZE<span class="br0">)</span>; geom.<span class="me1">cylinders</span> = <span class="br0">(</span> size & ~0x3f <span class="br0">)</span> &gt;&gt; <span class="nu0">6</span>; geom.<span class="me1">heads</span> = <span class="nu0">4</span>; geom.<span class="me1">sectors</span> = <span class="nu0">16</span>; geom.<span class="me1">start</span> = <span class="nu0">4</span>; <span class="kw1">if</span><span class="br0">(</span> copy_to_user<span class="br0">(</span><span class="br0">(</span><span class="kw4">void</span> *<span class="br0">)</span> arg, &geom, <span class="kw4">sizeof</span><span class="br0">(</span>geom<span class="br0">)</span><span class="br0">)</span><span class="br0">)</span> <span class="kw1">return</span> -EFAULT; <span class="kw1">return</span> <span class="nu0">0</span>; <span class="br0">}</span> <span class="kw1">return</span> -ENOTTY;<span class="br0">}</span> </pre></div><!-- SECTION [4494-5327] --><h3><a name="add_the_new_device" id="add_the_new_device">Add the new Device</a></h3><div class="level3"><p>Start the system by adding the disk.</p><pre class="code c"> add_disk<span class="br0">(</span>sim_device.<span class="me1">gendisk</span><span class="br0">)</span>; </pre><p>Following this you can define a block device using mknod. Create the device nodes.</p><pre class="code">get maj from cat /proc/devicesmknod /dev/myblock b maj 0 mknod /dev/myblock0 b maj 0 mknod /dev/myblock1 b maj 1 mknod /dev/myblock2 b maj 2 </pre><p>Then make a file system on one of the nodes</p><pre class="code c"> mke2fs /dev/myblock1 </pre><p>Now mount it and add files ( they will dissapear when you reboot or unmount the partition )</p><pre class="code">mkdir -p /mnt/myblockmount /dev/myblock1 /mnt/yblock</pre></div><!-- SECTION [5328-5949] --><h3><a name="clean_up" id="clean_up">Clean Up</a></h3><div class="level3"><p>Finally the clean up code follows. This is used to remove the driver if it was inserted as a module</p><pre class="code c"> <span class="kw4">static</span> <span class="kw4">void</span> __ exit sbd_exit<span class="br0">(</span><span class="kw4">void</span><span class="br0">)</span> <span class="br0">{</span> del_gendisk<span class="br0">(</span>sbd_device.<span class="me1">gendisk</span><span class="br0">)</span>; put_disk<span class="br0">(</span>sbd_device.<span class="me1">gendisk</span><span class="br0">)</span>; unregister_blkdev<span class="br0">(</span>maj,DEVICE_NAME<span class="br0">)</span>; blk_cleanup_queue<span class="br0">(</span>queue<span class="br0">)</span>; vfree<span class="br0">(</span>sbd_device.<span class="me1">data</span><span class="br0">)</span>; <span class="br0">}</span> </pre></div><!-- SECTION [5950-] --></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -