From 2a6690e9fd53a02613796764248006e06ac482d6 Mon Sep 17 00:00:00 2001 From: Miguel Date: Sun, 14 Oct 2018 22:36:16 +0200 Subject: ported vim et al --- interface/Makefile.am | 25 +++ interface/configure.in | 7 + interface/crt0.s | 3 + interface/fs.h | 11 ++ interface/syscalls.c | 421 +++++++++++++++++++++++++++++++++++++++++++++---- interface/syscalls.h | 31 +++- 6 files changed, 463 insertions(+), 35 deletions(-) create mode 100644 interface/Makefile.am create mode 100644 interface/configure.in (limited to 'interface') diff --git a/interface/Makefile.am b/interface/Makefile.am new file mode 100644 index 0000000..2003073 --- /dev/null +++ b/interface/Makefile.am @@ -0,0 +1,25 @@ +AUTOMAKE_OPTIONS = cygnus +INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) +AM_CCASFLAGS = $(INCLUDES) + +noinst_LIBRARIES = lib.a + +if MAY_SUPPLY_SYSCALLS +extra_objs = syscalls.o syscall.o # add more object files here if you split up +else # syscalls.c into multiple files in the previous step +extra_objs = +endif + +lib_a_SOURCES = +lib_a_LIBADD = $(extra_objs) +EXTRA_lib_a_SOURCES = syscalls.c syscall.s crt0.s # add more source files here if you split up +lib_a_DEPENDENCIES = $(extra_objs) # syscalls.c into multiple files +lib_a_CCASFLAGS = $(AM_CCASFLAGS) +lib_a_CFLAGS = $(AM_CFLAGS) + +if MAY_SUPPLY_SYSCALLS +all: crt0.o +endif + +ACLOCAL_AMFLAGS = -I ../../.. +CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host diff --git a/interface/configure.in b/interface/configure.in new file mode 100644 index 0000000..c25c89a --- /dev/null +++ b/interface/configure.in @@ -0,0 +1,7 @@ +AC_PREREQ(2.59) +AC_INIT([newlib], [NEWLIB_VERSION]) +AC_CONFIG_SRCDIR([crt0.s]) +AC_CONFIG_AUX_DIR(../../../..) +NEWLIB_CONFIGURE(../../..) +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/interface/crt0.s b/interface/crt0.s index 88e316e..935e5bd 100644 --- a/interface/crt0.s +++ b/interface/crt0.s @@ -89,6 +89,9 @@ pop %eax and $-16,%esp sub $4,%esp +push stdout +call fflush + # push exit code and pass to _exit syscall push %eax call exit diff --git a/interface/fs.h b/interface/fs.h index 5930ffe..a6168ae 100644 --- a/interface/fs.h +++ b/interface/fs.h @@ -13,6 +13,7 @@ enum FS_FILE_TYPE{ FS_FILE_TYPE_FILE = 2 }; +/* typedef struct fs_dirent_struct { uint32_t mount; //mount identifier @@ -21,5 +22,15 @@ typedef struct fs_dirent_struct char name[255]; }fs_dirent; +*/ + +typedef struct fs_dirent_struct +{ + uint32_t inode; + uint32_t offset; + uint16_t length; + uint8_t type; + char name[256]; +}fs_dirent; #endif diff --git a/interface/syscalls.c b/interface/syscalls.c index 4acbba5..7d12002 100644 --- a/interface/syscalls.c +++ b/interface/syscalls.c @@ -1,68 +1,215 @@ #include +#include +#include #include #include #include +#include #include "fs.h" #include "syscalls.h" -extern char **environ; -// TODO: errno! +// everybody is root +uid_t getuid(void) +{ + return 0; +} -int _readdir(const char *name,fs_dirent *dirs,int max) +// everybody is root +uid_t getgid(void) { - return syscall(SYSCALL_READDIR,name,dirs,max); + return 0; } -int _poll(int file) +// no sync needed for our ram-image so far (DMA?) +void sync(void) { - return syscall(SYSCALL_POLL,file,0,0); } -void _exit(int ret) +// C NEWLIB // + +// first of all we have a few posix syscalls required by newlib +// (we use version newlib-3.0.0.20180802) +// https://sourceware.org/newlib/libc.html#Syscalls +// just check liunx man-pages, how they SHOULD work. + +// holds environment variables +extern char **environ; + +// terminate caller +void _exit(int status) { - return syscall(SYSCALL_EXIT,ret,environ,0); + return syscall(SYSCALL_EXIT,status,0,0); } +// close file int _close(int file) { return syscall(SYSCALL_CLOSE,file,0,0); } +int close(int file) +{ + return syscall(SYSCALL_CLOSE,file,0,0); +} + +// execute programm +int _execve(const char *filename, char *const argv[], char *const envp[]) +{ + return syscall(SYSCALL_EXECVE,filename,argv,envp); +} +int execve(const char *filename, char *const argv[], char *const envp[]) +{ + return syscall(SYSCALL_EXECVE,filename,argv,envp); +} + +// create a child process +pid_t _fork(void) +{ + return syscall(SYSCALL_FORK,0,0,0); +} +pid_t fork(void) +{ + return syscall(SYSCALL_FORK,0,0,0); +} + +int _fstat(int file, struct stat *st) +{ + return syscall(SYSCALL_FSTAT,file,st,0); +} +int fstat(int file, struct stat *st) +{ + return syscall(SYSCALL_FSTAT,file,st,0); +} + +int _getpid(void) +{ + return syscall(SYSCALL_GETPID,0,0,0); +} +int getpid(void) +{ + return syscall(SYSCALL_GETPID,0,0,0); +} int _isatty(int file) { return syscall(SYSCALL_ISATTY,file,0,0); } +int isatty(int file) +{ + return syscall(SYSCALL_ISATTY,file,0,0); +} + +int _kill(int pid, int sig) +{ + return syscall(SYSCALL_KILL,pid,sig,0); +} +int kill(int pid, int sig) +{ + return syscall(SYSCALL_KILL,pid,sig,0); +} + +int _link(char *old, char *ne) +{ + return syscall(SYSCALL_LINK,old,ne,0); +} +int link(char *old, char *ne) +{ + return syscall(SYSCALL_LINK,old,ne,0); +} int _lseek(int file, int ptr, int dir) { return syscall(SYSCALL_LSEEK,file,ptr,dir); } +int lseek(int file, int ptr, int dir) +{ + return syscall(SYSCALL_LSEEK,file,ptr,dir); +} + +int _open(const char *name, int flags, int mode) +{ + return syscall(SYSCALL_OPEN,name,flags,mode); +} +int open(const char *name, int flags, int mode) +{ + return syscall(SYSCALL_OPEN,name,flags,mode); +} int _read(int file, char *ptr, int len) { return syscall(SYSCALL_READ,file,ptr,len); } +int read(int file, char *ptr, int len) +{ + return syscall(SYSCALL_READ,file,ptr,len); +} -int _open(const char *name, int flags, int mode) +uint32_t _sbrk(int incr) { - return syscall(SYSCALL_OPEN,name,flags,mode); + return syscall(SYSCALL_SBRK,incr,0,0); +} +uint32_t sbrk(int incr) +{ + return syscall(SYSCALL_SBRK,incr,0,0); +} + +int _stat(const char *file, struct stat *st) +{ + return syscall(SYSCALL_STAT,file,st,0); +} +int stat(const char *file, struct stat *st) +{ + return syscall(SYSCALL_STAT,file,st,0); +} + +int _times(struct tms *buf) +{ + return syscall(SYSCALL_TIMES,buf,0,0); +} +int times(struct tms *buf) +{ + return syscall(SYSCALL_TIMES,buf,0,0); +} + +int _unlink(char *name) +{ + return syscall(SYSCALL_UNLINK,name,0,0); +} +int unlink(char *name) +{ + return syscall(SYSCALL_UNLINK,name,0,0); +} + +int _wait(int *status) +{ + return syscall(SYSCALL_WAIT,status,0,0); +} +int wait(int *status) +{ + return syscall(SYSCALL_WAIT,status,0,0); } int _write(int file, char *ptr, int len) { return syscall(SYSCALL_WRITE,file,ptr,len); } +int write(int file, char *ptr, int len) +{ + return syscall(SYSCALL_WRITE,file,ptr,len); +} + +////////////////////////////////////////////////////////////////////// + -int _execve(char *name, char **argv, char **env) +int _readdir(const char *name,fs_dirent *dirs,int max) { - return syscall(SYSCALL_EXECVE,name,argv,env); + return syscall(SYSCALL_READDIR,name,dirs,max); } -uint32_t _sbrk(int incr) +int _poll(int file) { - return syscall(SYSCALL_SBRK,incr,0,0); + return syscall(SYSCALL_POLL,file,0,0); } int _gettimeofday(struct timeval *tv, void *tz) @@ -70,57 +217,263 @@ int _gettimeofday(struct timeval *tv, void *tz) return syscall(SYSCALL_GETTIMEOFDAY,tv,tz,0); } -int _fork(void) +int _lstat(const char *file, struct stat *st) { - return syscall(SYSCALL_FORK,0,0,0); + return syscall(SYSCALL_LSTAT,file,st,0); } +// EXTRA STUFF + + static struct termios tty1; // only one global terminal managed here... more might/should follow + //TODO : implement this properly + + int tcgetattr(int fd, struct termios *termios_p) + { + syscall(SYSCALL_UNIMPLEMENTED,"tcgetattr",0,0); + *termios_p=tty1; + return 0; + } + + int tcsetattr(int fd, int optional_actions, const struct termios *termios_p) + { + syscall(SYSCALL_UNIMPLEMENTED,"tcsetattr",0,0); + tty1=*termios_p; + return 0; + } + +/* + + int tcsendbreak(int fd, int duration); + + int tcdrain(int fd); + + + int tcflow(int fd, int action); +*/ + +// void cfmakeraw(struct termios *termios_p); + + /* + speed_t cfgetispeed(const struct termios *termios_p); + + */ + + speed_t cfgetospeed(const struct termios *termios_p) + { + syscall(SYSCALL_UNIMPLEMENTED,"cfgetospeed",0,0); + return B230400; + } + + long fpathconf(int fd, int name) + { + return syscall(SYSCALL_UNIMPLEMENTED,"fpathconf",0,0); + } + + int tcflush(int fd, int queue_selector) + { + return syscall(SYSCALL_UNIMPLEMENTED,"tcflush",0,0); + } + + /* + int cfsetispeed(struct termios *termios_p, speed_t speed); + + int cfsetospeed(struct termios *termios_p, speed_t speed); + + int cfsetspeed(struct termios *termios_p, speed_t speed); + */ + +////////////////////////////////////////// move along /// + + int access(const char *pathname, int mode) + { + return syscall(SYSCALL_UNIMPLEMENTED,"access",0,0); + } + + #include + #include + + mode_t umask(mode_t mask) + { + return syscall(SYSCALL_UNIMPLEMENTED,"umask",0,0); + } + + int mkdir(const char *pathname, mode_t mode) + { + return syscall(SYSCALL_UNIMPLEMENTED,"mkdir",0,0); + } + + int chdir(const char *path) + { + return syscall(SYSCALL_UNIMPLEMENTED,"chdir",0,0); + } + + char* getwd(char *buf) + { + return syscall(SYSCALL_UNIMPLEMENTED,"getwd",0,0); + } + + char *ttyname(int fd) + { + return syscall(SYSCALL_UNIMPLEMENTED,"ttyname",0,0); + } + +// + + struct dirent *readdir(DIR *dirp) + { + return syscall(SYSCALL_UNIMPLEMENTED,"readdir",0,0); + } + + DIR *opendir(const char *name) + { + return syscall(SYSCALL_UNIMPLEMENTED,"opendir",0,0); + } + + int closedir(DIR *dirp) + { + return syscall(SYSCALL_UNIMPLEMENTED,"closedir",0,0); + } + + + unsigned int sleep(unsigned int seconds) + { + return syscall(SYSCALL_UNIMPLEMENTED,"sleep",0,0); + } + + char *getlogin(void) + { + return syscall(SYSCALL_UNIMPLEMENTED,"getlogin",0,0); + } + + + /** + * Monitor multiple descriptors + * ============================ + * + * nfds is the MAX file descriptor number +1. + * + * It is possible to provide 3 different sets of filedescriptors + * (they can be NULL as well) + * + * - readfds - reading + * - writefds - writing + * - exceptfds - exceptions (all cleared unless exception occurs) + * + * The call returns the total number of descriptors contained in all + * sets after returning. + * + * This call will block until time (timeout) runs out + * OR a file descriptor becomes ready. + */ + + int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) + { + // pack all our sets togehter + fd_set *fd_sets[3]; + + fd_sets[0]=readfds; + fd_sets[1]=writefds; + fd_sets[2]=exceptfds; + + return syscall(SYSCALL_SELECT,nfds,timeout,fd_sets); + } + + int pclose(FILE *stream) + { + return syscall(SYSCALL_UNIMPLEMENTED,"pclose",0,0); + } + + FILE *popen(const char *command, const char *type) + { + return syscall(SYSCALL_UNIMPLEMENTED,"popen",0,0); + } + + // call dup2 in dup emulation mode + int dup(int oldfd) + { + return _dup2(oldfd,0xffffffff); // dup emulation mode + } + + int _clone(void) { return syscall(SYSCALL_CLONE,0,0,0); } +int _pipe(uint32_t fds[2]) +{ + return syscall(SYSCALL_PIPE,fds,0,0); +} +int pipe(uint32_t fds[2]) +{ + return syscall(SYSCALL_PIPE,fds,0,0); +} +int _dup2(uint32_t oldfd,uint32_t newfd) +{ + return syscall(SYSCALL_DUP2,oldfd,newfd,0); +} +int dup2(uint32_t oldfd,uint32_t newfd) +{ + return syscall(SYSCALL_DUP2,oldfd,newfd,0); +} +int _gui_rect() +{ + return syscall(SYSCALL_GUI_RECT,0,0,0); +} +int _gui_win() +{ + return syscall(SYSCALL_GUI_WIN,0,0,0); +} -int _getpid(void) +int gethostname(char *name, size_t len) { - return syscall(SYSCALL_GETPID,0,0,0); + strcpy(name,"foolcomp"); + return 0; //success } -int _kill(int pid, int sig) +ssize_t readlink(const char *pathname, char *buf, size_t bufsiz) { - return syscall(SYSCALL_KILL,pid,sig,0); + syscall(SYSCALL_UNIMPLEMENTED,"readlink",0,0); + return 0; } -int _link(char *old, char *ne) +int rmdir(const char *pathname) { - return syscall(SYSCALL_LINK,old,ne,0); + syscall(SYSCALL_UNIMPLEMENTED,"rmdir",0,0); + return 0; } -int _unlink(char *name) +int fcntl(int fd, int cmd, ... /* arg */ ) { - return syscall(SYSCALL_UNLINK,name,0,0); + syscall(SYSCALL_UNIMPLEMENTED,"fcntl",0,0); + return 0; } -int _times(struct tms *buf) +pid_t waitpid(pid_t pid, int *wstatus, int options) { - return syscall(SYSCALL_TIMES,buf,0,0); + syscall(SYSCALL_UNIMPLEMENTED,"waitpid",0,0); + return 0; } -int _wait(uint32_t pid) +int execl(const char *path, const char *arg, ...) { - return syscall(SYSCALL_WAIT,pid,0,0); + syscall(SYSCALL_UNIMPLEMENTED,"execl",0,0); + return 0; } -int _stat(const char *file, struct stat *st) +int execvp(const char *file, char *const argv[]) { - return syscall(SYSCALL_STAT,file,st,0); + syscall(SYSCALL_UNIMPLEMENTED,"execvp",0,0); + return 0; } -int _lstat(const char *file, struct stat *st) +long sysconf(int name) { - return syscall(SYSCALL_LSTAT,file,st,0); + syscall(SYSCALL_UNIMPLEMENTED,"sysconf",0,0); + return 0; } -int _fstat(int file, struct stat *st) +int chmod(const char *pathname, mode_t mode) { - return syscall(SYSCALL_FSTAT,file,st,0); + syscall(SYSCALL_UNIMPLEMENTED,"chmod",0,0); + return 0; } diff --git a/interface/syscalls.h b/interface/syscalls.h index 40a8c17..e758fd9 100644 --- a/interface/syscalls.h +++ b/interface/syscalls.h @@ -1 +1,30 @@ -/* empty */ +#define SYSCALL_EXIT 60 +#define SYSCALL_CLOSE 66 +#define SYSCALL_EXECVE 64 +#define SYSCALL_FORK 72 +#define SYSCALL_GETPID 78 +#define SYSCALL_ISATTY 68 +#define SYSCALL_LINK 82 +#define SYSCALL_LSEEK 69 +#define SYSCALL_OPEN 65 +#define SYSCALL_READ 62 +#define SYSCALL_SBRK 70 +#define SYSCALL_STAT 74 +#define SYSCALL_FSTAT 67 +#define SYSCALL_LSTAT 79 +#define SYSCALL_TIMES 75 +#define SYSCALL_UNLINK 76 +#define SYSCALL_WAIT 77 +#define SYSCALL_WRITE 61 +#define SYSCALL_GETTIMEOFDAY 71 +#define SYSCALL_READDIR 63 +#define SYSCALL_KILL 73 +#define SYSCALL_POLL 80 +#define SYSCALL_CLONE 83 +#define SYSCALL_PIPE 84 +#define SYSCALL_DUP2 86 +#define SYSCALL_GUI_RECT 87 +#define SYSCALL_GUI_WIN 88 +#define SYSCALL_SELECT 89 + +#define SYSCALL_UNIMPLEMENTED 255 -- cgit v1.2.3