Skip to main content

Section 18.5 I/O Ports

The CPU communicates with an I/O device through I/O ports. The specific port is specified by a value on the address bus. There are two ways to distinguish an I/O port address from a physical memory address:


Also called Isolated I/O. Uses a separate address space to identify the port address and special instructions to read from or write to the port. The distinction between the two addressing spaces is made in the control bus.


Uses a portion of the regular address space for the ports and regular load and store instructions to read from or write to the port.

The Raspberry Pi uses memory-mapped I/O. The addresses used for I/O are specified in the datasheet for the Broadcom BCM2835 SoC[6] used on earlier models of the Raspberry Pi (Table 8.0.1). This model reserves 16 MB, addresses \(\hex{0x20000000}\) to \(\hex{0x20ffffff}\text{,}\) for I/O devices. At the time of this writing, datasheets for the newer SoC models are not available, but they reserve addresses \(\hex{0x3e000000}\) to \(\hex{0x3effffff}\) for I/O devices.

As described in Chapter 17 the Linux kernel maintains control over the hardware resources. The software it uses to interact with each I/O device is called a Device Driver. Application software executes at exception level EL0 (Table 17.1.1) and thus is prohibited from accessing device drivers directly. They must request the services of an I/O device through supervisor calls to the operating system. The general sequence to use an I/O device is

  1. Open the device.

  2. Write to or read from the device.

  3. Close the device.

You have already used this sequence, starting in Section 2.15. When an application is launched, the operating system opens three devices:

  1. stdout—standard output, typically the monitor (terminal window).

  2. stdin—standard input, typically the keyboard.

  3. stderr—standard error, typically the monitor (terminal window).

You have written programs, both in C and in assembly language, that use the write system call to write to stdout and read from stdin. When you quit the program, the operating system automatically closes these devices. The device drivers for the monitor and keyboard are executing at the EL1 exception level, so they can access the ports (memory addresses) for each of these I/O devices. One of the main purposes of a device driver is to deal with the timing of the I/O device to ensure that the input or output is synchronized with its use by the application program.

The Raspberry Pi has a General Purpose Input/Output (GPIO) device connected to a set of pins that you can connect with various electronic devices. We will see how to program the GPIO in Chapter 19.