184 lines
3.9 KiB
C
184 lines
3.9 KiB
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.
|
||
|
*/
|
||
|
|
||
|
|
||
|
inline
|
||
|
int _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);
|
||
|
}
|