1 / 13

The ‘ioctl’ driver-function

The ‘ioctl’ driver-function. On implementing a way to query and modify our UART’s baudrate via the ‘device-file’ abstraction. ‘struct file_operations’. For a Linux device-driver’s ‘module_init()’ function, there are two main actions:

moreyj
Download Presentation

The ‘ioctl’ driver-function

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. The ‘ioctl’ driver-function On implementing a way to query and modify our UART’s baudrate via the ‘device-file’ abstraction

  2. ‘struct file_operations’ • For a Linux device-driver’s ‘module_init()’ function, there are two main actions: • Initializing the driver’s global data-structures (this includes verifying the device’s presence) • Registering the driver’s service-functions with the kernel (i.e., the ‘file_operations’ structure) • The driver’s ‘module_exit()’ function then has the duty to ‘unregister’ those services

  3. Driver services • For character-mode device-drivers (like ‘dram.c’, ‘cmos.c’ and ‘vram.c’), we have implemented some (or all) of the following service-functions (i.e., driver ‘methods’): • read() • llseek() • write() • mmap()

  4. The ‘file’ paradigm • The UNIX approach to device-control is to create objects that represent i/o-devices, but which behave like ‘files’ do, insofar as the application programmer is concerned • So ‘read()’, ‘lseek()’, ‘write()’ and ‘mmap() use the same function-call syntax – and in most respects the same semantics – for both ordinary ‘files’ and ‘device-files’

  5. An imperfect paradigm • But often there are a few ways in which the file-object paradigm doesn’t quite fit with important features of an i/o device • In these cases, device-drivers can provide a ‘workaround’ that allows applications to perform device-actions that deviate from customary ‘read/write/seek’ file-like actions • This ‘workaround’ mechanism is ‘ioctl()’

  6. The serial UART • Our PC’s serial UART device offers us an easy example of some desirable behavior that’s outside the traditional ‘file’ paradigm • In order to use our ‘dev/vram’ device-file for communications with computers that we can’t control, we may need to adjust our UART’s communication parameters • How can a program change ‘baudrate’?

  7. Our ‘baudrate.c’ module • These techniques are demonstrated in this device-driver module’s ‘ioctl()’ function • Two IOCTL services are implemented: #define GET_BAUDRATE 0 #define SET_BAUDRATE 1 • Applications can open the device-file and invoke an ‘ioctl’ system-call; for example: int fd = open( “/dev/uart”, O_RDWR ); ioctl( fd, GET_BAUDRATE, &baudrate );

  8. Recall role of a device-driver A device-driver is a software module that controls a hardware device in response to OS kernel requests relayed, often, from an application hardware device operating parameters in out RAM device-driver module user application ret call call ret Operating System kernel syscall standard “runtime” libraries sysret user space kernel space

  9. UART’s baudrate-control LSB DIVISOR LATCH (bits 7..0) i/o port 0x03F8 MSB DIVISOR LATCH (bits 15..8) i/o port 0x03F9 7 6 5 4 3 2 1 0 D L A B B R E A K parity controls stop bits data bits LINE CONTROL REGISTER i/o port 0x03FB

  10. Algorithm to ‘get’ baudrate • Input (and save) the LINE_CONTROL • Set DLAB-bit in LINE_CONTROL to 1 • Input (and save) the DIVISOR_LATCH • Restore LINE_CONTROL to former value • Compute ‘baudrate’ from divisor_latch: baudrate  115200 / divisor_latch • Return this current ‘baudrate’ value

  11. Algorithm to ‘set’ baudrate • Receive ‘baudrate’ as function-argument • Verify that argument is within valid range • Compute ‘divisor_latch’ from ‘baudrate’: divisor_latch  115200 / baudrate • Input (and save) the LINE_CONTROL • Set DLAB-bit in LINE_CONTROL to 1 • Output ‘divisor_latch’ to UART register • Restore LINE_CONTROL to former value

  12. Demo-program: ‘setbaud.cpp’ • This application-program lets a user query or modify the UART’s current baudrate in a convenient manner – without requiring any ‘special’ privileges (don’t need ‘iopl3’) • To see the current baudrate: $ ./setbaud • To change the current baudrate: $ ./setbaud 2400

  13. In-class exercise • Can you modify our ‘baudrate.c’ driver so it implements an additional ‘ioctl’ service: # define GET_LINECTRL 2 • Then add an extra ‘ioctl’ system-call in our ‘setbaud.cpp’ application so that it displays the UART’s current data-format (as well as baudrate) using format similar to 8-N-1 • HINT: look at driver’s ‘get_info()’ function

More Related