Now that we've seen the problems, let's take a look at some
of the solutions you can use. The following header files are
shipped standard with Neutrino:
<gulliver.h>
isolates big-endian vs little-endian issues
<hw/inout.h>
provides input and output functions for I/O or memory address
spaces
Determining endianness
The file <gulliver.h> contains macros to help resolve endian issues. The first thing you may need to know is the target system's endianness, which
you can find out via the following macros:
Swapping data if required
Suppose you need to ensure that data obtained in the host order (i.e. whatever is "native" on this machine) is returned in a particular order, either big- or little-endian. Or vice versa: you want to convert data
from host order to big- or little-endian. You can use the following macros (described here as if they're functions for syntactic
convenience):
Accessing unaligned data
To access data on nonaligned boundaries, you have to access the data one byte at a time (the correct endian order is preserved
during byte access). The following macros (documented as functions for convenience) accomplish this:
Examples
Here are some examples showing how to access different pieces of data using the macros introduced so far.
Accessing I/O ports
When porting code that accesses hardware, the x86 architecture has a set of instructions that manipulate a separate address
space called the I/O address space. This address space is completely separate from the memory address space. On non-x86 platforms (PPC, etc.), such an address
space doesn't exist — all devices are mapped into memory.