diff --git a/kernel/Makefile b/kernel/Makefile index 3d1b42260..ca8a27cd1 100755 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -14,7 +14,7 @@ CFLAGS = -I$i LDFLAGS = -i HEAD = mpx.o -OBJS = start.o protect.o klib.o table.o main.o proc.o \ +OBJS = start.o protect.o klib.o table.o kprintf.o main.o proc.o \ i8259.o exception.o system.o clock.o utility.o debug.o SYSTEM = system.a LIBS = -ltimers diff --git a/kernel/kprintf.c b/kernel/kprintf.c new file mode 100644 index 000000000..4f0feaef2 --- /dev/null +++ b/kernel/kprintf.c @@ -0,0 +1,71 @@ +/* + * printf for the kernel + * + * Changes: + * Dec 10, 2004 kernel printing to circular buffer (Jorrit N. Herder) + * + * This file contains the routines that take care of kernel messages, i.e., + * diagnostic output within the kernel. Kernel messages are not directly + * displayed on the console, because this must be done by the output driver. + * Instead, the kernel accumulates characters in a buffer and notifies the + * output driver when a new message is ready. + */ + +#include "kernel.h" +#include "proc.h" +#include + +#define printf kprintf + +#include "../lib/sysutil/kprintf.c" + +#define END_OF_KMESS 0 +FORWARD _PROTOTYPE( void ser_putc, (char c)); + +/*===========================================================================* + * kputc * + *===========================================================================*/ +PUBLIC void kputc(c) +int c; /* character to append */ +{ +/* Accumulate a single character for a kernel message. Send a notification + * to the output driver if an END_OF_KMESS is encountered. + */ + if (c != END_OF_KMESS) { + if (do_serial_debug) + ser_putc(c); + kmess.km_buf[kmess.km_next] = c; /* put normal char in buffer */ + if (kmess.km_size < KMESS_BUF_SIZE) + kmess.km_size += 1; + kmess.km_next = (kmess.km_next + 1) % KMESS_BUF_SIZE; + } else { + int p, outprocs[] = OUTPUT_PROCS_ARRAY; + for(p = 0; outprocs[p] != NONE; p++) { + if(isokprocn(outprocs[p]) && !isemptyn(outprocs[p])) { + send_sig(outprocs[p], SIGKMESS); + } + } + } +} + +#define COM1_BASE 0x3F8 +#define COM1_THR (COM1_BASE + 0) +#define LSR_THRE 0x20 +#define COM1_LSR (COM1_BASE + 5) + +PRIVATE void ser_putc(char c) +{ + int i; + int lsr, thr; + + return; + + lsr= COM1_LSR; + thr= COM1_THR; + for (i= 0; i<100000; i++) + { + if (inb(lsr) & LSR_THRE) + break; + } + outb(thr, c); +} diff --git a/kernel/proto.h b/kernel/proto.h index 91387954a..738dfbe96 100755 --- a/kernel/proto.h +++ b/kernel/proto.h @@ -20,7 +20,7 @@ _PROTOTYPE( void main, (void) ); _PROTOTYPE( void prepare_shutdown, (int how) ); /* utility.c */ -_PROTOTYPE( void kprintf, (const char *fmt, ...) ); +_PROTOTYPE( int kprintf, (const char *fmt, ...) ); _PROTOTYPE( void panic, (_CONST char *s, int n) ); /* proc.c */ diff --git a/kernel/utility.c b/kernel/utility.c index 64520b20e..34263c65b 100755 --- a/kernel/utility.c +++ b/kernel/utility.c @@ -1,29 +1,9 @@ /* This file contains a collection of miscellaneous procedures: * panic: abort MINIX due to a fatal error - * kprintf: diagnostic output for the kernel - * - * Changes: - * Dec 10, 2004 kernel printing to circular buffer (Jorrit N. Herder) - * - * This file contains the routines that take care of kernel messages, i.e., - * diagnostic output within the kernel. Kernel messages are not directly - * displayed on the console, because this must be done by the output driver. - * Instead, the kernel accumulates characters in a buffer and notifies the - * output driver when a new message is ready. */ -#include #include "kernel.h" -#include #include -#include -#include -#include -#include "proc.h" - -#define END_OF_KMESS -1 -FORWARD _PROTOTYPE(void kputc, (int c)); -FORWARD _PROTOTYPE( void ser_putc, (char c)); /*===========================================================================* * panic * @@ -45,127 +25,3 @@ int nr; /* Abort MINIX. */ prepare_shutdown(RBT_PANIC); } - -/*===========================================================================* - * kprintf * - *===========================================================================*/ -PUBLIC void kprintf(const char *fmt, ...) /* format to be printed */ -{ - int c; /* next character in fmt */ - int d; - unsigned long u; /* hold number argument */ - int base; /* base of number arg */ - int negative; /* print minus sign */ - static char x2c[] = "0123456789ABCDEF"; /* nr conversion table */ - char ascii[8 * sizeof(long) / 3 + 2]; /* string for ascii number */ - char *s; /* string to be printed */ - va_list argp; /* optional arguments */ - - va_start(argp, fmt); /* init variable arguments */ - - while((c=*fmt++) != 0) { - - if (c == '%') { /* expect format '%key' */ - negative = 0; /* (re)initialize */ - s = NULL; /* (re)initialize */ - switch(c = *fmt++) { /* determine what to do */ - - /* Known keys are %d, %u, %x, %s, and %%. This is easily extended - * with number types like %b and %o by providing a different base. - * Number type keys don't set a string to 's', but use the general - * conversion after the switch statement. - */ - case 'd': /* output decimal */ - d = va_arg(argp, signed int); - if (d < 0) { negative = 1; u = -d; } else { u = d; } - base = 10; - break; - case 'u': /* output unsigned long */ - u = va_arg(argp, unsigned long); - base = 10; - break; - case 'x': /* output hexadecimal */ - u = va_arg(argp, unsigned long); - base = 0x10; - break; - case 's': /* output string */ - s = va_arg(argp, char *); - if (s == NULL) s = "(null)"; - break; - case '%': /* output percent */ - s = "%"; - break; - - /* Unrecognized key. */ - default: /* echo back %key */ - s = "%?"; - s[1] = c; /* set unknown key */ - } - - /* Assume a number if no string is set. Convert to ascii. */ - if (s == NULL) { - s = ascii + sizeof(ascii)-1; - *s = 0; - do { *--s = x2c[(u % base)]; } /* work backwards */ - while ((u /= base) > 0); - } - - /* This is where the actual output for format "%key" is done. */ - if (negative) kputc('-'); /* print sign if negative */ - while(*s != 0) { kputc(*s++); } /* print string/ number */ - } - else { - kputc(c); /* print and continue */ - } - } - kputc(END_OF_KMESS); /* terminate output */ - va_end(argp); /* end variable arguments */ -} - -/*===========================================================================* - * kputc * - *===========================================================================*/ -PRIVATE void kputc(c) -int c; /* character to append */ -{ -/* Accumulate a single character for a kernel message. Send a notification - * to the output driver if an END_OF_KMESS is encountered. - */ - if (c != END_OF_KMESS) { - if (do_serial_debug) - ser_putc(c); - kmess.km_buf[kmess.km_next] = c; /* put normal char in buffer */ - if (kmess.km_size < KMESS_BUF_SIZE) - kmess.km_size += 1; - kmess.km_next = (kmess.km_next + 1) % KMESS_BUF_SIZE; - } else { - int p, outprocs[] = OUTPUT_PROCS_ARRAY; - for(p = 0; outprocs[p] != NONE; p++) { - if(isokprocn(outprocs[p]) && !isemptyn(outprocs[p])) { - send_sig(outprocs[p], SIGKMESS); - } - } - } -} - -#define COM1_BASE 0x3F8 -#define COM1_THR (COM1_BASE + 0) -#define LSR_THRE 0x20 -#define COM1_LSR (COM1_BASE + 5) - -PRIVATE void ser_putc(char c) -{ - int i; - int lsr, thr; - - return; - - lsr= COM1_LSR; - thr= COM1_THR; - for (i= 0; i<100000; i++) - { - if (inb(lsr) & LSR_THRE) - break; - } - outb(thr, c); -}