SimpleOS

LXR

Navigation



Site hébergé par : enix

The LXR Cross Referencer for SOS

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Article:1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 6.5 ] [ 7 ] [ 7.5 ] [ 8 ] [ 9 ] [ 9.5 ]

001 /* Copyright (C) 2005 David Decotigny
002    Copyright (C) 2003 Thomas Petazzoni
003 
004    This program is free software; you can redistribute it and/or
005    modify it under the terms of the GNU General Public License
006    as published by the Free Software Foundation; either version 2
007    of the License, or (at your option) any later version.
008    
009    This program is distributed in the hope that it will be useful,
010    but WITHOUT ANY WARRANTY; without even the implied warranty of
011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012    GNU General Public License for more details.
013    
014    You should have received a copy of the GNU General Public License
015    along with this program; if not, write to the Free Software
016    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
017    USA. 
018 */
019 
020 
021 /**
022  * @file crt.c
023  *
024  * The C RunTime environment for the basic support of SOS C user
025  * programs
026  */
027 
028 #include <hwcore/swintr.h>
029 #include <string.h>
030 #include "crt.h"
031 
032 /**
033  * Starter function !
034  */
035 void _start(void) __attribute__((noreturn));
036 void _start(void)
037 {
038   /* This starter function expects a main() function somewhere */
039   extern int main(void);
040 
041   /* Reset the bss section */
042   extern char _bbss, _ebss;
043   memset(& _bbss, 0x0, (& _ebss) - (& _bbss));
044 
045   _sos_exit(main());
046 }
047 
048 
049 /*
050  * By convention, the USER SOS programs always pass 4 arguments to the
051  * kernel syscall handler: in eax/../edx. For less arguments, the
052  * unused registers are filled with 0s. For more arguments, the 4th
053  * syscall parameter gives the address of the array containing the
054  * remaining arguments. In any case, eax corresponds to the syscall
055  * IDentifier.
056  */
057 
058 
059 inline
060 int _sos_syscall3(int id,
061                   unsigned int arg1,
062                   unsigned int arg2,
063                   unsigned int arg3)
064 {
065   int ret;
066   
067   asm volatile("movl %1,%%eax \n"
068                "movl %2,%%ebx \n"
069                "movl %3,%%ecx \n"
070                "movl %4,%%edx \n"
071                "int  %5\n"
072                "movl %%eax, %0"
073                :"=g"(ret)
074                :"g"(id),"g"(arg1),"g"(arg2),"g"(arg3)
075                 ,"i"(SOS_SWINTR_SOS_SYSCALL)
076                :"eax","ebx","ecx","edx","memory");
077 
078   return ret;
079 }
080 
081 
082 int _sos_syscall0(int id)
083 {
084   return _sos_syscall3(id, 0, 0, 0);
085 }
086 
087 
088 int _sos_syscall1(int id,
089              unsigned int arg1)
090 {
091   return _sos_syscall3(id, arg1, 0, 0);
092 }
093 
094 
095 int _sos_syscall2(int id,
096                   unsigned int arg1,
097                   unsigned int arg2)
098 {
099   return _sos_syscall3(id, arg1, arg2, 0);
100 }
101 
102 
103 int _sos_syscall4(int id,
104                   unsigned int arg1,
105                   unsigned int arg2,
106                   unsigned int arg3,
107                   unsigned int arg4)
108 {
109   unsigned int args[] = { arg3, arg4 };
110   return _sos_syscall3(id, arg1, arg2, (unsigned)args);
111 }
112 
113 
114 int _sos_syscall5(int id,
115                   unsigned int arg1,
116                   unsigned int arg2,
117                   unsigned int arg3,
118                   unsigned int arg4,
119                   unsigned int arg5)
120 {
121   unsigned int args[] = { arg3, arg4, arg5 };
122   return _sos_syscall3(id, arg1, arg2, (unsigned)args);
123 }
124 
125 
126 int _sos_syscall6(int id,
127                   unsigned int arg1,
128                   unsigned int arg2,
129                   unsigned int arg3,
130                   unsigned int arg4,
131                   unsigned int arg5,
132                   unsigned int arg6)
133 {
134   unsigned int args[] = { arg3, arg4, arg5, arg6 };
135   return _sos_syscall3(id, arg1, arg2, (unsigned)args);
136 }
137 
138 
139 int _sos_syscall7(int id,
140                   unsigned int arg1,
141                   unsigned int arg2,
142                   unsigned int arg3,
143                   unsigned int arg4,
144                   unsigned int arg5,
145                   unsigned int arg6,
146                   unsigned int arg7)
147 {
148   unsigned int args[] = { arg3, arg4, arg5, arg6, arg7 };
149   return _sos_syscall3(id, arg1, arg2, (unsigned)args);
150 }
151 
152 
153 int _sos_syscall8(int id,
154                   unsigned int arg1,
155                   unsigned int arg2,
156                   unsigned int arg3,
157                   unsigned int arg4,
158                   unsigned int arg5,
159                   unsigned int arg6,
160                   unsigned int arg7,
161                   unsigned int arg8)
162 {
163   unsigned int args[] = { arg3, arg4, arg5, arg6, arg7, arg8 };
164   return _sos_syscall3(id, arg1, arg2, (unsigned)args);
165 }
166 
167 
168 void _sos_exit(int status)
169 {
170   _sos_syscall1(SOS_SYSCALL_ID_EXIT, (unsigned)status);
171   
172   /* Never reached ! */
173   for ( ; ; )
174     ;
175 }
176 
177 
178 int _sos_bochs_write(const char * str, unsigned length)
179 {
180   return _sos_syscall2(SOS_SYSCALL_ID_BOCHS_WRITE,
181                        (unsigned)str,
182                        length);
183 }
184 
185 
186 int _sos_fork()
187 {
188   return _sos_syscall0(SOS_SYSCALL_ID_FORK);
189 }
190 
191 
192 int _sos_exec(const char * prog)
193 {
194   return _sos_syscall2(SOS_SYSCALL_ID_EXEC, (unsigned int)prog,
195                        (unsigned int)strlen(prog));
196 }
197 
198 
199 int _sos_munmap(void * start, size_t length)
200 {
201   return _sos_syscall2(SOS_SYSCALL_ID_MUNMAP,
202                        (unsigned int)start,
203                        length);
204 }
205 
206 
207 int _sos_mprotect(const void *addr, size_t len, int prot)
208 {
209   return _sos_syscall3(SOS_SYSCALL_ID_MPROTECT,
210                        (unsigned int)addr,
211                        len,
212                        (unsigned int)prot);
213 }
214 
215 
216 int _sos_mresize(void * old_addr, size_t old_len,
217                  void * *new_addr, size_t new_len,
218                  unsigned long flags)
219 {
220   return _sos_syscall5(SOS_SYSCALL_ID_MRESIZE,
221                        (unsigned int)old_addr,
222                        old_len,
223                        (unsigned int)new_addr,
224                        new_len,
225                        flags);
226 }
227 
228 
229 int _sos_msync(void *start, size_t length, int flags)
230 {
231   return _sos_syscall3(SOS_SYSCALL_ID_MSYNC,
232                        (unsigned int)start,
233                        length,
234                        flags);  
235 }
236 
237 
238 /**
239  * Helper function that represents the start routine of a new user
240  * thread created from user space (syscall new_thread). It takes 2
241  * arguments that are passsed in the eax/ebx registers (@see
242  * cpu_ustate_init() in hwcore/cpu_context.c): the start function of
243  * the new thread (eax), the argument passed to it (ebx).
244  */
245 static void thread_routine(void)
246 {
247   /* NOTE: variables as named registers is a gcc extension */
248   register unsigned long int reg_arg1 asm("%eax");
249   register unsigned long int reg_arg2 asm("%ebx");
250 
251   sos_thread_func_t * func = (sos_thread_func_t*)reg_arg1;
252   unsigned long int arg = reg_arg2;
253 
254   func(arg);
255   _sos_exit(0);
256 }
257 
258 
259 int _sos_new_thread(sos_thread_func_t *func,
260                     void* arg,
261                     size_t stack_size)
262 {
263   return _sos_syscall4(SOS_SYSCALL_ID_NEW_THREAD,
264                        (unsigned)thread_routine,
265                        (unsigned)func, (unsigned)arg,
266                        stack_size);
267 }
268 
269 
270 int _sos_nanosleep(unsigned long int sec,
271                    unsigned long int nanosec)
272 {
273   return _sos_syscall2(SOS_SYSCALL_ID_NANOSLEEP,
274                        sec, nanosec);
275 }
276 
277 
278 void * _sos_brk(void * new_top_address)
279 {
280   return (void*)_sos_syscall1(SOS_SYSCALL_ID_BRK,
281                               (unsigned)new_top_address);
282 }
283 
284 
285 int _sos_mount(const char *source, const char *target,
286                const char *filesystemtype, unsigned long mountflags,
287                const char *args)
288 {
289   if (!target || !filesystemtype)
290     return -1;
291 
292   return _sos_syscall7(SOS_SYSCALL_ID_MOUNT,
293                        (unsigned int)source, source?strlen(source):0,
294                        (unsigned int)target, strlen(target),
295                        (unsigned int)filesystemtype,
296                        mountflags,
297                        (unsigned int)args);
298 }
299 
300 
301 int _sos_umount(const char *target)
302 {
303   if (!target)
304     return -1;
305 
306   return _sos_syscall2(SOS_SYSCALL_ID_UMOUNT,
307                        (unsigned int)target,
308                        strlen(target));
309 }
310 
311 
312 void _sos_sync(void)
313 {
314   _sos_syscall0(SOS_SYSCALL_ID_SYNC);
315 }
316 
317 
318 int _sos_statvfs(const char *path, struct statvfs *buf)
319 {
320   if (! path)
321     return -1;
322     
323   return _sos_syscall3(SOS_SYSCALL_ID_VFSTAT64,
324                        (unsigned)path,
325                        strlen(path),
326                        (unsigned)buf);
327 }
328 
329 
330 int _sos_open(const char * pathname, int flags, int mode)
331 {
332   if (! pathname)
333     return -1;
334 
335   return _sos_syscall4(SOS_SYSCALL_ID_OPEN,
336                        (unsigned)pathname,
337                        strlen(pathname),
338                        flags,
339                        mode);
340 }
341 
342 
343 int _sos_close(int fd)
344 {
345   return _sos_syscall1(SOS_SYSCALL_ID_CLOSE, fd);
346 }
347 
348 
349 int _sos_read(int fd, char * buf, size_t * len)
350 {
351   return _sos_syscall3(SOS_SYSCALL_ID_READ, fd,
352                        (unsigned int) buf,
353                        (unsigned int) len);
354 }
355 
356 
357 int _sos_write(int fd, const char * buf, size_t * len)
358 {
359   return _sos_syscall3(SOS_SYSCALL_ID_WRITE, fd,
360                        (unsigned int) buf,
361                        (unsigned int) len);
362 }
363 
364 
365 int _sos_seek64(int fd, loff_t * offset, int whence)
366 {
367   return _sos_syscall3(SOS_SYSCALL_ID_SEEK64, fd,
368                        (unsigned int)offset,
369                        (unsigned int)whence);
370 }
371 
372 
373 int _sos_fmmap(void ** ptr_hint_addr, size_t len, int prot, int flags,
374                int fd, loff_t offset)
375 {
376   return _sos_syscall7(SOS_SYSCALL_ID_FSMMAP,
377                        (unsigned int)ptr_hint_addr, len, prot, flags,
378                        (unsigned int)fd,
379                        /* offs64_hi */(offset >> 32),
380                        /* offs64_lo */(offset & 0xffffffff));
381 }
382 
383 
384 int _sos_ftruncate64(int fd, loff_t length)
385 {
386   return _sos_syscall2(SOS_SYSCALL_ID_FTRUNCATE64, fd,
387                        (unsigned int)length);  
388 }
389 
390 
391 int _sos_fcntl(int fd, int cmd, int arg)
392 {
393   return _sos_syscall3(SOS_SYSCALL_ID_FCNTL, fd,
394                        (unsigned int)cmd,
395                        (unsigned int)arg);
396 }
397 
398 
399 int _sos_ioctl(int fd, int cmd, int arg)
400 {
401   return _sos_syscall3(SOS_SYSCALL_ID_IOCTL, fd,
402                        (unsigned int)cmd,
403                        (unsigned int)arg);
404 }
405 
406 
407 int _sos_creat(const char *pathname, int mode)
408 {
409   if (! pathname)
410     return -1;
411 
412   return _sos_syscall3(SOS_SYSCALL_ID_CREAT,
413                        (unsigned int)pathname,
414                        strlen(pathname),
415                        mode);
416 }
417 
418 
419 int _sos_link (const char *oldpath, const char *newpath)
420 {
421   if (!oldpath || !newpath)
422     return -1;
423 
424   return _sos_syscall4(SOS_SYSCALL_ID_LINK,
425                        (unsigned int)oldpath,
426                        strlen(oldpath),
427                        (unsigned int)newpath,
428                        strlen(newpath));
429 }
430 
431 
432 int _sos_unlink(const char *pathname)
433 {
434   if (! pathname)
435     return -1;
436 
437   return _sos_syscall2(SOS_SYSCALL_ID_UNLINK,
438                        (unsigned int)pathname,
439                        strlen(pathname));
440 }
441 
442 
443 int _sos_rename (const char *oldpath, const char *newpath)
444 {
445   if (!oldpath || !newpath)
446     return -1;
447 
448   return _sos_syscall4(SOS_SYSCALL_ID_RENAME,
449                        (unsigned int)oldpath,
450                        strlen(oldpath),
451                        (unsigned int)newpath,
452                        strlen(newpath));
453 }
454 
455 
456 int _sos_symlink(const char *target, const char *path)
457 {
458   if (!path || !target)
459     return -1;
460 
461   return _sos_syscall4(SOS_SYSCALL_ID_SYMLINK,
462                        (unsigned int)path,
463                        strlen(path),
464                        (unsigned int)target,
465                        strlen(target));
466 }
467 
468 
469 int _sos_mknod(const char *pathname, mode_t mode,
470                int type,
471                unsigned int major, unsigned minor)
472 {
473   if (!pathname)
474     return -1;
475 
476   return _sos_syscall6(SOS_SYSCALL_ID_MKNOD,
477                        (unsigned int)pathname,
478                        strlen(pathname),
479                        type, mode, major, minor);
480 }
481 
482 
483 struct dirent; /* Forward declaration */
484 int _sos_readdir(int fd, struct dirent * dirent)
485 {
486   return _sos_syscall2(SOS_SYSCALL_ID_READDIR,
487                        fd,
488                        (unsigned int)dirent);
489 }
490 
491 
492 int _sos_mkdir(const char *pathname, mode_t mode)
493 {
494   if (!pathname)
495     return -1;
496 
497   return _sos_syscall3(SOS_SYSCALL_ID_MKDIR,
498                        (unsigned int)pathname,
499                        strlen(pathname),
500                        mode);
501 }
502 
503 
504 int _sos_rmdir(const char *pathname)
505 {
506   if (!pathname)
507     return -1;
508 
509   return _sos_syscall2(SOS_SYSCALL_ID_RMDIR,
510                        (unsigned int)pathname,
511                        strlen(pathname));
512 }
513 
514 
515 int _sos_chmod(const char *pathname, mode_t mode)
516 {
517   if (!pathname)
518     return -1;
519 
520   return _sos_syscall3(SOS_SYSCALL_ID_CHMOD,
521                        (unsigned int)pathname,
522                        strlen(pathname),
523                        mode);
524 }
525 
526 
527 int _sos_stat(const char *pathname, int nofollow, struct stat * st)
528 {
529   if (!pathname || !st)
530     return -1;
531 
532   return _sos_syscall4(SOS_SYSCALL_ID_STAT64,
533                        (unsigned int)pathname,
534                        strlen(pathname),
535                        nofollow,
536                        (unsigned int)st);
537 }
538 
539 
540 int _sos_chroot(const char *dirname)
541 {
542   if (!dirname)
543     return -1;
544 
545   return _sos_syscall2(SOS_SYSCALL_ID_CHROOT,
546                        (unsigned int)dirname,
547                        strlen(dirname));
548 }
549 
550 
551 int _sos_chdir(const char *dirname)
552 {
553   if (!dirname)
554     return -1;
555 
556   return _sos_syscall2(SOS_SYSCALL_ID_CHDIR,
557                        (unsigned int)dirname,
558                        strlen(dirname));
559 }
560 
561 
562 int _sos_fchdir(int fd)
563 {
564   return _sos_syscall1(SOS_SYSCALL_ID_FCHDIR,
565                        (unsigned int)fd);
566 }

source navigation ] diff markup ] identifier search ] general search ]