Note that there are some explanatory texts on larger screens.

plurals
  1. POcharacter device driver
    text
    copied!<p>The read() and write() callback functions in our ‘cmosram.c’ device-driver only transfer a single byte of data for each time called, so it takes 128 system-calls to read all of the RTC storage-locations!</p> <p>Can you improve this driver’s efficiency, by modifying its read() and write() functions, so they’ll transfer as many valid bytes as the supplied buffer’s space could hold?</p> <p>code is as follows</p> <pre><code>char modname[] = "cmosram"; // name of this kernel module char devname[] = "cmos"; // name for the device's file int my_major = 70; // major ID-number for driver int cmos_size = 128; // total bytes of cmos memory int write_max = 9; // largest 'writable' address ssize_t my_read( struct file *file, char *buf, size_t len, loff_t *pos ) { unsigned char datum; if ( *pos &gt;= cmos_size ) return 0; outb( *pos, 0x70 ); datum = inb( 0x71 ); if ( put_user( datum, buf ) ) return -EFAULT; *pos += 1; return 1; } ssize_t my_write( struct file *file, const char *buf, size_t len, loff_t *pos ) { unsigned char datum; if ( *pos &gt;= cmos_size ) return 0; if ( *pos &gt; write_max ) return -EPERM; if ( get_user( datum, buf ) ) return -EFAULT; outb( *pos, 0x70 ); outb( datum, 0x71 ); *pos += 1; return 1; } loff_t my_llseek( struct file *file, loff_t pos, int whence ) { loff_t newpos = -1; switch ( whence ) { case 0: newpos = pos; break; // SEEK_SET case 1: newpos = file-&gt;f_pos + pos; break; // SEEK_CUR case 2: newpos = cmos_size + pos; break; // SEEK_END } if (( newpos &lt; 0 )||( newpos &gt; cmos_size )) return -EINVAL; file-&gt;f_pos = newpos; return newpos; } struct file_operations my_fops = { owner: THIS_MODULE, llseek: my_llseek, write: my_write, read: my_read, }; static int __init my_init( void ) { printk( "&lt;1&gt;\nInstalling \'%s\' module ", devname ); printk( "(major=%d) \n", my_major ); return register_chrdev( my_major, devname, &amp;my_fops ); } static void __exit my_exit(void ) { unregister_chrdev( my_major, devname ); printk( "&lt;1&gt;Removing \'%s\' module\n", devname ); } module_init( my_init ); module_exit( my_exit ); MODULE_LICENSE("GPL"); </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload