diff --git a/Makefile b/Makefile index ee7a606..203903f 100755 --- a/Makefile +++ b/Makefile @@ -1,7 +1,10 @@ # $Id$ # The System Makefile (C) 2002 The UbixOS Project -all: kernel +all: libc kernel + +libc: src + (cd src/lib/libc;make) kernel: src (cd src/sys;make) @@ -11,3 +14,4 @@ clean: (cd src/sys;make clean) + (cd src/lib/libc;make clean) \ No newline at end of file diff --git a/src/lib/libc/Makefile b/src/lib/libc/Makefile new file mode 100755 index 0000000..a6bcd9d --- /dev/null +++ b/src/lib/libc/Makefile @@ -0,0 +1,43 @@ +# $Id$ +# The System Makefile (C) 2002 The UbixOS Project + + +#Compiler +GCC = gcc +G++ = gcc + +#Linker +LD = ld -Bshareable +AR = ar + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = vsprintf.o + +#Output +OUTPUT = libc.so + +lib.so: $(OBJS) + $(LD) -o $(OUTPUT) $(OBJS) + +# Compile the source files +.cc.o: + $(G++) -Wall -nostdinc -O -I./include -c -o $@ $< + +.cc.s: + $(G++) -Wall -nostdinc -O -I./include -S -o $@ $< + +.c.o: + $(GCC) -Wall -nostdinc -O -I./include -c $< + +.c.s: + $(GCC) -Wall -nostdinc -O -I./include -S -o $@ $< + +.S.o: + $(GCC) -Wall -nostdinc -c -o $@ $< + +# Clean up the junk +clean: + $(REMOVE) $(OBJS) $(OUTPUT) diff --git a/src/lib/libc/vsprintf.c b/src/lib/libc/vsprintf.c index 35d97f6..6443b7f 100755 --- a/src/lib/libc/vsprintf.c +++ b/src/lib/libc/vsprintf.c @@ -54,9 +54,10 @@ } else sign=(type&PLUS) ? '+' : ((type&SPACE) ? ' ' : 0); if (sign) size--; - if (type&SPECIAL) - if (base==16) size -= 2; - else if (base==8) size--; + if (type&SPECIAL) { + if (base==16) { size -= 2; } + else if (base==8) { size--; } + } i=0; if (num==0) tmp[i++]='0'; @@ -69,13 +70,15 @@ *str++ = ' '; if (sign) *str++ = sign; - if (type&SPECIAL) - if (base==8) - *str++ = '0'; - else if (base==16) { - *str++ = '0'; - *str++ = digits[33]; + if (type&SPECIAL) { + if (base==8) { + *str++ = '0'; + } + else if (base==16) { + *str++ = '0'; + *str++ = digits[33]; } + } if (!(type&LEFT)) while(size-->0) *str++ = c; @@ -88,7 +91,7 @@ return str; } -int vsprintf(char *buf, const char *fmt, va_list args) +int vsprintf(char *buf, const char *fmt, vaList args) { int len; int i; diff --git a/src/sys/include/drivers/video.h b/src/sys/include/drivers/video.h index df7a7d9..98763c4 100755 --- a/src/sys/include/drivers/video.h +++ b/src/sys/include/drivers/video.h @@ -11,5 +11,6 @@ extern int printColor; void kprint(char *string); +int kprintf(const char *fmt, ...); #endif \ No newline at end of file diff --git a/src/sys/include/stdarg.h b/src/sys/include/stdarg.h new file mode 100755 index 0000000..bf7b3ae --- /dev/null +++ b/src/sys/include/stdarg.h @@ -0,0 +1,37 @@ +/************************************************************************************** +$Id$ + + +**************************************************************************************/ + +#ifndef _STDARG_H +#define _STDARG_H + +typedef char *va_list; + +/* Amount of space required in an argument list for an arg of type TYPE. + TYPE may alternatively be an expression whose type is used. */ + +#define __va_rounded_size(TYPE) \ + (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) + +#ifndef __sparc__ +#define va_start(AP, LASTARG) \ + (AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) +#else +#define va_start(AP, LASTARG) \ + (__builtin_saveregs (), \ + AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) +#endif + +void va_end (va_list); /* Defined in gnulib */ +#define va_end(AP) + +#define va_arg(AP, TYPE) \ + (AP += __va_rounded_size (TYPE), \ + *((TYPE *) (AP - __va_rounded_size (TYPE)))) + + +int vsprintf(char *buf, const char *fmt, va_list args); + +#endif /* _STDARG_H */ diff --git a/src/sys/include/version/version.h b/src/sys/include/version/version.h index 1bfb426..2749a8e 100755 --- a/src/sys/include/version/version.h +++ b/src/sys/include/version/version.h @@ -8,14 +8,8 @@ #ifndef _VERSION_H #define _VERSION_H -#include - #define ubixVersion "0.01a" void outputVersion(); -void outputCopyright() { - kprint("Copyright (c) 2002 - The UbixOS Project\n"); -}; - #endif \ No newline at end of file diff --git a/src/sys/init/main.c b/src/sys/init/main.c index 611bb3c..bc0062a 100755 --- a/src/sys/init/main.c +++ b/src/sys/init/main.c @@ -11,25 +11,33 @@ int main(); -descriptorTable(gdt,4) { +descriptorTable(GDT,4) { {dummy:0}, standardDescriptor(0, 0xFFFFF, (dCode + dRead + dBig + dBiglim)), standardDescriptor(0, 0xFFFFF, (dData + dWrite + dBig + dBiglim)), standardDescriptor(1000, (sizeof(struct tssStruct)-1), (dTss)), }; +struct { + unsigned short limit __attribute__ ((packed)); + union descriptorTableunion *idt __attribute__ ((packed)); + } loadgdt = { (5 * sizeof(union descriptorTableunion) - 1), GDT }; + void _start() { +/* asm( - "lgdt (gdt) \n" - "mov $0x18,%ax \n" - "ltr %ax \n" + "lgdt (loadgdt) \n" + "mov $0x18,%%ax \n" + "ltr %%ax \n" + : + : "r" (GDT) ); +*/ main(); while (1); } int main() { -// outputCopyright(); //Display Copyright Info outputVersion(); //Display Version Info return(0); } \ No newline at end of file diff --git a/src/sys/kernel/Makefile b/src/sys/kernel/Makefile index 7b00d01..254560a 100755 --- a/src/sys/kernel/Makefile +++ b/src/sys/kernel/Makefile @@ -14,7 +14,7 @@ REMOVE = rm -fr # Objects -OBJS = io.o kprintf.o version.o +OBJS = io.o version.o kprintf.o vsprintf.o all: $(OBJS) diff --git a/src/sys/kernel/kprintf.c b/src/sys/kernel/kprintf.c index 1de1de4..29d0127 100755 --- a/src/sys/kernel/kprintf.c +++ b/src/sys/kernel/kprintf.c @@ -5,4 +5,16 @@ $Id$ **************************************************************************************/ -#include \ No newline at end of file +#include +#include + +int kprintf(const char *fmt, ...) { + va_list args; + int i; + char buf[1024]; + va_start(args, fmt); + i=vsprintf(buf,fmt,args); + va_end(args); + kprint(buf); + return(i); + } \ No newline at end of file diff --git a/src/sys/kernel/version.c b/src/sys/kernel/version.c index 8686881..6d73777 100755 --- a/src/sys/kernel/version.c +++ b/src/sys/kernel/version.c @@ -9,5 +9,6 @@ #include void outputVersion() { - kprint("Woot"); + kprintf("Copyright (c) 2002 - The UbixOS Project\n"); + kprintf("Woot"); } diff --git a/src/sys/kernel/vsprintf.c b/src/sys/kernel/vsprintf.c new file mode 100755 index 0000000..3f85776 --- /dev/null +++ b/src/sys/kernel/vsprintf.c @@ -0,0 +1,233 @@ +/************************************************************************************** +$Id$ + + +**************************************************************************************/ + +/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ +/* + * Wirzenius wrote this portably, Torvalds fucked it up :-) + */ + +#include +//#include + +/* we use this so that we can do without the ctype library */ +#define is_digit(c) ((c) >= '0' && (c) <= '9') + +static int skip_atoi(const char **s) +{ + int i=0; + + while (is_digit(**s)) + i = i*10 + *((*s)++) - '0'; + return i; +} + +#define ZEROPAD 1 /* pad with zero */ +#define SIGN 2 /* unsigned/signed long */ +#define PLUS 4 /* show plus */ +#define SPACE 8 /* space if plus */ +#define LEFT 16 /* left justified */ +#define SPECIAL 32 /* 0x */ +#define SMALL 64 /* use 'abcdef' instead of 'ABCDEF' */ + +#define do_div(n,base) ({ \ +int __res; \ +__asm__("divl %4":"=a" (n),"=d" (__res):"0" (n),"1" (0),"r" (base)); \ +__res; }) + +static char * number(char * str, int num, int base, int size, int precision + ,int type) +{ + char c,sign,tmp[36]; + const char *digits="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + int i; + + if (type&SMALL) digits="0123456789abcdefghijklmnopqrstuvwxyz"; + if (type&LEFT) type &= ~ZEROPAD; + if (base<2 || base>36) + return 0; + c = (type & ZEROPAD) ? '0' : ' ' ; + if (type&SIGN && num<0) { + sign='-'; + num = -num; + } else + sign=(type&PLUS) ? '+' : ((type&SPACE) ? ' ' : 0); + if (sign) size--; + if (type&SPECIAL) + if (base==16) size -= 2; + else if (base==8) size--; + i=0; + if (num==0) + tmp[i++]='0'; + else while (num!=0) + tmp[i++]=digits[do_div(num,base)]; + if (i>precision) precision=i; + size -= precision; + if (!(type&(ZEROPAD+LEFT))) + while(size-->0) + *str++ = ' '; + if (sign) + *str++ = sign; + if (type&SPECIAL) + if (base==8) + *str++ = '0'; + else if (base==16) { + *str++ = '0'; + *str++ = digits[33]; + } + if (!(type&LEFT)) + while(size-->0) + *str++ = c; + while(i0) + *str++ = tmp[i]; + while(size-->0) + *str++ = ' '; + return str; +} + +int vsprintf(char *buf, const char *fmt, va_list args) +{ + int len; + int i; + char * str; + char *s; + int *ip; + + int flags; /* flags to number() */ + + int field_width; /* width of output field */ + int precision; /* min. # of digits for integers; max + number of chars for from string */ + int qualifier; /* 'h', 'l', or 'L' for integer fields */ + + for (str=buf ; *fmt ; ++fmt) { + if (*fmt != '%') { + *str++ = *fmt; + continue; + } + + /* process flags */ + flags = 0; + repeat: + ++fmt; /* this also skips first '%' */ + switch (*fmt) { + case '-': flags |= LEFT; goto repeat; + case '+': flags |= PLUS; goto repeat; + case ' ': flags |= SPACE; goto repeat; + case '#': flags |= SPECIAL; goto repeat; + case '0': flags |= ZEROPAD; goto repeat; + } + + /* get field width */ + field_width = -1; + if (is_digit(*fmt)) + field_width = skip_atoi(&fmt); + else if (*fmt == '*') { + /* it's the next argument */ + field_width = va_arg(args, int); + if (field_width < 0) { + field_width = -field_width; + flags |= LEFT; + } + } + + /* get the precision */ + precision = -1; + if (*fmt == '.') { + ++fmt; + if (is_digit(*fmt)) + precision = skip_atoi(&fmt); + else if (*fmt == '*') { + /* it's the next argument */ + precision = va_arg(args, int); + } + if (precision < 0) + precision = 0; + } + + /* get the conversion qualifier */ + qualifier = -1; + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') { + qualifier = *fmt; + ++fmt; + } + + switch (*fmt) { + case 'c': + if (!(flags & LEFT)) + while (--field_width > 0) + *str++ = ' '; + *str++ = (unsigned char) va_arg(args, int); + while (--field_width > 0) + *str++ = ' '; + break; + + case 's': + s = va_arg(args, char *); + len = strlen(s); + if (precision < 0) + precision = len; + else if (len > precision) + len = precision; + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = *s++; + while (len < field_width--) + *str++ = ' '; + break; + + case 'o': + str = number(str, va_arg(args, unsigned long), 8, + field_width, precision, flags); + break; + + case 'p': + if (field_width == -1) { + field_width = 8; + flags |= ZEROPAD; + } + str = number(str, + (unsigned long) va_arg(args, void *), 16, + field_width, precision, flags); + break; + + case 'x': + flags |= SMALL; + case 'X': + str = number(str, va_arg(args, unsigned long), 16, + field_width, precision, flags); + break; + + case 'd': + case 'i': + flags |= SIGN; + case 'u': + str = number(str, va_arg(args, unsigned long), 10, + field_width, precision, flags); + break; + + case 'n': + ip = va_arg(args, int *); + *ip = (str - buf); + break; + + default: + if (*fmt != '%') + *str++ = '%'; + if (*fmt) + *str++ = *fmt; + else + --fmt; + break; + } + } + *str = '\0'; + return str-buf; +} diff --git a/ubixos.kdevprj b/ubixos.kdevprj index 53db6ab..0222f96 100755 --- a/ubixos.kdevprj +++ b/ubixos.kdevprj @@ -85,8 +85,14 @@ sub_dirs=libc, type=normal +[src/lib/libc/Makefile] +dist=true +install=false +install_location= +type=DATA + [src/lib/libc/Makefile.am] -files=src/lib/libc/vsprintf.c +files=src/lib/libc/vsprintf.c,src/lib/libc/Makefile sub_dirs=include, type=static_library @@ -164,6 +170,7 @@ type=SOURCE [src/sys/include/Makefile.am] +files=src/sys/include/stdarg.h sub_dirs=ubixos,version,drivers type=normal @@ -178,6 +185,12 @@ install_location= type=HEADER +[src/sys/include/stdarg.h] +dist=true +install=false +install_location= +type=HEADER + [src/sys/include/ubixos/Makefile.am] files=src/sys/include/ubixos/gdt.h,src/sys/include/ubixos/scheduler.h,src/sys/include/ubixos/io.h sub_dirs=