Please enable JavaScript.
Coggle requires JavaScript to display documents.
Devices
For a system to be really useful, we need to be able to…
Devices
For a system to be really useful, we need to be able to communicate with it.
- Sending inputs to the system
- Receiving outputs from the system
Operating system provides interface to devices
- Devices are resources and it is the kernel's responsibility to manage resources
- Kernel provides a uniform interface for applications
-
-
Using Devices
-
Opening a Device
The open() System Call
- Device name is passed to kernel
- Kernel allocated FDT entry
- Major/minor numbers determined from name
- Locate device block
- Calls open() function pointed to by the device block
- Returns index of FDT to process
General Function Calls
The Process
- Locate FDT entry using index
- Using pointer to device entry, find the function pointer corresponding to the request
- Call function pointed to by function pointer
(This is a call into upper half of device driver)
- Return value of call returned to process
Synchronous Operations
-
Once system call returns, caller is guaranteed operation has completed or failed
e.g. read(), open(), putc()
Asynchronous Operations
-
-
Caller needs to check if operation complete
aiowrite(), aioread()
-
-
-
-
Design Problems
Thrashing
Occurs when all buffers are used. Free results are used immediately and cause high context switching overhead
-
Full Usage Example
Device-independent open()
- Get major/minor device numbers
- Look up device block in device table of kernel
- Check if process has permission to use device
- Call device-dependent open()
Device-dependent open()
- Device-specific initialization
- Allocate per-process device block
- Allocate device descriptor
- Device block
- Device-independent state
- Index device block into PCB's device table
Configure Device
- Using ioctl()
- Either
- Create control requests for processing by lower half; or
- Make direct calls to lower half to control device
- Return to dispatcher
Write to Device
- Device independent write() calls device-dependent write()
- Creates request and copies data into buffer if available
- Enqueue request
- If device is idle, lower half is notified
- If data cannot be processed, request placed on blocked queue
Write Request Completes
- Enter kernel via CS
- Dispatcher calls lower half of device driver (ISR)
- Lower half notifies upper half request is complete
- Upper half moves requesting process to ready queue
- Return to dispatcher
-
Hardware Interface
-
-
-
-
Device Addressing
Memory Mapping
-
-
-
To read/write from/to registers, just read/write from/to those addresses
Ports
-
Just like "normal" address spaces, ports are identified by addresses
-
-
-
-
-
-
-