Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "The ‘ioctl’ driver-function On implementing a way to query and modify our UART’s baudrate via the ‘device-file’ abstraction."— 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_BAUDRATE0 #define SET_BAUDRATE1 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 user application standard “runtime” libraries call ret user spacekernel space Operating System kernel syscall sysret device-driver module call ret hardware device out in operating parameters RAM A device-driver is a software module that controls a hardware device in response to OS kernel requests relayed, often, from an application

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

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_LINECTRL2 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


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

Similar presentations


Ads by Google