DOC PREVIEW
USF CS 635 - UNIX’s “grand illusion”

This preview shows page 1-2-16-17-18-33-34 out of 34 pages.

Save
View full document
View full document
Premium Document
Do you want full access? Go Premium and unlock all 34 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 34 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 34 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 34 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 34 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 34 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 34 pages.
Access to all documents
Download any document
Ad free experience
Premium Document
Do you want full access? Go Premium and unlock all 34 pages.
Access to all documents
Download any document
Ad free experience

Unformatted text preview:

UNIX’s “grand illusion”Basic char-driver componentsBackgroundStandard File-I/O functionsOur ‘elfcheck.cpp’ exampleSpecial ‘device’ filesUNIX ‘man’ pagesThe ‘open’ functionThe ‘close’ functionThe ‘write’ functionThe ‘read’ functionNotes on ‘read()’ and ‘write()’The ‘lseek’ functionGetting the size of a fileDevice knowledgeOur RTC exampleHow device-access worksOur ‘cmosram.c’ driverThe ‘fops’ syntax‘init’ and ‘exit’Our ‘dump.cpp’ utilityNow for a useful char-driver…2-GB RAM has ‘zones’Legacy DMA‘Normal’ memory zone‘HIGH’ memoryThe 896-MB limit‘dram.c’ module-structureOur ‘dram_size’ global‘major’ ID-numberOur ‘file_operations’Using our driverIn-class exercise #1In-class exercise #2UNIX’s “grand illusion”How Linux makes a hardware device appear to be a ‘file’Basic char-driver components init exit fopsfunctionfunctionfunction. . .Device-driver LKM layout registers the ‘fops’ unregisters the ‘fops’ module’s ‘payload’ is a collection of callback-functions having prescribed prototypes AND a ‘package’ of function-pointers the usual pair of module-administration functionsBackground•To appreciate the considerations that have motivated the over-all Linux driver’s design requires an understanding of how normal application-programs get their access to services that the operating system offers•This access is indirect – through specially protected interfaces (i.e., system calls) – usually implemented as ‘library’ functionsStandard File-I/O functions int open( char *pathname, int flags, … ); int read( int fd, void *buf, size_t count ); int write( int fd, void *buf, size_t count ); int lseek( int fd, loff_t offset, int whence ); int close( int fd ); (and other less-often-used file-I/O functions)Our ‘elfcheck.cpp’ example#include <fcntl.h> # for open()#include <stdio.h> # for perror(), printf()#include <unistd.h> # for read(), close()#include <string.h> # for strncpy()char buf[4];int main( int argc, char *argv[] ){if ( argc == 1 ) return -1; // command-line argument is requiredint fd = open( argv[1], O_RDONLY ); // open specified fileif ( fd < 0 ) { perror( argv[1] ); return -1; // quit if open failedint nbytes = read( fd, buf, 4 ); // read first 4 bytesif ( nbytes < 0 ) { perror( argv[1] ); return -1; // quit if read failedif ( strncmp( buf, “\177ELF”, 4 ) == 0 ) // check for ELF idprintf( “File \’%s\’ has ELF signature \n”, argv[1] );else printf( “File \’%s\’ is not an ELF file \n”, argv[1] );close( fd ); // close the file}Special ‘device’ files•UNIX systems treat hardware-devices as special files, so that familiar functions can be used by application programmers to access devices (e.g., open, read, close)•But a System Administrator has to create these device-files (in the ‘/dev’ directory)•Or alternatively (as we’ve seen), an LKM could create these necessary device-filesUNIX ‘man’ pages•A convenient online guide to prototypes and semantics of the C library functions•Example of usage:$ man 2 openThe ‘open’ function•#include <fcntl.h>•int open( char *pathname, int flags, … );•Converts a pathname to a file-descriptor•File-descriptor is a nonnegative integer •Used as a file-ID in subsequent functions•‘flags’ is a symbolic constant: O_RDONLY, O_WRONLY, O_RDWRThe ‘close’ function•#include <unistd.h>•int close( int fd );•Breaks link between file and file-descriptor•Returns 0 on success, or -1 if an errorThe ‘write’ function•#include <unistd.h>•int write( int fd, void *buf, size_t count );•Attempts to write up to ‘count’ bytes•Bytes are taken from ‘buf’ memory-buffer•Returns the number of bytes written•Or returns -1 if some error occurred•Return-value 0 means no data was writtenThe ‘read’ function•#include <unistd.h>•int read( int fd, void *buf, size_t count );•Attempts to read up to ‘count’ bytes•Bytes are placed in ‘buf’ memory-buffer•Returns the number of bytes read•Or returns -1 if some error occurred•Return-value 0 means ‘end-of-file’Notes on ‘read()’ and ‘write()’•These functions have (as a “side-effect”) the advancement of a file-pointer variable•They return a negative function-value of -1 if an error occurs, indicating that no actual data could be transferred; otherwise, they return the number of bytes read or written•The ‘read()’ function normally does not return 0, unless ‘end-of-file’ is reachedThe ‘lseek’ function•#include <unistd.h>•off_t lseek( int fd, off_t offset, int whence );•Modifies the file-pointer variable, based on the value of whence:enum { SEEK_SET, SEEK_CUR, SEEK_END }; •Returns the new value of the file-pointer (or returns -1 if any error occurred)Getting the size of a file•For normal files, your application can find out how many bytes belong to a file using the ‘lseek()’ function: int filesize = lseek( fd, 0, SEEK_END );•But afterward you need to ‘rewind’ the file if you want to read its data: lseek( fd, 0, SEEK_SET );Device knowledge•Before you can write a device-driver, you must understand how the hardware works•Usually this means you need to obtain the programmer manual (from manufacturer)•Nowdays this can often be an obstacle•But some equipment is standardized, or is well understood (because of its simplicity)Our RTC example•We previously learned how the Real-Time Clock device can be accessed by module code, using the ‘inb()’ and ‘outb()’ macros:•So we can create a simple char driver that lets application-programs treat the RTC’s memory as if it were in an ordinary file outb( addr, 0x70 ); outb( data, 0x71 ); outb( addr, 0x70 ); data = inb( 0x71 );How device-access worksPhysical peripheral device (hardware)Device-driver module (software)Operating system (software)Application programStandard runtime library supervisor space(privileged) user space(unprivileged)call ret int $0x80 iret int $0x80 iretcall ret out inOur ‘cmosram.c’ driver•We implement three callback functions:–llseek: // sets file-pointer’s position–read: // inputs a byte from CMOS–write: // outputs a byte to CMOS•We omit other callback functions, such as:–open: // we leave this function-pointer NULL–release:// we leave this function-pointer NULL•The kernel has its own ‘default’ implementation for any


View Full Document

USF CS 635 - UNIX’s “grand illusion”

Download UNIX’s “grand illusion”
Our administrator received your request to download this document. We will send you the file to your email shortly.
Loading Unlocking...
Login

Join to view UNIX’s “grand illusion” and access 3M+ class-specific study document.

or
We will never post anything without your permission.
Don't have an account?
Sign Up

Join to view UNIX’s “grand illusion” 2 2 and access 3M+ class-specific study document.

or

By creating an account you agree to our Privacy Policy and Terms Of Use

Already a member?