From b500b1a7b78490f537ff0925152b98a8c73516ff Mon Sep 17 00:00:00 2001 From: dtrg Date: Sat, 21 Apr 2007 23:02:11 +0000 Subject: [PATCH] Added linux386 platform. --- plat/linux386/.distr | 14 ++ plat/linux386/README | 40 ++++ plat/linux386/boot.s | 40 ++++ plat/linux386/descr | 73 +++++++ plat/linux386/include/ack/config.h | 14 ++ plat/linux386/include/sys/ioctl.h | 76 +++++++ plat/linux386/include/unistd.h | 123 +++++++++++ plat/linux386/libsys/_exit.c | 14 ++ plat/linux386/libsys/_hol0.s | 20 ++ plat/linux386/libsys/_syscall.s | 47 ++++ plat/linux386/libsys/brk.c | 13 ++ plat/linux386/libsys/close.c | 14 ++ plat/linux386/libsys/creat.c | 13 ++ plat/linux386/libsys/errno.s | 28 +++ plat/linux386/libsys/getpid.c | 14 ++ plat/linux386/libsys/gettimeofday.c | 16 ++ plat/linux386/libsys/isatty.c | 13 ++ plat/linux386/libsys/kill.c | 14 ++ plat/linux386/libsys/libsys.h | 15 ++ plat/linux386/libsys/lseek.c | 14 ++ plat/linux386/libsys/open.c | 25 +++ plat/linux386/libsys/pmfile | 31 +++ plat/linux386/libsys/read.c | 14 ++ plat/linux386/libsys/sbrk.c | 31 +++ plat/linux386/libsys/signal.c | 14 ++ plat/linux386/libsys/syscalls.h | 328 ++++++++++++++++++++++++++++ plat/linux386/libsys/write.c | 14 ++ plat/linux386/pmfile | 46 ++++ 28 files changed, 1118 insertions(+) create mode 100644 plat/linux386/.distr create mode 100644 plat/linux386/README create mode 100644 plat/linux386/boot.s create mode 100644 plat/linux386/descr create mode 100644 plat/linux386/include/ack/config.h create mode 100644 plat/linux386/include/sys/ioctl.h create mode 100644 plat/linux386/include/unistd.h create mode 100644 plat/linux386/libsys/_exit.c create mode 100644 plat/linux386/libsys/_hol0.s create mode 100644 plat/linux386/libsys/_syscall.s create mode 100644 plat/linux386/libsys/brk.c create mode 100644 plat/linux386/libsys/close.c create mode 100644 plat/linux386/libsys/creat.c create mode 100644 plat/linux386/libsys/errno.s create mode 100644 plat/linux386/libsys/getpid.c create mode 100644 plat/linux386/libsys/gettimeofday.c create mode 100644 plat/linux386/libsys/isatty.c create mode 100644 plat/linux386/libsys/kill.c create mode 100644 plat/linux386/libsys/libsys.h create mode 100644 plat/linux386/libsys/lseek.c create mode 100644 plat/linux386/libsys/open.c create mode 100644 plat/linux386/libsys/pmfile create mode 100644 plat/linux386/libsys/read.c create mode 100644 plat/linux386/libsys/sbrk.c create mode 100644 plat/linux386/libsys/signal.c create mode 100644 plat/linux386/libsys/syscalls.h create mode 100644 plat/linux386/libsys/write.c create mode 100644 plat/linux386/pmfile diff --git a/plat/linux386/.distr b/plat/linux386/.distr new file mode 100644 index 000000000..98965493d --- /dev/null +++ b/plat/linux386/.distr @@ -0,0 +1,14 @@ +descr +boot.s +pmfile +README +libsys/pmfile +libsys/libsys.h +libsys/_sys_rawwrite.s +libsys/_mon.s +libsys/_sys_write.c +libsys/_sys_read.c +libsys/_sys_rawread.s +libsys/_brk.s +libsys/errno.s +libsys/_sys_ioctl.c diff --git a/plat/linux386/README b/plat/linux386/README new file mode 100644 index 000000000..a6c27e8a5 --- /dev/null +++ b/plat/linux386/README @@ -0,0 +1,40 @@ +# $Source$ +# $State$ +# $Revision$ + + +The linux386 platform +===================== + +linux386 is an i386-based BSP that produces Linux ELF executables. + +This port only implements a very limited number of system calls; basically, +just enough to make the demo apps run. Adding more is easy, but there are some +subtleties that require more thought. The port should be considered only in +proof-of-concept stage right now. + +Important note: you *can't* link access ELF shared libraries from these +executables. In other words, you have to all your work from inside ACK. + +The executables are generated with aelfslod and are extremely simple; there's +one rwx ELF section which contains all the application's code and data. This +is not optimal, but it does work. + + +Bugs +==== + +isatty() is a stub and always returns 0. + + +Example command line +==================== + +ack -mlinux386 -O -o linux386.exe examples/paranoia.c + +The file linux386.exe can then be run on a i386 Linux machine (or on an +emulation thereof). + + +David Given +dg@cowlark.com diff --git a/plat/linux386/boot.s b/plat/linux386/boot.s new file mode 100644 index 000000000..86ce05b49 --- /dev/null +++ b/plat/linux386/boot.s @@ -0,0 +1,40 @@ +# +! $Source$ +! $State$ +! $Revision$ + +! Declare segments (the order is important). + +.sect .text +.sect .rom +.sect .data +.sect .bss + +.sect .text + +begtext: + ! This code is placed at the beginning of the ELF executable and is the + ! first thing that runs. + + jmp __m_a_i_n + + ! This provides an emergency exit routine used by EM. + +.define EXIT +.extern EXIT +EXIT: + push 1 + jmp __exit + +! Define symbols at the beginning of our various segments, so that we can find +! them. (Except .text, which has already been done.) + +.sect .data; begdata: +.sect .rom; begrom: +.sect .bss; begbss: + +! Some magic data. All EM systems need these. + +.define .trppc, .ignmask +.comm .trppc, 4 +.comm .ignmask, 4 diff --git a/plat/linux386/descr b/plat/linux386/descr new file mode 100644 index 000000000..6b7b1a0af --- /dev/null +++ b/plat/linux386/descr @@ -0,0 +1,73 @@ +# $Source$ +# $State$ +# $Revision$ + +var w=4 +var p=4 +var s=2 +var l=4 +var f=4 +var d=8 +var ARCH=i386 +var PLATFORM=linux386 +var PLATFORMDIR={EM}/lib/{PLATFORM} +var CPP_F=-D__unix +var ALIGN=-a0:4 -a1:4 -a2:4 -a3:4 -b0:0x08048054 +var C_LIB={PLATFORMDIR}/libc-ansi.a +# bitfields reversed for compatibility with (g)cc. +var CC_ALIGN=-Vr +var OLD_C_LIB={C_LIB} +var MACHOPT_F=-m10 + +# Override the setting in fe so that files compiled for linux386 can see +# the platform-specific headers. + +var C_INCLUDES=-I{PLATFORMDIR}/include -I{EM}/include/ansi + +name be + from .m.g + to .s + program {EM}/lib.bin/{PLATFORM}/ncg + mapflag -gdb GF=-gdb + args {GF?} < + stdout + need .e +end +name as + from .s.so + to .o + program {EM}/lib.bin/{PLATFORM}/as + args - -o > < + prep cond +end +name led + from .o.a + to .out + program {EM}/lib.bin/em_led + mapflag -l* LNAME={PLATFORMDIR}/lib* + mapflag -fp FLOATS={EM}/{LIB}fp + args {ALIGN} {SEPID?} \ + (.e:{HEAD}={PLATFORMDIR}/boot.o) \ + ({RTS}:.ocm.b={PLATFORMDIR}/c-ansi.o) \ + ({RTS}:.c={PLATFORMDIR}/c-ansi.o) \ + ({RTS}:.mod={PLATFORMDIR}/modula2.o) \ + ({RTS}:.p={PLATFORMDIR}/pascal.o) \ + -o > < \ + (.p:{TAIL}={PLATFORMDIR}/libpascal.a) \ + (.b:{TAIL}={PLATFORMDIR}/libbasic.a) \ + (.mod:{TAIL}={PLATFORMDIR}/libmodula2.a) \ + (.ocm:{TAIL}={PLATFORMDIR}/liboccam.a) \ + (.ocm.b.mod.c.p:{TAIL}={PLATFORMDIR}/libc.a) \ + {FLOATS?} \ + (.e:{TAIL}={PLATFORMDIR}/libem.a \ + {PLATFORMDIR}/libsys.a \ + {PLATFORMDIR}/libend.a) + linker +end +name cv + from .out + to .exe + program {EM}/bin/aelflod + args < > + outfile linux386.exe +end diff --git a/plat/linux386/include/ack/config.h b/plat/linux386/include/ack/config.h new file mode 100644 index 000000000..af4a90ed2 --- /dev/null +++ b/plat/linux386/include/ack/config.h @@ -0,0 +1,14 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#ifndef _ACK_CONFIG_H +#define _ACK_CONFIG_H + +/* We're providing a time() system call rather than wanting a wrapper around + * gettimeofday() in the libc. */ + +/* #define ACKCONF_TIME_IS_A_SYSCALL */ + +#endif diff --git a/plat/linux386/include/sys/ioctl.h b/plat/linux386/include/sys/ioctl.h new file mode 100644 index 000000000..e35308d8a --- /dev/null +++ b/plat/linux386/include/sys/ioctl.h @@ -0,0 +1,76 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#ifndef _SYS_IOCTL_H +#define _SYS_IOCTL_H + +/* These are copied from the ioctl_list(2) man page. */ + +/* */ + +#define FIOSETOWN 0x00008901 +#define SIOCSPGRP 0x00008902 +#define FIOGETOWN 0x00008903 +#define SIOCGPGRP 0x00008904 +#define SIOCATMARK 0x00008905 +#define SIOCGSTAMP 0x00008906 + +/* */ + +#define TCGETS 0x00005401 +#define TCSETS 0x00005402 +#define TCSETSW 0x00005403 +#define TCSETSF 0x00005404 +#define TCGETA 0x00005405 +#define TCSETA 0x00005406 +#define TCSETAW 0x00005407 +#define TCSETAF 0x00005408 +#define TCSBRK 0x00005409 +#define TCXONC 0x0000540A +#define TCFLSH 0x0000540B +#define TIOCEXCL 0x0000540C +#define TIOCNXCL 0x0000540D +#define TIOCSCTTY 0x0000540E +#define TIOCGPGRP 0x0000540F +#define TIOCSPGRP 0x00005410 +#define TIOCOUTQ 0x00005411 +#define TIOCSTI 0x00005412 +#define TIOCGWINSZ 0x00005413 +#define TIOCSWINSZ 0x00005414 +#define TIOCMGET 0x00005415 +#define TIOCMBIS 0x00005416 +#define TIOCMBIC 0x00005417 +#define TIOCMSET 0x00005418 +#define TIOCGSOFTCAR 0x00005419 +#define TIOCSSOFTCAR 0x0000541A +#define FIONREAD 0x0000541B +#define TIOCINQ 0x0000541B +#define TIOCLINUX 0x0000541C +#define TIOCCONS 0x0000541D +#define TIOCGSERIAL 0x0000541E +#define TIOCSSERIAL 0x0000541F +#define TIOCPKT 0x00005420 +#define FIONBIO 0x00005421 +#define TIOCNOTTY 0x00005422 +#define TIOCSETD 0x00005423 +#define TIOCGETD 0x00005424 +#define TCSBRKP 0x00005425 +#define TIOCTTYGSTRUCT 0x00005426 +#define FIONCLEX 0x00005450 +#define FIOCLEX 0x00005451 +#define FIOASYNC 0x00005452 +#define TIOCSERCONFIG 0x00005453 +#define TIOCSERGWILD 0x00005454 +#define TIOCSERSWILD 0x00005455 +#define TIOCGLCKTRMIOS 0x00005456 +#define TIOCSLCKTRMIOS 0x00005457 +#define TIOCSERGSTRUCT 0x00005458 +#define TIOCSERGETLSR 0x00005459 +#define TIOCSERGETMULTI 0x0000545A +#define TIOCSERSETMULTI 0x0000545B + + + +#endif diff --git a/plat/linux386/include/unistd.h b/plat/linux386/include/unistd.h new file mode 100644 index 000000000..cd78196f3 --- /dev/null +++ b/plat/linux386/include/unistd.h @@ -0,0 +1,123 @@ +/* + * unistd.h - standard system calls + */ +/* $Id$ */ + +#ifndef _UNISTD_H +#define _UNISTD_H + +#include +#include + +/* Types */ + +typedef int pid_t; +typedef int mode_t; + +typedef long suseconds_t; + +/* Time handling. */ + +struct timeval +{ + time_t tv_sec; + suseconds_t tv_usec; +}; + +struct timezone +{ + int tz_minuteswest; + int tz_dsttime; +}; /* obsolete, unused */ + +extern int gettimeofday(struct timeval* tv, struct timezone* tz); +extern int settimeofday(const struct timeval* tv, const struct timezone* tz); + +/* File access. */ + +enum +{ + O_ACCMODE = 0x3, + + O_RDONLY = 0, + O_WRONLY = 1, + O_RDWR = 2, + + O_CREAT = 0x10, + O_TRUNC = 0x20, + O_APPEND = 0x40 +}; + +extern int open(const char* path, int access, ...); +extern int creat(const char* path, mode_t mode); +extern int close(int d); +extern int read(int fd, void* buffer, size_t count); +extern int write(int fd, void* buffer, size_t count); +extern off_t lseek(int fildes, off_t offset, int whence); +extern int fcntl(int fd, int op, ...); + +/* Special variables */ + +extern char** environ; + +/* Implemented system calls */ + +extern void _exit(int); +extern pid_t getpid(void); +extern int brk(void* ptr); +extern void* sbrk(intptr_t increment); +extern int isatty(int d); + +/* Signal handling */ + +typedef int sig_atomic_t; + +#define SIG_ERR ((__sighandler_t) -1) /* Error return. */ +#define SIG_DFL ((__sighandler_t) 0) /* Default action. */ +#define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */ + +#define SIGHUP 1 /* Hangup (POSIX). */ +#define SIGINT 2 /* Interrupt (ANSI). */ +#define SIGQUIT 3 /* Quit (POSIX). */ +#define SIGILL 4 /* Illegal instruction (ANSI). */ +#define SIGTRAP 5 /* Trace trap (POSIX). */ +#define SIGABRT 6 /* Abort (ANSI). */ +#define SIGIOT 6 /* IOT trap (4.2 BSD). */ +#define SIGBUS 7 /* BUS error (4.2 BSD). */ +#define SIGFPE 8 /* Floating-point exception (ANSI). */ +#define SIGKILL 9 /* Kill, unblockable (POSIX). */ +#define SIGUSR1 10 /* User-defined signal 1 (POSIX). */ +#define SIGSEGV 11 /* Segmentation violation (ANSI). */ +#define SIGUSR2 12 /* User-defined signal 2 (POSIX). */ +#define SIGPIPE 13 /* Broken pipe (POSIX). */ +#define SIGALRM 14 /* Alarm clock (POSIX). */ +#define SIGTERM 15 /* Termination (ANSI). */ +#define SIGSTKFLT 16 /* Stack fault. */ +#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */ +#define SIGCHLD 17 /* Child status has changed (POSIX). */ +#define SIGCONT 18 /* Continue (POSIX). */ +#define SIGSTOP 19 /* Stop, unblockable (POSIX). */ +#define SIGTSTP 20 /* Keyboard stop (POSIX). */ +#define SIGTTIN 21 /* Background read from tty (POSIX). */ +#define SIGTTOU 22 /* Background write to tty (POSIX). */ +#define SIGURG 23 /* Urgent condition on socket (4.2 BSD). */ +#define SIGXCPU 24 /* CPU limit exceeded (4.2 BSD). */ +#define SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */ +#define SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */ +#define SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */ +#define SIGWINCH 28 /* Window size change (4.3 BSD, Sun). */ +#define SIGPOLL SIGIO /* Pollable event occurred (System V). */ +#define SIGIO 29 /* I/O now possible (4.2 BSD). */ +#define SIGPWR 30 /* Power failure restart (System V). */ +#define SIGSYS 31 /* Bad system call. */ +#define SIGUNUSED 31 + +#define _NSIG 32 /* Biggest signal number + 1 + (not including real-time signals). */ +typedef void (*sighandler_t)(int); +extern sighandler_t signal(int signum, sighandler_t handler); +extern int raise(int signum); + + + +#endif diff --git a/plat/linux386/libsys/_exit.c b/plat/linux386/libsys/_exit.c new file mode 100644 index 000000000..3171a1cce --- /dev/null +++ b/plat/linux386/libsys/_exit.c @@ -0,0 +1,14 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include +#include "libsys.h" + +void _exit(int status) +{ + _syscall(__NR_exit, status, 0, 0); +} diff --git a/plat/linux386/libsys/_hol0.s b/plat/linux386/libsys/_hol0.s new file mode 100644 index 000000000..99a29fd4a --- /dev/null +++ b/plat/linux386/libsys/_hol0.s @@ -0,0 +1,20 @@ +# +! $Source$ +! $State$ +! $Revision$ + +! Declare segments (the order is important). + +.sect .text +.sect .rom +.sect .data +.sect .bss + +.sect .text + +! +! This data block is used to store information about the current line number +! and file. + +.define hol0 +.comm hol0, 8 diff --git a/plat/linux386/libsys/_syscall.s b/plat/linux386/libsys/_syscall.s new file mode 100644 index 000000000..f765ccfbe --- /dev/null +++ b/plat/linux386/libsys/_syscall.s @@ -0,0 +1,47 @@ +# +! $Source$ +! $State$ +! $Revision$ + +#include "syscalls.h" + +! Declare segments (the order is important). + +.sect .text +.sect .rom +.sect .data +.sect .bss + +.sect .text + +EINVAL = 22 + +! Perform a Linux system call. + +.define __syscall + +__syscall: + mov eax, 4(esp) + mov ebx, 8(esp) + mov ecx, 12(esp) + mov edx, 16(esp) + + int 0x80 + or eax, eax + jl 1f + ret +1: + neg eax + ! It just so happens that errnos 1-34 are the same in Linux as in the ACK. + cmp eax, 1 + jb 2f + cmp eax, 34 + ja 2f + mov (_errno), eax +3: + mov eax, -1 + ret +2: + ! All other errnos become EINVAL for now. FIXME dtrg. + mov (_errno), EINVAL + jmp 3b diff --git a/plat/linux386/libsys/brk.c b/plat/linux386/libsys/brk.c new file mode 100644 index 000000000..cf6c4d2d1 --- /dev/null +++ b/plat/linux386/libsys/brk.c @@ -0,0 +1,13 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include "libsys.h" + +int brk(void* end) +{ + return _syscall(__NR_brk, (quad) end, 0, 0); +} diff --git a/plat/linux386/libsys/close.c b/plat/linux386/libsys/close.c new file mode 100644 index 000000000..2615333e2 --- /dev/null +++ b/plat/linux386/libsys/close.c @@ -0,0 +1,14 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include +#include "libsys.h" + +int close(int fd) +{ + return _syscall(__NR_close, fd, 0, 0); +} diff --git a/plat/linux386/libsys/creat.c b/plat/linux386/libsys/creat.c new file mode 100644 index 000000000..984ae6cf5 --- /dev/null +++ b/plat/linux386/libsys/creat.c @@ -0,0 +1,13 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include "libsys.h" + +int creat(const char* filename, int mode) +{ + return open(filename, O_CREAT|O_WRONLY|O_TRUNC, mode); +} diff --git a/plat/linux386/libsys/errno.s b/plat/linux386/libsys/errno.s new file mode 100644 index 000000000..9858d2640 --- /dev/null +++ b/plat/linux386/libsys/errno.s @@ -0,0 +1,28 @@ +# +! $Source$ +! $State$ +! $Revision$ + +! Declare segments (the order is important). + +.sect .text +.sect .rom +.sect .data +.sect .bss + +#define D(e) .define e; e + +.sect .data + +! Define various ACK error numbers. Note that these are *not* ANSI C +! errnos, and are used for different purposes. + +D(ERANGE) = 1 +D(ESET) = 2 +D(EIDIVZ) = 6 +D(EHEAP) = 17 +D(EILLINS) = 18 +D(EODDZ) = 19 +D(ECASE) = 20 +D(EBADMON) = 25 + diff --git a/plat/linux386/libsys/getpid.c b/plat/linux386/libsys/getpid.c new file mode 100644 index 000000000..ca2803246 --- /dev/null +++ b/plat/linux386/libsys/getpid.c @@ -0,0 +1,14 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include +#include "libsys.h" + +pid_t getpid(void) +{ + return _syscall(__NR_getpid, 0, 0, 0); +} diff --git a/plat/linux386/libsys/gettimeofday.c b/plat/linux386/libsys/gettimeofday.c new file mode 100644 index 000000000..df01df5e7 --- /dev/null +++ b/plat/linux386/libsys/gettimeofday.c @@ -0,0 +1,16 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include +#include +#include +#include "libsys.h" + +int gettimeofday(struct timeval *tv, struct timezone *tz) +{ + return _syscall(__NR_gettimeofday, (quad) tv, (quad) tz, 0); +} diff --git a/plat/linux386/libsys/isatty.c b/plat/linux386/libsys/isatty.c new file mode 100644 index 000000000..23ffb7fb3 --- /dev/null +++ b/plat/linux386/libsys/isatty.c @@ -0,0 +1,13 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include + +int isatty(int fd) +{ + return 0; +} diff --git a/plat/linux386/libsys/kill.c b/plat/linux386/libsys/kill.c new file mode 100644 index 000000000..6b4cace40 --- /dev/null +++ b/plat/linux386/libsys/kill.c @@ -0,0 +1,14 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include +#include "libsys.h" + +int kill(pid_t pid, int signum) +{ + return _syscall(__NR_kill, pid, signum, 0); +} diff --git a/plat/linux386/libsys/libsys.h b/plat/linux386/libsys/libsys.h new file mode 100644 index 000000000..58d02d8cc --- /dev/null +++ b/plat/linux386/libsys/libsys.h @@ -0,0 +1,15 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#ifndef LIBSYS_H +#define LIBSYS_H + +#include "syscalls.h" + +typedef unsigned long quad; + +extern quad _syscall(int op, quad p1, quad p2, quad p3); + +#endif diff --git a/plat/linux386/libsys/lseek.c b/plat/linux386/libsys/lseek.c new file mode 100644 index 000000000..ca903c514 --- /dev/null +++ b/plat/linux386/libsys/lseek.c @@ -0,0 +1,14 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include +#include "libsys.h" + +off_t lseek(int fd, off_t offset, int whence) +{ + return _syscall(__NR_lseek, fd, offset, whence); +} diff --git a/plat/linux386/libsys/open.c b/plat/linux386/libsys/open.c new file mode 100644 index 000000000..1e8d9890e --- /dev/null +++ b/plat/linux386/libsys/open.c @@ -0,0 +1,25 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include +#include +#include "libsys.h" + +int open(const char* path, int access, ...) +{ + int mode = 0; + + if (access & O_CREAT) + { + va_list ap; + va_start(ap, access); + mode = va_arg(ap, int); + va_end(ap); + } + + return _syscall(__NR_open, (quad) path, access, mode); +} diff --git a/plat/linux386/libsys/pmfile b/plat/linux386/libsys/pmfile new file mode 100644 index 000000000..6ab47b504 --- /dev/null +++ b/plat/linux386/libsys/pmfile @@ -0,0 +1,31 @@ +-- $Source$ +-- $State$ +-- $Revision$ + +local d = ROOTDIR.."plat/linux386/libsys/" + +libsys_linux386 = acklibrary { + ACKBUILDFLAGS = {PARENT, "-ansi"}, + ACKINCLUDES = {"%BINDIR%include"}, + + ackfile (d.."errno.s"), + ackfile (d.."_hol0.s"), + ackfile (d.."_syscall.s"), + + ackfile (d.."brk.c"), + ackfile (d.."close.c"), + ackfile (d.."creat.c"), + ackfile (d.."getpid.c"), + ackfile (d.."gettimeofday.c"), + ackfile (d.."_exit.c"), + ackfile (d.."isatty.c"), + ackfile (d.."kill.c"), + ackfile (d.."lseek.c"), + ackfile (d.."open.c"), + ackfile (d.."read.c"), + ackfile (d.."sbrk.c"), + ackfile (d.."signal.c"), + ackfile (d.."write.c"), + + install = pm.install("%BINDIR%lib/%PLATFORM%/libsys.a"), +} diff --git a/plat/linux386/libsys/read.c b/plat/linux386/libsys/read.c new file mode 100644 index 000000000..8d67190c9 --- /dev/null +++ b/plat/linux386/libsys/read.c @@ -0,0 +1,14 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include +#include "libsys.h" + +int read(int fd, void* buffer, size_t count) +{ + return _syscall(__NR_read, fd, (quad) buffer, count); +} diff --git a/plat/linux386/libsys/sbrk.c b/plat/linux386/libsys/sbrk.c new file mode 100644 index 000000000..121de9aee --- /dev/null +++ b/plat/linux386/libsys/sbrk.c @@ -0,0 +1,31 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include "libsys.h" + +#define OUT_OF_MEMORY (void*)(-1) /* sbrk returns this on failure */ + +extern char _end[1]; + +static char* current = _end; + +void* sbrk(intptr_t increment) +{ + char* old; + char* new; + + if (increment == 0) + return current; + + old = current; + new = old + increment; + if (brk(new) < 0) + return OUT_OF_MEMORY; + + current = new; + return old; +} diff --git a/plat/linux386/libsys/signal.c b/plat/linux386/libsys/signal.c new file mode 100644 index 000000000..7d3e575fa --- /dev/null +++ b/plat/linux386/libsys/signal.c @@ -0,0 +1,14 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include +#include "libsys.h" + +sighandler_t signal(int signum, sighandler_t handler) +{ + return (sighandler_t) _syscall(__NR_signal, signum, (quad) handler, 0); +} diff --git a/plat/linux386/libsys/syscalls.h b/plat/linux386/libsys/syscalls.h new file mode 100644 index 000000000..6b495c169 --- /dev/null +++ b/plat/linux386/libsys/syscalls.h @@ -0,0 +1,328 @@ +/* $Source$ +* $State$ +* $Revision$ +*/ + +#ifndef SYSCALLS_H +#define SYSCALLS_H + +/* Linux system calls. */ + +#define __NR_restart_syscall 0 +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_open 5 +#define __NR_close 6 +#define __NR_waitpid 7 +#define __NR_creat 8 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_execve 11 +#define __NR_chdir 12 +#define __NR_time 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_lchown 16 +#define __NR_break 17 +#define __NR_oldstat 18 +#define __NR_lseek 19 +#define __NR_getpid 20 +#define __NR_mount 21 +#define __NR_umount 22 +#define __NR_setuid 23 +#define __NR_getuid 24 +#define __NR_stime 25 +#define __NR_ptrace 26 +#define __NR_alarm 27 +#define __NR_oldfstat 28 +#define __NR_pause 29 +#define __NR_utime 30 +#define __NR_stty 31 +#define __NR_gtty 32 +#define __NR_access 33 +#define __NR_nice 34 +#define __NR_ftime 35 +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_rename 38 +#define __NR_mkdir 39 +#define __NR_rmdir 40 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_times 43 +#define __NR_prof 44 +#define __NR_brk 45 +#define __NR_setgid 46 +#define __NR_getgid 47 +#define __NR_signal 48 +#define __NR_geteuid 49 +#define __NR_getegid 50 +#define __NR_acct 51 +#define __NR_umount2 52 +#define __NR_lock 53 +#define __NR_ioctl 54 +#define __NR_fcntl 55 +#define __NR_mpx 56 +#define __NR_setpgid 57 +#define __NR_ulimit 58 +#define __NR_oldolduname 59 +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_ustat 62 +#define __NR_dup2 63 +#define __NR_getppid 64 +#define __NR_getpgrp 65 +#define __NR_setsid 66 +#define __NR_sigaction 67 +#define __NR_sgetmask 68 +#define __NR_ssetmask 69 +#define __NR_setreuid 70 +#define __NR_setregid 71 +#define __NR_sigsuspend 72 +#define __NR_sigpending 73 +#define __NR_sethostname 74 +#define __NR_setrlimit 75 +#define __NR_getrlimit 76 /* Back compatible 2Gig limited rlimit */ +#define __NR_getrusage 77 +#define __NR_gettimeofday 78 +#define __NR_settimeofday 79 +#define __NR_getgroups 80 +#define __NR_setgroups 81 +#define __NR_select 82 +#define __NR_symlink 83 +#define __NR_oldlstat 84 +#define __NR_readlink 85 +#define __NR_uselib 86 +#define __NR_swapon 87 +#define __NR_reboot 88 +#define __NR_readdir 89 +#define __NR_mmap 90 +#define __NR_munmap 91 +#define __NR_truncate 92 +#define __NR_ftruncate 93 +#define __NR_fchmod 94 +#define __NR_fchown 95 +#define __NR_getpriority 96 +#define __NR_setpriority 97 +#define __NR_profil 98 +#define __NR_statfs 99 +#define __NR_fstatfs 100 +#define __NR_ioperm 101 +#define __NR_socketcall 102 +#define __NR_syslog 103 +#define __NR_setitimer 104 +#define __NR_getitimer 105 +#define __NR_stat 106 +#define __NR_lstat 107 +#define __NR_fstat 108 +#define __NR_olduname 109 +#define __NR_iopl 110 +#define __NR_vhangup 111 +#define __NR_idle 112 +#define __NR_vm86old 113 +#define __NR_wait4 114 +#define __NR_swapoff 115 +#define __NR_sysinfo 116 +#define __NR_ipc 117 +#define __NR_fsync 118 +#define __NR_sigreturn 119 +#define __NR_clone 120 +#define __NR_setdomainname 121 +#define __NR_uname 122 +#define __NR_modify_ldt 123 +#define __NR_adjtimex 124 +#define __NR_mprotect 125 +#define __NR_sigprocmask 126 +#define __NR_create_module 127 +#define __NR_init_module 128 +#define __NR_delete_module 129 +#define __NR_get_kernel_syms 130 +#define __NR_quotactl 131 +#define __NR_getpgid 132 +#define __NR_fchdir 133 +#define __NR_bdflush 134 +#define __NR_sysfs 135 +#define __NR_personality 136 +#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ +#define __NR_setfsuid 138 +#define __NR_setfsgid 139 +#define __NR__llseek 140 +#define __NR_getdents 141 +#define __NR__newselect 142 +#define __NR_flock 143 +#define __NR_msync 144 +#define __NR_readv 145 +#define __NR_writev 146 +#define __NR_getsid 147 +#define __NR_fdatasync 148 +#define __NR__sysctl 149 +#define __NR_mlock 150 +#define __NR_munlock 151 +#define __NR_mlockall 152 +#define __NR_munlockall 153 +#define __NR_sched_setparam 154 +#define __NR_sched_getparam 155 +#define __NR_sched_setscheduler 156 +#define __NR_sched_getscheduler 157 +#define __NR_sched_yield 158 +#define __NR_sched_get_priority_max 159 +#define __NR_sched_get_priority_min 160 +#define __NR_sched_rr_get_interval 161 +#define __NR_nanosleep 162 +#define __NR_mremap 163 +#define __NR_setresuid 164 +#define __NR_getresuid 165 +#define __NR_vm86 166 +#define __NR_query_module 167 +#define __NR_poll 168 +#define __NR_nfsservctl 169 +#define __NR_setresgid 170 +#define __NR_getresgid 171 +#define __NR_prctl 172 +#define __NR_rt_sigreturn 173 +#define __NR_rt_sigaction 174 +#define __NR_rt_sigprocmask 175 +#define __NR_rt_sigpending 176 +#define __NR_rt_sigtimedwait 177 +#define __NR_rt_sigqueueinfo 178 +#define __NR_rt_sigsuspend 179 +#define __NR_pread64 180 +#define __NR_pwrite64 181 +#define __NR_chown 182 +#define __NR_getcwd 183 +#define __NR_capget 184 +#define __NR_capset 185 +#define __NR_sigaltstack 186 +#define __NR_sendfile 187 +#define __NR_getpmsg 188/* some people actually want streams */ +#define __NR_putpmsg 189/* some people actually want streams */ +#define __NR_vfork 190 +#define __NR_ugetrlimit 191/* SuS compliant getrlimit */ +#define __NR_mmap2 192 +#define __NR_truncate64 193 +#define __NR_ftruncate64 194 +#define __NR_stat64 195 +#define __NR_lstat64 196 +#define __NR_fstat64 197 +#define __NR_lchown32 198 +#define __NR_getuid32 199 +#define __NR_getgid32 200 +#define __NR_geteuid32 201 +#define __NR_getegid32 202 +#define __NR_setreuid32 203 +#define __NR_setregid32 204 +#define __NR_getgroups32 205 +#define __NR_setgroups32 206 +#define __NR_fchown32 207 +#define __NR_setresuid32 208 +#define __NR_getresuid32 209 +#define __NR_setresgid32 210 +#define __NR_getresgid32 211 +#define __NR_chown32 212 +#define __NR_setuid32 213 +#define __NR_setgid32 214 +#define __NR_setfsuid32 215 +#define __NR_setfsgid32 216 +#define __NR_pivot_root 217 +#define __NR_mincore 218 +#define __NR_madvise 219 +#define __NR_getdents64 220 +#define __NR_fcntl64 221 +#define __NR_gettid 224 +#define __NR_readahead 225 +#define __NR_setxattr 226 +#define __NR_lsetxattr 227 +#define __NR_fsetxattr 228 +#define __NR_getxattr 229 +#define __NR_lgetxattr 230 +#define __NR_fgetxattr 231 +#define __NR_listxattr 232 +#define __NR_llistxattr 233 +#define __NR_flistxattr 234 +#define __NR_removexattr 235 +#define __NR_lremovexattr 236 +#define __NR_fremovexattr 237 +#define __NR_tkill 238 +#define __NR_sendfile64 239 +#define __NR_futex 240 +#define __NR_sched_setaffinity 241 +#define __NR_sched_getaffinity 242 +#define __NR_set_thread_area 243 +#define __NR_get_thread_area 244 +#define __NR_io_setup 245 +#define __NR_io_destroy 246 +#define __NR_io_getevents 247 +#define __NR_io_submit 248 +#define __NR_io_cancel 249 +#define __NR_fadvise64 250 +#define __NR_exit_group 252 +#define __NR_lookup_dcookie 253 +#define __NR_epoll_create 254 +#define __NR_epoll_ctl 255 +#define __NR_epoll_wait 256 +#define __NR_remap_file_pages 257 +#define __NR_set_tid_address 258 +#define __NR_timer_create 259 +#define __NR_timer_settime (__NR_timer_create+1) +#define __NR_timer_gettime (__NR_timer_create+2) +#define __NR_timer_getoverrun (__NR_timer_create+3) +#define __NR_timer_delete (__NR_timer_create+4) +#define __NR_clock_settime (__NR_timer_create+5) +#define __NR_clock_gettime (__NR_timer_create+6) +#define __NR_clock_getres (__NR_timer_create+7) +#define __NR_clock_nanosleep (__NR_timer_create+8) +#define __NR_statfs64 268 +#define __NR_fstatfs64 269 +#define __NR_tgkill 270 +#define __NR_utimes 271 +#define __NR_fadvise64_64 272 +#define __NR_vserver 273 +#define __NR_mbind 274 +#define __NR_get_mempolicy 275 +#define __NR_set_mempolicy 276 +#define __NR_mq_open 277 +#define __NR_mq_unlink (__NR_mq_open+1) +#define __NR_mq_timedsend (__NR_mq_open+2) +#define __NR_mq_timedreceive (__NR_mq_open+3) +#define __NR_mq_notify (__NR_mq_open+4) +#define __NR_mq_getsetattr (__NR_mq_open+5) +#define __NR_kexec_load 283 +#define __NR_waitid 284 +#define __NR_add_key 286 +#define __NR_request_key 287 +#define __NR_keyctl 288 +#define __NR_ioprio_set 289 +#define __NR_ioprio_get 290 +#define __NR_inotify_init 291 +#define __NR_inotify_add_watch 292 +#define __NR_inotify_rm_watch 293 +#define __NR_migrate_pages 294 +#define __NR_openat 295 +#define __NR_mkdirat 296 +#define __NR_mknodat 297 +#define __NR_fchownat 298 +#define __NR_futimesat 299 +#define __NR_fstatat64 300 +#define __NR_unlinkat 301 +#define __NR_renameat 302 +#define __NR_linkat 303 +#define __NR_symlinkat 304 +#define __NR_readlinkat 305 +#define __NR_fchmodat 306 +#define __NR_faccessat 307 +#define __NR_pselect6 308 +#define __NR_ppoll 309 +#define __NR_unshare 310 +#define __NR_set_robust_list 311 +#define __NR_get_robust_list 312 +#define __NR_splice 313 +#define __NR_sync_file_range 314 +#define __NR_tee 315 +#define __NR_vmsplice 316 + +#define concat(x, y) x##y +#define MAPPED_SYSCALL(p, n) .define concat(p,n); concat(p,n): xor eax, eax; movb al, concat(__NR_,n); jmp __mapped_syscall + +#endif diff --git a/plat/linux386/libsys/write.c b/plat/linux386/libsys/write.c new file mode 100644 index 000000000..a4543c8d8 --- /dev/null +++ b/plat/linux386/libsys/write.c @@ -0,0 +1,14 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include +#include "libsys.h" + +int write(int fd, void* buffer, size_t count) +{ + return _syscall(__NR_write, fd, (quad) buffer, count); +} diff --git a/plat/linux386/pmfile b/plat/linux386/pmfile new file mode 100644 index 000000000..24adc42ef --- /dev/null +++ b/plat/linux386/pmfile @@ -0,0 +1,46 @@ +-- $Source$ +-- $State$ +-- $Revision$ + +local d = ROOTDIR.."plat/linux386/" + +include (d.."libsys/pmfile") + +local bootsector = ackfile { + file (d.."boot.s"), + install = pm.install("%BINDIR%lib/linux386/boot.o"), +} + +local descr = group { + install = pm.install(d.."descr", "%BINDIR%%PLATIND%/%PLATFORM%/descr") +} + +local headers = group { + install = { + pm.install(d.."include/ack/config.h", "%BINDIR%%PLATIND%/%PLATFORM%/include/ack/config.h"), + pm.install(d.."include/unistd.h", "%BINDIR%%PLATIND%/%PLATFORM%/include/unistd.h"), + } +} + +platform_linux386 = group { + ARCH = "i386", + PLATFORM = "linux386", + OPTIMISATION = "-O", + + -- Ensure the descr and headers are installed first because we'll need it + -- to build the libraries. + + descr, + headers, + + -- Build the back-end support. + + mach_i386, + support_i386, + lang_runtimes, + + -- Build the PC standalone syscall library. + + libsys_linux386, + bootsector, +}