How does an OS communicate with other hardware components?

[H]ow can program runnig on CPU (mostly OS) acess other PC hardware? Such as Graphic card, HDD and so?

The complete answer to this question is complex and difficult to answer in general. So I'm going to try to answer it in general, and hopefully give you some pointers for finding additional information for further learning. I hope this is useful.

For 32/64-bit protected modes as used by MS Windows 95 and newer, or Linux on an x86 (IA-32) processor, software interrupts (such as the INT opcode for x86) go to the appropriate Interrupt vector table (or dispatch table) which may direct the CPU where in the OS the process should jump to the interrupt handler (or Interrupt Service Routine, ISR) for handling the request.

In x86 real-mode, like MS-DOS these may be handled by the BIOS that provides low-level specific implementation details for that particular system / chipset / motherboard.

[H]ow can some program stored in RAM acess other computer HW, when CPU can acess only RAM, and reeive interrupts?

So you don't want the usual hand-wavy answer? I'll try to answer this, but I am not a computer engineer or expert of computer architecture.

There are various mechanisms including

  • memory mapped or port mapped I/O
  • Direct Memory Access (DMA)
  • IO Processors (I/O "channels")
  • Peripheral Processing Units

(Src: CS 473 - IO, New Mexico State University, pfeiffer, 2006)

The simplest is memory mapped I/O where an memory address might be mapped to the registers of a hardware device (e.g. serial UART) and the CPU and write and/or read certain memory addresses to access the hardware directly. This is fast, and simple, but reduces the memory address range of what can be used as RAM.

The others are more advanced techniques developed to allow modern CPUs and more advanced Operating Systems access hardware in a controlled fashion.

In the OS itself, these are normally referred to as device drivers, as they include specific details about the hardware devices they support.

And, does windows use int instructions as well, or is there any new way to communicate with HW?

Yes, and yes, but I think I've explained that.


There are several ways software running on the CPU on a PC can communicate with the rest of the hardware.

The simplest to understand are I/O ports. The software uses the OUT instruction to write 8, 16, or 32 bits at a time to a I/O port. In the same way, the software uses the IN instruction to read from a I/O port. The I/O ports live in a separate 16-bit address space, unrelated to the addresses space used by the main memory. Each piece of hardware which uses I/O ports has a range of I/O addresses; writing to and reading from each of these addresses has a different effect (and often reading from and writing to the same address has different effects too).

Another way is memory-mapped I/O, where part of the memory address space is mapped to a piece of hardware. Instead of going to the main memory, the reads and writes from and to that region of memory go to the corresponding hardware. What they mean depends on the hardware and on the region (it is not uncommon to have more than one memory-mapped I/O region in the same piece of hardware); reading and writing to it could have a special effect (as is common with I/O ports) or it could simply read and write directly to memory on the hardware (for instance, a video card's frame buffer).

On the other direction (the rest of the hardware talking to the software running on the CPU), there are also several ways. The simplest one would be to wait for the software to ask (either via an I/O port or memory-mapped I/O); used alone, this can be very inefficient.

Another way is for the hardware to write directly to the main memory. This is very efficient for transfering large amounts of data, and can be used in the other direction too (to read from the main memory). However, the software still has to know when the transfer is finished.

The last way is interrupts. The CPU receives an interrupt request, together with the interrupt number. The CPU interrupts (thus the name) what it was doing, and switches to another part of the code (which part depends on the interrupt number). Usually each hardware corresponds to a single interrupt number, but interrupt numbers are often shared by several interrupt sources. There are also special kinds of interrupt which do not have a number; for instance, the NMI.


For a practical example, let's take a simple network interface card. This network card has a set of registers, which can be acessed either via I/O ports or memory-mapped I/O. It can also read from and write to the main memory, and has an interrupt pin.

To send a packet to the network, the network card driver first writes the full packet to the memory, at an address aligned to a multiple of 4 bytes. It then writes to a couple of registers on the network interface card, telling it the memory address, the packet size, and some other information. The network card then reads the packet from the memory, sends it to the network, and signals the interrupt. The interrupt controller (a separate piece of hardware) sends the interrupt request to the CPU and tells it the interrupt number. In the interrupt handler, the driver reads a register from the card which tells it the interrupt was about a packet being sent, reads another register to find out which packet was sent, and knows it can now reuse the memory where it had written the packet.

To receive packets from the network, the network card driver allocates a block of memory to be used as storage for the packets, and writes several registers on the card telling it the memory address of the block of memory, its size, and some other information. When a packet is received from the network, the network card writes it to that block of memory, together with the packet's size and some other information. It updates some registers which tell both it and the driver how much free space is there in that block of memory, where the free space begins, and where the used space begins (the buffer is circular, so after getting to the end it rolls over to the beginning). Finally, it signals its interrupt. The driver will read the registers and the memory to obtain the packet(s), and will update the registers to tell the card that space is now free again.

There are other things the card can tell the driver by writing its registers and signalling an interrupt; for instance, that the network cable was unplugged, that there was a transmission error, and so on.


What you're looking for is "IRQ", Interrupt Requests from the hardware to the CPU. There is a basic article here.