⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 crt.c

📁 Simple Operating Systems (简称SOS)是一个可以运行在X86平台上(包括QEMU
💻 C
字号:
/* Copyright (C) 2005 David Decotigny   Copyright (C) 2003 Thomas Petazzoni   This program is free software; you can redistribute it and/or   modify it under the terms of the GNU General Public License   as published by the Free Software Foundation; either version 2   of the License, or (at your option) any later version.      This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.      You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,   USA. *//** * @file crt.c * * The C RunTime environment for the basic support of SOS C user * programs */#include <hwcore/swintr.h>#include <string.h>#include "crt.h"/** * Starter function ! */void _start() __attribute__((noreturn));void _start(){  /* This starter function expects a main() function somewhere */  extern int main();  /* Reset the bss section */  extern char _bbss, _ebss;  memset(& _bbss, 0x0, (& _ebss) - (& _bbss));  _sos_exit(main());}/* * By convention, the USER SOS programs always pass 4 arguments to the * kernel syscall handler: in eax/../edx. For less arguments, the * unused registers are filled with 0s. For more arguments, the 4th * syscall parameter gives the address of the array containing the * remaining arguments. In any case, eax corresponds to the syscall * IDentifier. */inlineint _sos_syscall3(int id,		  unsigned int arg1,		  unsigned int arg2,		  unsigned int arg3){  int ret;  asm volatile("movl %1,%%eax \n"	       "movl %2,%%ebx \n"	       "movl %3,%%ecx \n"	       "movl %4,%%edx \n"	       "int  %5\n"	       "movl %%eax, %0"	       :"=g"(ret)	       :"g"(id),"g"(arg1),"g"(arg2),"g"(arg3)	        ,"i"(SOS_SWINTR_SOS_SYSCALL)	       :"eax","ebx","ecx","edx");  return ret;}int _sos_syscall0(int id){  return _sos_syscall3(id, 0, 0, 0);}int _sos_syscall1(int id,	     unsigned int arg1){  return _sos_syscall3(id, arg1, 0, 0);}int _sos_syscall2(int id,		  unsigned int arg1,		  unsigned int arg2){  return _sos_syscall3(id, arg1, arg2, 0);}int _sos_syscall4(int id,		  unsigned int arg1,		  unsigned int arg2,		  unsigned int arg3,		  unsigned int arg4){  unsigned int args[] = { arg3, arg4 };  return _sos_syscall3(id, arg1, arg2, (unsigned)args);}int _sos_syscall5(int id,		  unsigned int arg1,		  unsigned int arg2,		  unsigned int arg3,		  unsigned int arg4,		  unsigned int arg5){  unsigned int args[] = { arg3, arg4, arg5 };  return _sos_syscall3(id, arg1, arg2, (unsigned)args);}int _sos_syscall6(int id,		  unsigned int arg1,		  unsigned int arg2,		  unsigned int arg3,		  unsigned int arg4,		  unsigned int arg5,		  unsigned int arg6){  unsigned int args[] = { arg3, arg4, arg5, arg6 };  return _sos_syscall3(id, arg1, arg2, (unsigned)args);}int _sos_syscall7(int id,		  unsigned int arg1,		  unsigned int arg2,		  unsigned int arg3,		  unsigned int arg4,		  unsigned int arg5,		  unsigned int arg6,		  unsigned int arg7){  unsigned int args[] = { arg3, arg4, arg5, arg6, arg7 };  return _sos_syscall3(id, arg1, arg2, (unsigned)args);}int _sos_syscall8(int id,		  unsigned int arg1,		  unsigned int arg2,		  unsigned int arg3,		  unsigned int arg4,		  unsigned int arg5,		  unsigned int arg6,		  unsigned int arg7,		  unsigned int arg8){  unsigned int args[] = { arg3, arg4, arg5, arg6, arg7, arg8 };  return _sos_syscall3(id, arg1, arg2, (unsigned)args);}void _sos_exit(int status){  _sos_syscall1(SOS_SYSCALL_ID_EXIT, (unsigned)status);    /* Never reached ! */  for ( ; ; )    ;}int _sos_bochs_write(const char * str, unsigned length){  return _sos_syscall2(SOS_SYSCALL_ID_BOCHS_WRITE,		       (unsigned)str,		       length);}int _sos_fork(){  return _sos_syscall0(SOS_SYSCALL_ID_FORK);}int _sos_exec(const char * prog){  return _sos_syscall2(SOS_SYSCALL_ID_EXEC, (unsigned int)prog,		       (unsigned int)strlen(prog));}int _sos_fakemmap(void ** ptr_hint_addr, size_t len, int prot, int flags,		  const char *resource_path, loff_t offset){  return _sos_syscall7(SOS_SYSCALL_ID_FAKEMMAP,		       (unsigned int)ptr_hint_addr, len, prot, flags,		       (unsigned int)resource_path,		       /* offs64_hi */(offset >> 32),		       /* offs64_lo */(offset & 0xffffffff));}int _sos_munmap(void * start, size_t length){  return _sos_syscall2(SOS_SYSCALL_ID_MUNMAP,		       (unsigned int)start,		       length);}int _sos_mprotect(const void *addr, size_t len, int prot){  return _sos_syscall3(SOS_SYSCALL_ID_MPROTECT,		       (unsigned int)addr,		       len,		       (unsigned int)prot);}int _sos_mresize(void * old_addr, size_t old_len,		 void * *new_addr, size_t new_len,		 unsigned long flags){  return _sos_syscall5(SOS_SYSCALL_ID_MRESIZE,		       (unsigned int)old_addr,		       old_len,		       (unsigned int)new_addr,		       new_len,		       flags);}/** * Helper function that represents the start routine of a new user * thread created from user space (syscall new_thread). It takes 2 * arguments that are passsed in the eax/ebx registers (@see * cpu_ustate_init() in hwcore/cpu_context.c): the start function of * the new thread (eax), the argument passed to it (ebx). */static void thread_routine(){  /* NOTE: variables as named registers is a gcc extension */  register unsigned long int reg_arg1 asm("%eax");  register unsigned long int reg_arg2 asm("%ebx");  sos_thread_func_t * func = (sos_thread_func_t*)reg_arg1;  unsigned long int arg = reg_arg2;  func(arg);  _sos_exit(0);}int _sos_new_thread(sos_thread_func_t *func,		    void* arg,		    size_t stack_size){  return _sos_syscall4(SOS_SYSCALL_ID_NEW_THREAD,		       (unsigned)thread_routine,		       (unsigned)func, (unsigned)arg,		       stack_size);}int _sos_nanosleep(unsigned long int sec,		   unsigned long int nanosec){  return _sos_syscall2(SOS_SYSCALL_ID_NANOSLEEP,		       sec, nanosec);}void * _sos_brk(void * new_top_address){  return (void*)_sos_syscall1(SOS_SYSCALL_ID_BRK,			      (unsigned)new_top_address);}int _sos_mount(const char *source, const char *target,	       const char *filesystemtype, unsigned long mountflags,	       const char *args){  if (!target || !filesystemtype)    return -1;  return _sos_syscall7(SOS_SYSCALL_ID_MOUNT,		       (unsigned int)source, source?strlen(source):0,		       (unsigned int)target, strlen(target),		       (unsigned int)filesystemtype,		       mountflags,		       (unsigned int)args);}int _sos_umount(const char *target){  if (!target)    return -1;  return _sos_syscall2(SOS_SYSCALL_ID_UMOUNT,		       (unsigned int)target,		       strlen(target));}void _sos_sync(void){  _sos_syscall0(SOS_SYSCALL_ID_SYNC);}int _sos_statvfs(const char *path, struct statvfs *buf){  if (! path)    return -1;      return _sos_syscall3(SOS_SYSCALL_ID_VFSTAT64,		       (unsigned)path,		       strlen(path),		       (unsigned)buf);}int _sos_open(const char * pathname, int flags, int mode){  if (! pathname)    return -1;      return _sos_syscall4(SOS_SYSCALL_ID_OPEN,		       (unsigned)pathname,		       strlen(pathname),		       flags,		       mode);}int _sos_close(int fd){  return _sos_syscall1(SOS_SYSCALL_ID_CLOSE, fd);}int _sos_read(int fd, char * buf, size_t * len){  return _sos_syscall3(SOS_SYSCALL_ID_READ, fd,		       (unsigned int) buf,		       (unsigned int) len);}int _sos_write(int fd, const char * buf, size_t * len){  return _sos_syscall3(SOS_SYSCALL_ID_WRITE, fd,		       (unsigned int) buf,		       (unsigned int) len);}int _sos_seek64(int fd, loff_t * offset, int whence){  return _sos_syscall3(SOS_SYSCALL_ID_SEEK64, fd,		       (unsigned int)offset,		       (unsigned int)whence);}int _sos_fmmap(void ** ptr_hint_addr, size_t len, int prot, int flags,	       int fd, loff_t offset){  return _sos_syscall7(SOS_SYSCALL_ID_FSMMAP,		       (unsigned int)ptr_hint_addr, len, prot, flags,		       (unsigned int)fd,		       /* offs64_hi */(offset >> 32),		       /* offs64_lo */(offset & 0xffffffff));}int _sos_ftruncate64(int fd, loff_t length){  return _sos_syscall2(SOS_SYSCALL_ID_FTRUNCATE64, fd,		       (unsigned int)length);  }int _sos_fcntl(int fd, int cmd, int arg){  return _sos_syscall3(SOS_SYSCALL_ID_FCNTL, fd,		       (unsigned int)cmd,		       (unsigned int)arg);}int _sos_creat(const char *pathname, int mode){  if (! pathname)    return -1;  return _sos_syscall3(SOS_SYSCALL_ID_CREAT,		       (unsigned int)pathname,		       strlen(pathname),		       mode);}int _sos_link (const char *oldpath, const char *newpath){  if (!oldpath || !newpath)    return -1;  return _sos_syscall4(SOS_SYSCALL_ID_LINK,		       (unsigned int)oldpath,		       strlen(oldpath),		       (unsigned int)newpath,		       strlen(newpath));}int _sos_unlink(const char *pathname){  if (! pathname)    return -1;  return _sos_syscall2(SOS_SYSCALL_ID_UNLINK,		       (unsigned int)pathname,		       strlen(pathname));}int _sos_rename (const char *oldpath, const char *newpath){  if (!oldpath || !newpath)    return -1;  return _sos_syscall4(SOS_SYSCALL_ID_RENAME,		       (unsigned int)oldpath,		       strlen(oldpath),		       (unsigned int)newpath,		       strlen(newpath));}int _sos_symlink(const char *target, const char *path){  if (!path || !target)    return -1;  return _sos_syscall4(SOS_SYSCALL_ID_SYMLINK,		       (unsigned int)path,		       strlen(path),		       (unsigned int)target,		       strlen(target));}struct dirent; /* Forward declaration */int _sos_readdir(int fd, struct dirent * dirent){  return _sos_syscall2(SOS_SYSCALL_ID_READDIR,		       fd,		       (unsigned int)dirent);}int _sos_mkdir(const char *pathname, mode_t mode){  if (!pathname)    return -1;  return _sos_syscall3(SOS_SYSCALL_ID_MKDIR,		       (unsigned int)pathname,		       strlen(pathname),		       mode);}int _sos_rmdir(const char *pathname){  if (!pathname)    return -1;  return _sos_syscall2(SOS_SYSCALL_ID_RMDIR,		       (unsigned int)pathname,		       strlen(pathname));}int _sos_chmod(const char *pathname, mode_t mode){  if (!pathname)    return -1;  return _sos_syscall3(SOS_SYSCALL_ID_CHMOD,		       (unsigned int)pathname,		       strlen(pathname),		       mode);}int _sos_stat(const char *pathname, int nofollow, struct stat * st){  if (!pathname || !st)    return -1;  return _sos_syscall4(SOS_SYSCALL_ID_STAT64,		       (unsigned int)pathname,		       strlen(pathname),		       nofollow,		       (unsigned int)st);}int _sos_chroot(const char *dirname){  if (!dirname)    return -1;  return _sos_syscall2(SOS_SYSCALL_ID_CHROOT,		       (unsigned int)dirname,		       strlen(dirname));}int _sos_chdir(const char *dirname){  if (!dirname)    return -1;  return _sos_syscall2(SOS_SYSCALL_ID_CHDIR,		       (unsigned int)dirname,		       strlen(dirname));}int _sos_fchdir(int fd){  return _sos_syscall1(SOS_SYSCALL_ID_FCHDIR,		       (unsigned int)fd);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -