On a real embedded target eCos interacts with the hardware by peeking
and poking various registers, manipulating special regions of memory,
and so on. The synthetic target does not access hardware directly.
Instead I/O and other operations are emulated by making appropriate
Linux system calls. The HAL package exports a number of functions
which allow other packages, or even application code, to make these
same system calls. However this facility must be used with care: any
code which calls, for example,
will only ever run on the synthetic target; that functionality is
obviously not provided on any real hardware because there is no
underlying Linux kernel to implement it.
The synthetic target only provides a subset of the available system
calls, specifically those calls which have proved useful to implement
I/O emulation. This subset can be extended fairly easily if necessary.
All of the available calls, plus associated data structures and
macros, are defined in the header file cyg/hal/hal_io.h. There is a simple
convention: given a Linux system call such as
open, the synthetic target will prefix
cyg_hal_sys and provide a function with that name.
The second argument to the
open system call is
a set of flags such as
O_RDONLY, and the header
file will define a matching constant
CYG_HAL_SYS_O_RDONLY. There are also data
structures such as
matching the Linux data structure
In most cases the functions provided by the synthetic target behave as
per the documentation for the Linux system calls, and section 2 of the
Linux man pages can be consulted for more information. There is one
important difference: typically the documentation will say that a
function returns -1 to indicate an error, with the
actual error code held in
errno; the actual
underlying system call and hence the
cyg_hal_sys_xyz provided by eCos instead returns
a negative number to indicate an error, with the absolute value of
that number corresponding to the error code; usually it is the C
library which handles this and manipulates errno, but of course
synthetic target applications are not linked with that Linux library.
However, there are some exceptions. The Linux kernel has evolved over
the years, and some of the original system call interfaces are no
longer appropriate. For example the original
select system call has been superseded by
_newselect, and that is what the
select function in the C library actually uses.
The old call is still available to preserve binary compatibility but,
like the C library, eCos makes use of the new one because it provides
the appropriate functionality. In an attempt to reduce confusion the
eCos function is called
in other words it matches the official system call naming scheme. The
authoritive source of information on such matters is the Linux kernel
sources themselves, and especially its header files.
eCos packages and applications should never #include Linux header files directly. For example, doing a #include </usr/include/fcntl.h> to access additional macros or structure definitions, or alternatively manipulating the header file search path, will lead to problems because the Linux header files are likely to duplicate and clash with definitions in the eCos headers. Instead the appropriate functionality should be extracted from the Linux headers and moved into either cyg/hal/hal_io.h or into application code, with suitable renaming to avoid clashes with eCos names. Users should be aware that large-scale copying may involve licensing complications.
Adding more system calls is usually straightforward and involves adding one or more lines to the platform-specific file in the appropriate platform HAL, for example syscall-i386-linux-1.0.S. However it is necessary to do some research first about the exact interface implemented by the system call, because of issues such as old system calls that have been superseded. The required information can usually be found fairly easily by searching through the Linux kernel sources and possibly the GNU C library sources.