IO (Input and Output)

General trend of IO is towards more specialised hardware. We'd like to handle everything the same, but things are different with encoding and protocols, and generalisation often kills efficiency.

Different devices have different data transfer rates and different encoding schemes. And they are often the slow point compared to CPU and memory - hence multiprocessing allows other work to happen whilst waiting on IO.

Buses - can either have one bus, or two (single vs dual). The two allows CPU to high bandwidth talk to memory.

IO Controllers

Memory-Mapped IO vs Separate I/O address space. Oh no.

IO Controllers;

  • Separate IO and memory space
    • I/O controller registers appear as I/O ports
    • Special IO instructions
  • Memory mapped IO
    • IO registers in memory, accessed with standard load/store instructions
  • Hybrid1!!11
    • Ports AND memory mapped IO

In memory-mapped, we just split the address space in 2 section - memory, and IO. Wow cray. They use standard instructions ooh no need for special ones. But they take up memory space cause they map to them. Also whole address needs to be decoded Lame.

Separate IO address space = the opposite.! You have to have a separate control signal so only one of them uses the bus at a time. Also separate instructions so we know which address space we referring to. But decoding is easier on account of how we already know which space it going to.

Direct Memory Access

Allows memory and device to interact without CPU. DMA controller can either be part of device, or separate. DMA means processor is only involved at start and end, as its job is just to pass over to DMA.

Requires contiguous regions.

Informing CPU of finished task execution

Either CPU can poll devices or they can issue interrupts when they're done.
Both waste CPU time (polling = busy waiting, interrupts = reads/writes have to go through CPU)
When we interrupt we might be waking up a high priority blocked thread. So we make sure it is scheduled next.


Interrupts can cause all kinds of complexity issues in hardware. Generally structured so I/O operations block until interrupts notify them of completion

We split the interrupt handler into 2 parts (for things like hardware - network packets or printers). One that just says 'stop, set up stack, disable interrupts, save, reenable' and the other which is the actual work to be done, which we save for when we have a free moment (instead of handling straight away). The top half is insta-processed (acknowledge the interrupt), the bottom half is done later (actual response).


Classified into different 'types' of devices. Then OS has specs for handling a category (e.g. 'USB drivers').


Buffering IO data to transfer from device to user space. Or vice versa.

• No buffer = one byte at a time. Maaaaaan so slow. Always blocking the reads.
• User space buffer = slightly better. Only works if the place it chooses to use as a buffer doesn't get swapped
• Singular buffer (both kernel and user) = either kernel buffer fills up or user space gets swapped to disk. Same problem! Drop parts of the buffering
• Circular buffer = still the same problems if they fill up. BUT because you do one at a time hopefully they don't fill up all at once woo.

Buffering is a producer consumer problem. So if we add extra buffers then we can process the data in one buffer whilst storing up new data to process in another. Yay magic.

But buffering is not always great because copying has a cost and reducing latency is a key goal.



We use IN and OUT controls to read and write to IO.
Ports have: DD, PORT and PIN. (ddrd, portd, pind).
* DD = direction (is it input, output, some weird combination (e.g. keypad switches))
* PORT = write to
* PIN = read from


We use switches to do input/output. They are either set to high or to low which tells us the combination of things that we want.

But when we pull up switches they bounce! So all we do is detect a low, and then wait for a while to ensure it's stable. Or we can count how long it's been in one state for, and only operate if it's been there for a while.


Keyboard = 2d array of switches. If we close a switch it connects the horizontal and vertical lines.


LCD we have both input register and data register.