Networking with the Printer Port

One of the strengths of Linux is its ability to serve both as engine for powerful number-crunchers and as effective support for minimal computer systems. The PLIP implementation is an outstanding resource in the latter realm, and this article shows its internals at the software level.

PLIP means “Parallel Line Internet Protocol”. It is a protocol used to bring IP traffic over a parallel cable. It works with any parallel interface and is able to transfer about 40KB per second. With PLIP you can connect any two computers at virtually no cost. Although nowadays ISA network cards are readily found and installed, you will still enjoy PLIP as soon as you get a laptop, unless you can afford a PCMCIA network card.

PLIP allows you to connect your computer to the Internet wherever there is a networked Linux box with a parallel port available, as long as you have root access on both systems (only root can load a module or configure an interface).

I find the internal design of PLIP quite interesting on three levels:

  1. It shows how to use simple I/O instructions.

  2. It lets you look at how network interfaces fit in the overall kernel.

  3. It shows in practice how kernel software uses the task queues.

Hardware Handling

Before showing any PLIP code, I'd like to describe the workings of the standard parallel port, so that you'll be able to understand how the actual data transfer takes place.

The parallel port is a simple device; its external connector exposes 12 output bits and 5 input bits. Software has direct access to the bits by means of three 8-bit ports: two ports for writing and one for reading. Moreover, one of the input signals can trigger an interrupt; this ability is enabled by setting a bit in one of the output ports. Figure 1 shows how the three ports are mapped to the 25-pin connector. The base_addr of a parallel port (the address of its data port) is usually 0x378, 0x278 or 0x3bc. The vast majority of the parallel ports uses 0x378.

Figure 1. Mapping of Three Ports to Connector

Physical access to the ports is achieved by calling two C-language functions defined in the kernel headers:

#include <linux/io.h>
unsigned char inb(unsigned short port);
void outb(unsigned char value, unsigned short port);

The “b” in the function name means “byte”. Linux also offers inw (word, 16-bit), inl (long, 32-bit) and their output counterparts, but they are not needed to use the parallel port. The functions just shown are in fact macros, and they expand to a single machine instruction on most Linux platforms. Their definition relies on extern inline functions; this means you must turn optimization on when compiling any code using them. The reason behind this is somehow technical, and it is well explained in the gcc man page.

You don't need to be in kernel space to call inb and outb. If you want to access I/O ports from a shell script, you can compile inp.c and outp.c and play games with your devices (and even destroy the computer). For this reason, only root can access ports. The source code for inp.c and outp.c is available by anonymous download in the file


Based on the description of the parallel port I provided in the previous section, it should be clear that two parties that communicate using PLIP must exchange five bits at a time, at most. The PLIP cable must be specially wired in order to connect five of the outputs of one side to the five inputs at the other side, and vice-versa. The exact pin out of the PLIP cable is described in the source file drivers/net/plip.c and in several places elsewhere, so I won't repeat the information here.

One of the deficiencies of the parallel port is the unavailability of any timing resources in hardware. Compare this with the serial port which contains its own clock. The communication protocol can't exploit any advanced hardware functionality, and any handshake must be performed in software. The chosen protocol uses one of the bits as a strobe signal to signal the availability of four data bits; the receiver must acknowledge receipt of the data by toggling its own strobe line. This approach to data transmission is very CPU intensive. The processor must poll the strobe signal to send its data, and system performance degrades severely during PLIP data transfers.

The time line of a PLIP transmission is depicted in Figure 2, which details the steps involved in the transmission of a single byte of information.

Figure 2. Time Line of PLIP Transmission