Presentation is loading. Please wait.

Presentation is loading. Please wait.

Character Driver Issues Implementing ‘/dev/physmem’

Similar presentations


Presentation on theme: "Character Driver Issues Implementing ‘/dev/physmem’"— Presentation transcript:

1 Character Driver Issues Implementing ‘/dev/physmem’

2 Goals for ‘physmem’ Let user-programs ‘read’ physical memory Make this convenient for the programmer Treat physical memory as just one big file Then can use standard C library functions: i.e., open(), lseek(), read(), close() But don’t give user-programs write-access!

3 The ‘mknod’ command Device-file: usually created by command # mknod /dev/physmem c 251 0 ‘mknod’ takes 4 command-line arguments: the pathname of the special file ‘c’ indicates it’s a character device 251 is driver’s ID-number (i.e., major) 0 is the device’s ID-number (i.e., minor) Need ‘root’ privileges to create /dev file

4 Default file permissions Without ‘root’ privileges, we can’t try it But if we could, we’d see file-permissions Example: # mknod /dev/xxx c 251 0 # ls -l /dev/xxx crw-r—r-- 1 root root 251, 0 25 Feb dev/xxx We don’t want users to ‘write’ to physmem

5 Modifying file-permissions Supervisor can change file-permissions ‘chmod’ is the privileged command to use Example: # chmod 0444 /dev/xxx # ls -l /dev/xxx cr--r—r-- 1 root root 251, 0 25 Feb dev/xxx Now the device-file has ‘read-only’ access

6 A ‘smarter’ driver Our drivers can create their own files: syscall: mknod( pathname, mode, devid); Our drivers can modify file-permissions: syscall: chmod( pathname, mode); Our drivers can also delete their own files: syscall: unlink( pathname );

7 Some manifest constants Header-file: #include #define S_IFCHR0020000 #define S_IRUSR 0000400 #define S_IRGRP 0000040 #define S_IROTH0000004 By ‘or’-ing the latter three values, can get: #define S_IRUGO 0000444

8 Driver’s ‘read()’ function Must conform to standard prototype Otherwise: can’t ‘register_chrdev()’ Return-value has type ‘ssize_t’ Function takes four arguments: struct file *filp;// pointer to file-structure char*buf; // pointer to user-buffer size_tcount; // size of user-buffer loff_t*pos; // points to file-position

9 Algorithm for ‘read()’ Step 1: Check for an invalid request: if ( *pos >= filesize ) return –EINVAL; Step 2: Adjust ‘count’ for remaining bytes: If ( *pos + count > filesize ) count = filesize - *pos;

10 Algorithm (continued) Step 3: Find location of next data bytes void *from = phys_to_virt( *pos ); Step 4: Copy data into user-space buffer more = copy_to_user( buf, from, count ); Step 5: Return error if copying unfinished if ( more ) return –EFAULT;

11 Algorithm (conclusion) Step 6: Advance file’s current position *pos += count; Step 7: Return number of bytes copied return count;

12 Driver needs ‘llseek()’ ‘fileview.cpp’ checks for size of device-file Standard C library function is ‘lseek()’: filesize = lseek( fd, 0, SEEK_END ); ‘fd’ is the file-descriptor for an opened file 0 is the ‘offset’ to seek to SEEK_END says offset is from end-of-file

13 Default ‘llseek()’ won’t work No way for kernel to know device’s filesize So default ‘llseek()’ will give a wrong result Driver must implement its own ‘llseek()’ For ‘/dev/physmen’ with 1GB memory: FILESIZE = 0x38000000 But more generally: FILESIZE = virt_to_phys( high_memory );

14 Sample ‘llseek()’ in LDD text ‘llseek()’ must handle three cases: #define SEEK_SET0 #define SEEK_CUR1 #define SEEK_END2 (See author’s example-code on page 163)

15 Prototype for ‘llseek()’ Function has three arguments: struct file *filp;// pointer to file-structure loff_t offset;// file-offset to seek to intwhence;// where to seek from Return-value has type ‘loff_t’ (new offset)

16 Algorithm for ‘llseek()’ Step 1: Use ‘switch’ statement: switch( whence ) { case 0:// for SEEK_SET case 1:// for SEEK_CUR case 2:// for SEEK_END default:// should never happen! }

17 Actions for ‘switch’ cases case SEEK_SET: newpos = offset; break; case SEEK_CUR: newpos = file->f_pos + offset; break; case SEEK_SET: newpos = filesize + offset; break; default: return -EINVAL;

18 Algotithm (conclusion) Step 2: Check for illegal ‘newpos’ value: if ( newpos < 0 ) return –EINVAL; Step 3: Update ‘f_pos’ in file-structure: filp->f_pos = newpos; Step 4: Return new file-pointer position: return newpos;

19 ‘physmem’ is read-only If device-file lacks ‘write’ permissions, then kernel won’t call driver’s ‘write()’ function So omit write-function from device-driver in order to avoid having ‘dead code’

20 Consider your legacy Your driver-code may have a future life! Another programmer could ‘inherit’ it Or you, yourself, may want to ‘reuse’ it Keeping ‘dead code’ will cause confusion Omitting commentary will cause frustration Need the author’s name (and contact-info) Need code’s revision-history (when/why)


Download ppt "Character Driver Issues Implementing ‘/dev/physmem’"

Similar presentations


Ads by Google