Design Article

Unix portability: underutilized in embedded development

Alistair Crooks, Director of Engineering, Wasabi Systems, New York, NY

12/13/2002 11:10 AM EST

Unix portability: underutilized in embedded development

One of the most important considerations in choosing an operating system for a new embedded platform is how long it takes to port the operating system to the hardware. If your hot, new product's hardware is six months ahead of the curve, but it takes you six months to port the software, you've lost your hardware advantage.

Portability is the ability of a piece of software to move easily from one hardware platform to another. Unix was the first portable operating system, reimplemented in C to enable it to move from early Digital Equipment Corp. minicomputers to later, more advanced products. C itself was invented specifically for the purpose of enabling Unix to be portable and compiles on almost every CPU used in computing today.

Many operating systems are written in C and are, in theory, portable. In reality, most Unix implementations, despite being written primarily in C, are not truly portable. Often, code makes assumptions about the hardware it will be running on with regards to word-endianness or integer size, or simply reflects quirks about the hardware on which it was developed. This unportable C code adds dramatically to the time and cost of a porting job, as it is not often clearly delineated as being machine-dependent (MD) and may be difficult to hunt down.

Unix was designed to be highly modular, where each piece of the operating system is small and is meant to work with other pieces. Modularity is highly important to a portable operating system, enabling both greater customization and code reuse, yet most Unix operating systems have failed to take sufficient advantage of this feature.

Linux, a Unix-based operating system that has seen increasing embedded usage, was originally developed for the IA-32 architecture, where it still sees the most use. Consequently, the Linux memory management system is designed around the three level MMU available on IA-32 processors. For these and similar processors this works extremely well, but it forces systems with other MMU designs to suffer the complexity and performance impact of making the underlying hardware appear to function like a three level MMU system. In many cases, this requires code to perform specific low level hardware access (for example, to flush TLBs) to be scattered throughout the kernel . Further, drivers require intimate knowledge of the hardware and busses to which they attach, resulting in many cases in completely independent drivers for identical hardware based purely on the bus type, or architecture of the machine's CPU.

NetBSD, like Linux, is an open source Unix-based operating system, but it has been multiarchitectural from its inception, running on not only IBM PCs, but Acorn ARM-based PCs, Digital Alpha servers and workstations, MIPS workstations, and VAX minicomputers and workstations, Motorola 68000-based PCs and workstations, and Sun SPARC workstations to name but a few. From early on, an effort was made to integrate all of these architectures, whether RISC or CISC, 32- or 64-bit, big or little-endian, into one source tree. This was accomplished through the rigorous separation of machine-dependent and machine-independent (MI) code, allowing sharing of code across platforms wherever appropriate. As descendants of the chips used in these workstations become common in the embedded space, this heritage has stood NetBSD in good stead.

Clean code

Just as there is more to portability than simply writing code in C, there is more to a piece of hardware than its CPU. A truly portable operating system must be able to easily support new devices, as well as processors.

The overwhelming majority of operating systems require reimplementation of device drivers for each new architecture, greatly increasing the time and cost of a porting project. Often, due to architectural constraints, the same device will need to access I/O and memory differently on different hardware architectures, or potentially even on different buses on the same machine.

NetBSD takes advantage of Unix's modular nature by separating the MD and MI parts of the driver code. A "bus space" abstraction is provided for each bus which encapsulates any requirements for accessing memory and hardware for that machine type. Drivers are split into chipset specific code, and a "glue" portion to attach the driver to a given bus. This permits the same chipset driver to to work across a range of platforms without requiring any knowledge of the differing constraints such as alignment, byte swapping busses, or cache synchronisation. Thus, once a bus is supported for a given architecture, most of the devices that use that bus interface will be supported.

This clean approach to proper abstraction extends to kernel memory management. All of the higher level facilities such as managing virtual address space, resolution of page faults and uio-based I/O to virtual memory are handled by the MI "UVM" system. This in turn calls the MD "pmap" which manages physical address maps, programs MMU hardware and performs any required cache operations. This abstraction allows the low level pmap code to implement the data structures and algorithms best suited to each individual hardware architecture, without requiring any changes to the upper level UVM code.

With clean code and proper abstraction, code reuse is maximized, and adding new architectures becomes simple. This makes it possible for an operating system to be maintained for hundreds of boards, representing fifteen distinct CPU architectures, from a single source tree. The result of these simple practices, derived from the heritage of Unix, is an operating system that maximizes portability — NetBSD was recently ported to SuperH's new 64-bit SH-5 architecture in six weeks, as contrasted with the eight months it took to port Linux to that architecture.





Please sign in to post comment

Navigate to related information

Datasheets.com Parts Search

185 million searchable parts
(please enter a part number or hit search to begin)

Feedback Form