Search code examples
cmemorysysteminterruptdma

Interrupt and DMA, what happens in the background?


I'm trying to understand how Interrupts are handled by the system and how does it work if there is a DMA integrated in the system.

I will express what I understood until now, and I would like to have some feedback if I'm right or not.

In order for the system to catch I/O actions performed by some device, the system uses what's called Interrupts. The system sets up interrupts for given actions (we're interested in, for example typing on a keyboard), and once the action is performed the system catches it.

Now I have some doubts, once we catch an Interrupt what happens in the background? What are the overheads? What has does the CPU needs to set up? Is there a context switch? How does the interrupt handler works?

The CPU has to do some work in order to handle the interrupt, does it read the registers and writes the "message" in the memory, in order for the user to see it?

If we have a DMA, instead, once the CPU catches the Interrupt it doesn't need to handle the memory access for the device, thus it can perform other thing until the DMA interrupts the CPU telling him that the transfer it completed and that the CPU can safely close the handling?

As you can see there is some stuff I need to clarify. I would really appreciate your help. I know that an answer to all those questions could be written in one book, but all I need is to know how the things are connected, to get an intuition on what's going on behind the scenes in order to reason more easily about it.


Solution

  • Interrupts are handled by something called Interrupt Service Routines (ISRs). These are functions implemented by the kernel and registered with the hardware. Each type of an interrupt is registered with a separate handler.

    When a hardware receives an interrupt, it halts the execution of any running process (on that processor), pushes the state of the process (registers, flags, segments) on the stack and executes the ISR.

    Apart from saving the context, the hardware also does one more important thing. It changes the processor context to Privileged mode (lower ring). This is of course if the processor is already not in Ring 0 and if Privileged operations are required by the ISR. There is a flag in the Interrupt Descriptor Table (IDT) which tells the processor whether it is a user mode exception or a privileged mode exception.

    Since these ISRs are written by the kernel they are trusted. These ISRs perform whatever is required for example in case of a keyboard interrupt, it moves the byte reads into the input stream of the foreground process.

    After the ISR is done, (signaled by an iret instruction on X86), the state of the program is popped off and the execution of the process continues.

    Yes, this can be thought of a context switch, but it really isn't since other process is not loaded. It can be just thought of as a halt till a more important job is done.

    While this has some overhead, it is not much in case of frequent interrupts like keyboards interrupts (the ISRs are very small) and also these interrupts are very infrequent.

    But say there is a hardware that does jobs are very regular interval. Like disk read/write or network card. In this case, interrupting again and again would be very costly.

    So what we use is DMA (direct memory access). The processor allocates some physical memory to these hardware. They can access this part of the RAM without halting the process, since the processor's intervention is not required.

    They keep doing all the IO they need to, but in the end when the job is done (or if it fails), they signal the processor with a single interrupt.