From bb55beef914e7488350ad1d0419d4bc60ad63c99 Mon Sep 17 00:00:00 2001 From: Alex AUVOLAT Date: Fri, 28 Mar 2014 09:10:23 +0100 Subject: Import code for article1, 2, 3, 4 --- sos-code-article1/sos/assert.h | 42 +++++++ sos-code-article1/sos/errno.h | 39 ++++++ sos-code-article1/sos/klibc.c | 271 +++++++++++++++++++++++++++++++++++++++++ sos-code-article1/sos/klibc.h | 84 +++++++++++++ sos-code-article1/sos/main.c | 69 +++++++++++ sos-code-article1/sos/types.h | 42 +++++++ 6 files changed, 547 insertions(+) create mode 100644 sos-code-article1/sos/assert.h create mode 100644 sos-code-article1/sos/errno.h create mode 100644 sos-code-article1/sos/klibc.c create mode 100644 sos-code-article1/sos/klibc.h create mode 100644 sos-code-article1/sos/main.c create mode 100644 sos-code-article1/sos/types.h (limited to 'sos-code-article1/sos') diff --git a/sos-code-article1/sos/assert.h b/sos-code-article1/sos/assert.h new file mode 100644 index 0000000..a14ca0b --- /dev/null +++ b/sos-code-article1/sos/assert.h @@ -0,0 +1,42 @@ +/* Copyright (C) 2004 The KOS Team + + 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. +*/ +#ifndef _SOS_ASSERT_H_ +#define _SOS_ASSERT_H_ + +#include +#include + +/** + * If the expr is FALSE, print a message and halt the machine + */ +#define SOS_ASSERT_FATAL(expr) \ + ({ \ + int __res=(int)(expr); \ + if (! __res) { \ + asm("cli\n"); /* disable interrupts -- x86 only */ \ + sos_bochs_printf("%s@%s:%d Assertion " # expr " failed\n", \ + __PRETTY_FUNCTION__, __FILE__, __LINE__); \ + sos_x86_videomem_printf(24, 0, 12, \ + "%s@%s:%d Assertion " # expr " failed", \ + __PRETTY_FUNCTION__, __FILE__, __LINE__); \ + for (;;) asm("hlt;") ; /* Infinite loop, ie simple system halt */ \ + } \ + }) + + +#endif /* _SOS_ASSERT_H_ */ diff --git a/sos-code-article1/sos/errno.h b/sos-code-article1/sos/errno.h new file mode 100644 index 0000000..f13e740 --- /dev/null +++ b/sos-code-article1/sos/errno.h @@ -0,0 +1,39 @@ +/* Copyright (C) 2004 The SOS Team + Copyright (C) 1999 Free Software Foundation, Inc. + + 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. +*/ +#ifndef _SOS_ERRNO_H_ +#define _SOS_ERRNO_H_ + +/** + * @file errno.h + * + * SOS return value codes and errors. + */ + +/* Positive values of the error codes */ +#define SOS_OK 0 /* No error */ +#define SOS_EINVAL 1 /* Invalid argument */ +#define SOS_ENOSUP 2 /* Operation not supported */ +#define SOS_EFATAL 255 /* Internal fatal error */ + +/* A negative value means that an error occured. For + * example -SOS_EINVAL means that the error was "invalid + * argument" */ +typedef int sos_ret_t; + +#endif /* _SOS_ERRNO_H_ */ diff --git a/sos-code-article1/sos/klibc.c b/sos-code-article1/sos/klibc.c new file mode 100644 index 0000000..277a15c --- /dev/null +++ b/sos-code-article1/sos/klibc.c @@ -0,0 +1,271 @@ +/* Copyright (C) 2004 David Decotigny (with INSA Rennes for vsnprintf) + Copyright (C) 2003 The KOS Team + Copyright (C) 1999 Free Software Foundation + + 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. +*/ +#include "klibc.h" + +/* For an optimized version, see BSD sources ;) */ +void *memcpy(void *dst0, const void *src0, register unsigned int size) +{ + char *dst; + const char *src; + for (dst = (char*)dst0, src = (const char*)src0 ; + size > 0 ; + dst++, src++, size--) + *dst = *src; + return dst0; +} + +/* ditto */ +void *memset(void *dst0, register int c, register unsigned int length) +{ + char *dst; + for (dst = (char*) dst0 ; + length > 0 ; + dst++, length --) + *dst = (char)c; + return dst0; +} + +int memcmp(const void *s1, const void *s2, sos_size_t len) +{ + const unsigned char *c1, *c2; + unsigned int i; + + for (i = 0, c1 = s1, c2 = s2; i < len; i++, c1++, c2++) + { + if(*c1 != *c2) + return *c1 - *c2; + } + + return 0; +} + + +unsigned int strlen(register const char *str) +{ + unsigned int retval = 0; + + while (*str++) + retval++; + + return retval; +} + + +unsigned int strnlen(const char * s, sos_size_t count) +{ + const char *sc; + + for (sc = s; count-- && *sc != '\0'; ++sc) + /* nothing */continue; + + return sc - s; +} + + +char *strzcpy(register char *dst, register const char *src, register int len) +{ + int i; + + if (len <= 0) + return dst; + + for (i = 0; i < len; i++) + { + dst[i] = src[i]; + if(src[i] == '\0') + return dst; + } + + dst[len-1] = '\0'; + return dst; +} + + +char *strzcat (char *dest, const char *src, sos_size_t n) +{ + char *res = dest; + + for ( ; *dest ; dest++); + + for ( ; *src ; src++, dest++) { + *dest = *src; + n--; + if (n <= 0) + break; + } + + *dest = '\0'; + return res; +} + +int strcmp(register const char *s1, register const char *s2) +{ + while (*s1 == *s2++) + if (*s1++ == 0) + return (0); + + return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1)); +} + + +int strncmp(register const char *s1, register const char *s2, register int len) +{ + char c1 = '\0', c2 = '\0'; + + while (len > 0) + { + c1 = (unsigned char) *s1++; + c2 = (unsigned char) *s2++; + if (c1 == '\0' || c1 != c2) + return c1 - c2; + len--; + } + + return c1 - c2; +} + + +/* I (d2) borrowed and rewrote this for Nachos/INSA Rennes. Thanks to + them for having kindly allowed me to do so. */ +int vsnprintf(char *buff, sos_size_t len, const char * format, va_list ap) +{ + sos_size_t i, result; + + if (!buff || !format || (len < 0)) + return -1; + +#define PUTCHAR(thechar) \ + do { \ + if (result < len-1) \ + *buff++ = (thechar); \ + result++; \ + } while (0) + + result = 0; + for(i=0 ; format[i] != '\0' ; i++){ + switch (format[i]) + { + case '%': + i++; + switch(format[i]) + { + case '%': + { + PUTCHAR('%'); + break; + } + case 'i':; + case 'd': + { + int integer = va_arg(ap,int); + int cpt2 = 0; + char buff_int[16]; + + if (integer<0) + PUTCHAR('-'); + /* Ne fait pas integer = -integer ici parce que INT_MIN + n'a pas d'equivalent positif (int = [-2^31, 2^31-1]) */ + + do { + int m10 = integer%10; + m10 = (m10 < 0)? -m10:m10; + buff_int[cpt2++]=(char)('0'+ m10); + integer=integer/10; + } while(integer!=0); + + for(cpt2 = cpt2 - 1 ; cpt2 >= 0 ; cpt2--) + PUTCHAR(buff_int[cpt2]); + + break; + } + + case 'c': + { + int value = va_arg(ap,int); + PUTCHAR((char)value); + break; + } + + case 's': + { + char *string = va_arg(ap,char *); + if (! string) + string = "(null)"; + for( ; *string != '\0' ; string++) + PUTCHAR(*string); + break; + } + + case 'x': + { + unsigned int hexa = va_arg(ap,int); + unsigned int nb; + int i, had_nonzero = 0; + for(i=0 ; i < 8 ; i++) + { + nb = (unsigned int)(hexa << (i*4)); + nb = (nb >> 28) & 0xf; + // Skip the leading zeros + if (nb == 0) + { + if (had_nonzero) + PUTCHAR('0'); + } + else + { + had_nonzero = 1; + if (nb < 10) + PUTCHAR('0'+nb); + else + PUTCHAR('a'+(nb-10)); + } + } + if (! had_nonzero) + PUTCHAR('0'); + break; + } + break; + + default: + PUTCHAR('%'); + PUTCHAR(format[i]); + } + break; + + default: + PUTCHAR(format[i]); + } + } + + *buff = '\0'; + return result; +} + + +int snprintf(char * buff, sos_size_t len, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + len = vsnprintf(buff, len, format, ap); + va_end(ap); + + return len; +} diff --git a/sos-code-article1/sos/klibc.h b/sos-code-article1/sos/klibc.h new file mode 100644 index 0000000..a8b9d49 --- /dev/null +++ b/sos-code-article1/sos/klibc.h @@ -0,0 +1,84 @@ +/* Copyright (C) 2003 The KOS Team + Copyright (C) 1999 Free Software Foundation + + 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. +*/ +#ifndef _SOS_KLIBC_H_ +#define _SOS_KLIBC_H_ + +/** + * @file klibc.h + * + * Basic libc-style support for common useful functions (string.h, + * stdarg.h), some with slight non-standard behavior (see comments). + */ + +#include + +/* string.h functions */ + +void *memcpy(void *dst, const void *src, register unsigned int size ) ; +void *memset(void *dst, register int c, register unsigned int length ) ; +int memcmp(const void *s1, const void *s2, sos_size_t n); + +unsigned int strlen( register const char *str) ; +unsigned int strnlen(const char * s, sos_size_t maxlen); + +/** + * @note Same as strncpy(), with a slightly different semantic. + * Actually, strncpy(3C) says " The result will not be null-terminated + * if the length of 'from' is n or more.". Here, 'dst' is ALWAYS + * null-terminated. And its total len will ALWAYS be <= len, with + * null-terminating-char included. + */ +char *strzcpy( register char *dst, register const char *src, + register int len ) ; + +/** + * @note Same as strncat(), with the same semantic : 'dst' is ALWAYS + * null-terminated. And its total len will ALWAYS be <= len, with + * null-terminating-char included. + */ +char *strzcat (char *dest, const char *src, + const sos_size_t len); + +int strcmp(register const char *s1, register const char *s2 ); +int strncmp(register const char *s1, register const char *s2, + register int len ); + +/* Basic stdarg.h macros. Taken from gcc support files */ +#define __GNUC_VA_LIST +typedef void *__gnuc_va_list; +typedef __gnuc_va_list va_list; +#define __va_rounded_size(TYPE) \ + (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) +#define va_start(AP, LASTARG) \ + (AP = ((__gnuc_va_list) __builtin_next_arg (LASTARG))) +#define va_end(AP) \ + ((void)0) +#define va_arg(AP, TYPE) \ + (AP = (__gnuc_va_list) ((char *) (AP) + __va_rounded_size (TYPE)), \ + *((TYPE *) (void *) ((char *) (AP) - __va_rounded_size (TYPE)))) +#define __va_copy(dest, src) \ + (dest) = (src) + +/* stdarg.h functions. There might be a non-standard behavior: there + will always be a trailing '\0' in the resulting string */ +int vsnprintf(char *, sos_size_t, const char *, va_list); +int snprintf(char *, sos_size_t, const char *, /*args*/ ...) + __attribute__ ((format (printf, 3, 4))); + +#endif /* _SOS_KLIBC_H_ */ diff --git a/sos-code-article1/sos/main.c b/sos-code-article1/sos/main.c new file mode 100644 index 0000000..a5adb54 --- /dev/null +++ b/sos-code-article1/sos/main.c @@ -0,0 +1,69 @@ +/* Copyright (C) 2004 The SOS Team + Copyright (C) 1999 Free Software Foundation, Inc. + + 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. +*/ + +/* Include definitions of the multiboot standard */ +#include +#include +#include +#include +#include + + + +/* The C entry point of our operating system */ +void sos_main(unsigned long magic, unsigned long addr) +{ + unsigned i; + + /* Grub sends us a structure, called multiboot_info_t with a lot of + precious informations about the system, see the multiboot + documentation for more information. */ + multiboot_info_t *mbi; + mbi = (multiboot_info_t *) addr; + + /* Setup bochs and console, and clear the console */ + sos_bochs_setup(); + + sos_x86_videomem_setup(); + sos_x86_videomem_cls(SOS_X86_VIDEO_BG_BLUE); + + /* Greetings from SOS */ + if (magic == MULTIBOOT_BOOTLOADER_MAGIC) + /* Loaded with Grub */ + sos_x86_videomem_printf(1, 0, + SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE, + "Welcome From GRUB to %s%c RAM is %dMB (upper mem = 0x%x kB)", + "SOS", ',', + (unsigned)(mbi->mem_upper >> 10) + 1, + (unsigned)mbi->mem_upper); + else + /* Not loaded with grub */ + sos_x86_videomem_printf(1, 0, + SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE, + "Welcome to SOS"); + + sos_bochs_putstring("Message in a bochs\n"); + + + /* An operatig system never ends */ + for (;;) + continue; + + return; +} diff --git a/sos-code-article1/sos/types.h b/sos-code-article1/sos/types.h new file mode 100644 index 0000000..de54a9c --- /dev/null +++ b/sos-code-article1/sos/types.h @@ -0,0 +1,42 @@ +/* Copyright (C) 2004 The SOS Team + Copyright (C) 1999 Free Software Foundation, Inc. + + 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. +*/ +#ifndef _SOS_TYPES_H_ +#define _SOS_TYPES_H_ + +/** + * @file types.h + * + * SOS basic types definition + */ + +/** Memory size of an object (positive) */ +typedef unsigned int sos_size_t; + +/** Low-level sizes */ +typedef unsigned long int sos_ui32_t; /* 32b unsigned */ +typedef unsigned short int sos_ui16_t; /* 16b unsigned */ +typedef unsigned char sos_ui8_t; /* 8b unsigned */ + +typedef enum { FALSE=0, TRUE } sos_bool_t; + +/** Not a proper type, but highly useful with basic type + manipulations */ +#define NULL ((void*)0) + +#endif /* _SOS_TYPES_H_ */ -- cgit v1.2.3