XV6 Device Driver
Why we have a Driver?
A driver is the code in an operating system that manages a particular device: 1. It tells the device hardware to perform operations,. 2. Configures the device to generate interrupts when done. 3. Handles the resulting interrupts,. 4. Interacts with processes that may be waiting for I/O from the device.
Initialization
Config Hardware
Xv6’s main calls consoleinit (kernel/console.c:189) to initialize the UART hardware, and to configure the UART hardware to generate input interrupts (kernel/uart.c:34).
void
consoleinit(void)
{
initlock(&cons.lock, “cons”);
uartinit();
// connect read and write system calls
// to consoleread and consolewrite.
devsw[CONSOLE].read = consoleread;
devsw[CONSOLE].write = consolewrite;
}Create console device
In init.c, create a console device:
The file path is console, type is T_DEVICE.
mknod implementation.
At this point, we have a console device. A file descriptor 0 points to this device.
How to read or write from device
Let’s look at fileread
If the file type is DEVICE, we call the special read function to perform read operation. Note: The special read is set up in consoleinit.
consoleread sleeps and wait for a line of inputs, then copy to user space. Details see flow section.
Flow
Every input char generates an interrupt
When the user types a character, the UART hardware asks the RISC-V to raise an interrupt.
Trap handler determines interrupt source
xv6’s trap handling code calls devintr (kernel/trap.c:177). devintr looks at the RISC-V scause register to discover that the interrupt is from an external device. Then it asks a hardware unit called the PLIC [1] to tell it which device interrupted (kernel/trap.c:186). If it was the UART, devintrcalls uartintr.
Accumulate inputs and Wake up
Read one char and hand over
uartintr (kernel/uart.c:84) reads any waiting input characters from the UART hardware and hands them to consoleintr.
Accumulate inputs
The job of consoleintr is to accumulate input characters in cons.buf until a whole line arrives.
Wake up when get a whole line
When a newline arrives, consoleintr wakes up a waiting consoleread (if there is one).
Copy to user space
Once woken, consoleread will observe a full line in cons.buf, copy it to user space and return to user space.
Question:
How does open(“console", O_RDWR) opens a file with DEVICE type?
open(“console", O_RDWR) opens a file with DEVICE type?Research: It seems this console string is defined somewhere. I tried to change to other string, and it does not work. Using this console string to open file, the file inode returns a file with type is DEVICE.
Answer:
OS create a console device using system call mknod. Any read or write with console is interacting with the UART hardware.
Last updated
Was this helpful?