| @node syscalls,machine,reentrancy,Top |
| @chapter NEC V70 system calls |
| |
| The library needs a certain amount of system-specific support in order |
| to operate. These routines have to be written for each unique |
| target environment. For testing purposes, |
| a set of system calls specific to an NEC V70 Unix PC running AT&T Unix |
| System V R2 are included. These files are in the @file{sys/sysvnecv70} |
| directory. |
| |
| All the calls have to be implemented in order to avoid link time |
| errors, but the implementation need not include all possible |
| functionality; in general, for any functionality that isn't |
| available, returning an error code is sufficient. |
| |
| @section Input/Output |
| |
| The V70 target may not have any character I/O devices. |
| In this case, the @code{fstat}, @code{ioctl}, @code{isatty}, |
| @code{lseek}, @code{read} and @code{write} routines may all return @code{-1}, |
| to signal failure (inspect @file{cerror.s} to see how to do this). |
| |
| Sometimes it is correct to implement the functions in a very |
| simple and machine specific way. For instance, the target board may |
| have one serial line. |
| |
| In this case, the @code{write} system call can be ``hard-wired'' to |
| always print to the serial device, no matter what the supplied file |
| handle says. Similarly, the other I/O system calls can be written to |
| take advantage of a known configuration. |
| |
| Note that the library starts up assuming that three files are already |
| open. File handles used are: |
| @table @code |
| @item 0 |
| Is used for all input from @code{stdin}. |
| @item 1 |
| Is used for all output to @code{stdout}. This includes functions like |
| @code{putc} and @code{printf}. |
| @item 2 |
| Is used for all output to @code{stderr}. The library will use this |
| file to print error messages from the math functions. Output can |
| also be sent to @code{stderr} by @code{fprintf(stderr,@dots{})} |
| @end table |
| @section Example @code{write} routine |
| On a board with a very simple I/O structure, this would be adequate: |
| |
| @example |
| |
| @group |
| char *duart_status = DUART_ADDR; |
| |
| void poll() |
| @{ |
| /* Dummy function to fool optimizer */ |
| @} |
| |
| int write(fd, string, len) |
| int fd; |
| char *string; |
| int len; |
| @{ |
| int i; |
| |
| for (i = 0; i < len; i++) |
| @{ |
| while (*duart_status & DUART_BUSY) |
| poll(); |
| *duart_port = string[i]; |
| @} |
| return len; |
| @} |
| @end group |
| @end example |
| |
| @section Memory allocation |
| |
| The library allocates memory from the heap either for its own use, or when |
| you explicitly call @code{malloc}. It asks the system for |
| memory by calling the @code{sbrk} function. |
| |
| On a Unix system, @code{sbrk} keeps track of the heap's extent by keeping a |
| pointer to the end of the @code{bss} section. Unix linkers |
| traditionaly mark the end of @code{bss} by creating a symbol |
| @code{_end}. When the library wants more memory, it calls |
| @code{sbrk} with the size of the request. @code{sbrk} must then |
| perform an operation specific to the target environment, and return a pointer |
| to the new area. For a simple application, the following fragment may |
| be sufficient: |
| @example |
| |
| @group |
| char *moving_end = &end; |
| |
| char *sbrk(request) |
| int request; |
| @{ |
| char *return_address; |
| |
| return_address = moving_end; |
| moving_end += request; |
| return return_address; |
| @} |
| @end group |
| @end example |
| |
| @section Initialization and termination |
| |
| The system dependent support routines are responsible for |
| initializing the library for use by an application, and cleaning up |
| when the application is complete. |
| |
| This functionality is traditionally provided in @code{crt0} and |
| @code{_exit}. |
| |
| The @code{crt0} function usually contains the instructions first run |
| by the operating system when an application starts. The |
| @code{crt0} function can take advantage of this and prepare the way |
| for the libary. |
| |
| Another task for @code{crt0} is to call the @code{main} function |
| provided by the application writer, and also to call @code{exit} if |
| the main function ever returns. |
| |
| @code{exit} tells the operating system that the application has |
| finished. |
| |
| |
| |