changeset 34:8012221dd740

Fixes for uninitialized data. This causes problems on real machines
author windel
date Mon, 16 Jan 2012 13:46:06 +0100
parents d8185ddb6c7b
children bcb3b68c8147
files .hgignore cos/kernel/Makefile cos/kernel/goto64.asm cos/kernel/kernel.c cos/kernel/kernel.h cos/kernel/keyboard.c cos/kernel/mm.c cos/kernel/snprintf.c cos/kernel/task.c cos/kernel/timer.c
diffstat 10 files changed, 153 insertions(+), 184 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Sun Jan 15 13:39:49 2012 +0100
+++ b/.hgignore	Mon Jan 16 13:46:06 2012 +0100
@@ -6,4 +6,6 @@
 *.bin
 
 cos/bootdisk.img
+cos/lcfosinitrd.img
+cos/kernel/kernel.map
 
--- a/cos/kernel/Makefile	Sun Jan 15 13:39:49 2012 +0100
+++ b/cos/kernel/Makefile	Mon Jan 16 13:46:06 2012 +0100
@@ -4,14 +4,14 @@
 
 CRT0 = goto64.o
 
-CFLAGS = -m64 -nostdinc	-nostdlib -nostartfiles -mno-red-zone \
+CFLAGS = -g -m64 -nostdinc	-nostdlib -nostartfiles -mno-red-zone \
 	-fno-builtin -mcmodel=large -Wall -Wextra -Werror
 
 OBJECTS = video.o snprintf.o kernel.o asmcode.o handlers.o keyboard.o \
 			klib.o malloc.o task.o mm.o timer.o fs.o initrd.o
 
 lcfos.bin: $(CRT0) $(OBJECTS) link.ld
-	ld -M -T link.ld -s -o lcfos.bin $(CRT0) $(OBJECTS)
+	ld -g -T link.ld -s --cref -Map=kernel.map -o lcfos.bin $(CRT0) $(OBJECTS)
 
 %.o : %.asm
 	nasm -f elf64 -o $@ $<
--- a/cos/kernel/goto64.asm	Sun Jan 15 13:39:49 2012 +0100
+++ b/cos/kernel/goto64.asm	Mon Jan 16 13:46:06 2012 +0100
@@ -97,6 +97,8 @@
 ; here ebx contains the pointer to the multiboot header, store is for later use.
 extern multiboot_info
 mov [multiboot_info], ebx
+xor ebx, ebx
+mov [multiboot_info + 4], ebx ; zero the rest of 64 bits address.
 
 ; Check that the CPU supports long mode:
 mov eax, 80000000h
--- a/cos/kernel/kernel.c	Sun Jan 15 13:39:49 2012 +0100
+++ b/cos/kernel/kernel.c	Mon Jan 16 13:46:06 2012 +0100
@@ -21,31 +21,25 @@
  * */
 void kmain()
 {
+   // No kmalloc required here yet:
    init_screen();
    setupIDT();
-
-   uint64_t available_memory = 0;
-
-   printf("Running with %d MB ram\n", available_memory / 1000000);
-
-   printf("Detecting amount of memory\n");
+   keyboard_init();
+   timer_init();
 
-   printf("Grub multiboot header location: %x\n", multiboot_info);
-   // On real hardware, the retrieval of the flags fails into general protection fault??
-   
-   printf("Grub lower mem: %d\n", multiboot_info->mem_lower);
-   printf("Grub multiboot header flags: %x\n", multiboot_info->flags);
-
-   /* Display memory information from multiboot header */
+   /* Retrieve memory information from multiboot header */
+   uint64_t available_memory = 0;
    if ((multiboot_info->flags & (1<<6)) == (1<<6))
    {
-      printf("Found GRUB memory map\n");
       multiboot_memory_map_t *mmap;
       for (mmap = (multiboot_memory_map_t*)(uint64_t)multiboot_info->mmap_addr; 
             (uint64_t)mmap < multiboot_info->mmap_addr + multiboot_info->mmap_length; 
             mmap = (multiboot_memory_map_t*) ( (uint64_t)mmap + mmap->size + sizeof(mmap->size)) )
       {
-         printf("size: %d, start: 0x%x, length=0x%x, type=%d\n", mmap->size, mmap->base, mmap->length, mmap->type);
+         /*
+         printf("size: %d, start: 0x%x, length=0x%x, type=%d\n", mmap->size, 
+            mmap->base, mmap->length, mmap->type);
+         */
 
          if ( (mmap->type == 1) && (mmap->base == 0x100000) )
          {
@@ -55,13 +49,13 @@
    }
    else
    {
-      printf("Found no GRUB map\n");
+      panic("Found no GRUB memory map\n");
    }
 
    printf("Running with %d MB ram\n", available_memory / 1000000);
 
+   /*
    fs_node_t *fs_root = 0;
-
    if ( (multiboot_info->flags & (1<<3)) == (1<<3))
    {
       printf("Mod count: %d\n", multiboot_info->mods_count);
@@ -75,6 +69,8 @@
             uint64_t ramdisk_location = ((uint32_t*)((uint64_t)multiboot_info->mods_addr))[0];
             fs_root = initialize_initrd(ramdisk_location);
          }
+         // TODO: Make sure that placement malloc does not overwrite the ramdisk.
+         printf("Mod size: %d", mod->mod_end - mod->mod_start);
       }
    }
    
@@ -87,9 +83,7 @@
 
       }
    }
-
-   // TODO: Make sure that placement malloc does not overwrite the ramdisk.
-   printf("Mod size: ");
+   */
 
    // Assume first 16MB:
    // TODO: get size from grub
@@ -98,8 +92,7 @@
    // TODO: make below a user space program!
    printf("Welcome!\n");
 
-
-  while (1==1) 
+  while (1) 
   {
     char buffer[70];
     printf(">");
--- a/cos/kernel/kernel.h	Sun Jan 15 13:39:49 2012 +0100
+++ b/cos/kernel/kernel.h	Mon Jan 16 13:46:06 2012 +0100
@@ -11,6 +11,13 @@
 typedef unsigned short      uint16_t;
 typedef unsigned int        uint32_t;
 typedef unsigned long int   uint64_t;
+typedef long int            int64_t;
+
+_Static_assert(sizeof(uint8_t) == 1, "sizeof(uint8_t) != 1");
+_Static_assert(sizeof(uint16_t) == 2, "sizeof(uint16_t) != 2");
+_Static_assert(sizeof(uint32_t) == 4, "sizeof(uint32_t) != 4");
+_Static_assert(sizeof(uint64_t) == 8, "sizeof(uint64_t) != 8");
+_Static_assert(sizeof(int64_t) == 8, "sizeof(int64_t) != 8");
 
 // IDT related structures:
 typedef struct {
@@ -315,10 +322,12 @@
 // Keyboard driver:
 void keyboardDriverUpdate(void);
 void getline(char *buffer, int len);
+void keyboard_init(void);
 
 // Timer:
 void timerDriverUpdate(void);
 uint64_t getTimeMS();
+void timer_init(void);
 
 #endif
 
--- a/cos/kernel/keyboard.c	Sun Jan 15 13:39:49 2012 +0100
+++ b/cos/kernel/keyboard.c	Mon Jan 16 13:46:06 2012 +0100
@@ -31,6 +31,12 @@
   '?','?','?','?', '?', '?', '?','?', '?', '?','?', '?', '?','?', '?', '?'
 };
 
+void keyboard_init()
+{
+   shiftstate = 0;
+   charAvail = 0;
+}
+
 void keyboardDriverUpdate()
 {
   unsigned char scancode = inb(0x60);
--- a/cos/kernel/mm.c	Sun Jan 15 13:39:49 2012 +0100
+++ b/cos/kernel/mm.c	Mon Jan 16 13:46:06 2012 +0100
@@ -124,7 +124,6 @@
 void switch_mapping(memmap_t* mapping)
 {
    current_map = mapping;
-   printf("Switching to use of other at %x\n", &mapping->table);
 
    asm volatile("mov %0, %%cr3" :: "r"(&mapping->table));
 
--- a/cos/kernel/snprintf.c	Sun Jan 15 13:39:49 2012 +0100
+++ b/cos/kernel/snprintf.c	Mon Jan 16 13:46:06 2012 +0100
@@ -17,7 +17,6 @@
 #define _X	0x40	/* hex digit */
 #define _SP	0x80	/* hard space (0x20) */
 
-
 uint8_t _ctype[] = {
 _C,_C,_C,_C,_C,_C,_C,_C,			/* 0-7 */
 _C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,		/* 8-15 */
@@ -64,7 +63,7 @@
 static inline uint8_t tolower(uint8_t c)
 {
 	if (isupper(c))
-		c -= 'A'-'a';
+		c += 'a'-'A';
 	return c;
 }
 
@@ -83,166 +82,127 @@
     '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
 };
 
+/* string print function. Supports the formats:
+  %p, %x: 64 bits hex number
+  %d: signed integer
+  %u: unsigned integer
+*/
 void va_snprintf(char *b, int l, const char *fmt, va_list pvar)
 {
-    int n, i;
-    uint32_t u;
-    uint64_t ull;
-    char *t;
-    char d[10];
-    char mod_l;
-    char mod_ll;
-
-    if (!fmt || !b || (l < 1))
-	return;
-
-    mod_l = 0;
-    mod_ll = 0;
-
-    while (l && *fmt) {
-      if (*fmt == '%') {
-          if (!(--l))
-         break;
-        again:
-          fmt++;
-
-          switch (*fmt) {
-          case '.':		/* precision modifier */
-         while(isdigit(fmt[1]))
-            fmt++;
-         goto again;
-
-          case 'l':		/* long modifier */
-         if (!mod_l) {
-             mod_l = 1;
-         } else if (!mod_ll) {
-             mod_l = 0;
-             mod_ll = 1;
-         }
-         goto again;
-
-          case 's':		/* string */
-         t = va_arg(pvar, char *);
-         while (l && *t)
-             *b++ = *t++, l--;
-         break;
-
-          case 'c':		/* single character */
-         *b++ = (char)va_arg(pvar, int);
-         l--;
-         break;
+   int i;
+   int64_t s64;
+   uint64_t u64;
+   char *t;
+   char d[20]; // For storing the decimal value in chars.
 
-          case 'S':		/* uint32 as a short ... */
-         if (l < 4) {
-             l = 0;
-             break;
-         }
-         u = va_arg(pvar, unsigned int);
-         for (i = 3; i >= 0; i--) {
-             b[i] = hexmap[u & 0x0F];
-             u >>= 4;
-         }
-         b += 4;
-         l -= 4;
-         break;
+   if ((fmt == 0) || (b == 0) || (l < 1))
+   {
+	   return;
+   }
 
-          case 'x':
-          case 'p':
-         if (!mod_ll) {	/* 8 digit, unsigned 32-bit hex integer */
-             if (l < 8) {
-            l = 0;
-            break;
-             }
-             u = va_arg(pvar, unsigned int);
-             for (i = 7; i >= 0; i--) {
-            b[i] = hexmap[u & 0x0F];
-            u >>= 4;
-             }
-             b += 8;
-             l -= 8;
-         } else if (mod_ll) {	/* 16 digit, unsigned 64-bit hex integer */
-             if (l < 16) {
-            l = 0;
-            break;
-             }
-             ull = va_arg(pvar, uint64_t);
-             for (i = 15; i >= 0; i--) {
-            b[i] = hexmap[ull & 0x0f];
-            ull >>= 4;
-             }
-             b += 16;
-             l -= 16;
-         }
-         mod_l = mod_ll = 0;
-         break;
-
-          case 'd':		/* signed integer */
-         n = va_arg(pvar, int);
-         if (n < 0) {
-             u = -n;
-             *b++ = '-';
-             if (!(--l))
-            break;
-         } else {
-             u = n;
-         }
-         goto u2;
-
-          case 'u':		/* unsigned integer */
-         u = va_arg(pvar, unsigned int);
-            u2:
-         i = 9;
-         do {
-             d[i] = (u % 10) + '0';
-             u /= 10;
-             i--;
-         }
-         while (u && i >= 0);
-         while (++i < 10) {
-             *b++ = d[i];
-             if (!(--l))
+   while ((l > 0) && (*fmt != 0))
+   {
+      if (*fmt == '%') 
+      {
+         if ((--l) == 0)
+         {
             break;
          }
-         break;
+
+         fmt++;
+         switch (*fmt) 
+         {
+            case 's':		/* string */
+               t = va_arg(pvar, char *);
+               while ((l > 0) && (*t != 0))
+               {
+                   *b++ = *t++;
+                   l--;
+               }
+               break;
+
+            case 'c':		/* single character */
+               *b++ = (char)va_arg(pvar, int);
+               l--;
+               break;
+
+            case 'x':
+            case 'p':
+               /* Pointer and hex uint64_t */
+               /* 16 digit, unsigned 64-bit hex integer */
+               if (l < 18) 
+               {
+                  l = 0;
+                  break;
+               }
+
+               *b++ = '0';
+               *b++ = 'x';
+
+               u64 = va_arg(pvar, uint64_t);
+               for (i = 15; i >= 0; i--)
+               {
+                  b[i] = hexmap[u64 & 0x0f];
+                  u64 >>= 4;
+               }
+               b += 16;
+               l -= 16;
+               break;
 
-          case 'U':
-         u = va_arg(pvar, unsigned int);
-         i = 9;
-         d[8] = d[7] = d[6] = ' ';
-         do {
-             d[i] = (u % 10) + '0';
-             u /= 10;
-             i--;
+            case 'd':		/* signed integer */
+               s64 = va_arg(pvar, int);
+               if (s64 < 0) 
+               {
+                  u64 = (uint64_t)(-s64);
+                  *b++ = '-';
+                  if ((--l) == 0)
+                  {
+                     break;
+                  }
+               }
+               else 
+               {
+                  u64 = s64;
+               }
+               goto u2;
+
+            case 'u':		/* unsigned integer */
+               u64 = va_arg(pvar, unsigned int);
+               u2:
+               i = 19;
+               do 
+               {
+                   d[i] = (u64 % 10) + '0';
+                   u64 /= 10;
+                   i--;
+               }
+               while ((u64 != 0) && (i >= 0));
+
+               // Now print the characters:
+               while (++i < 20)
+               {
+                  *b++ = d[i];
+                  if ((--l) == 0)
+                  {
+                     break;
+                  }
+               }
+               break;
+
+            default:
+               *b++ = *fmt;
          }
-         while (u && i >= 0);
-         i = 5;
-         while (++i < 10) {
-             *b++ = d[i];
-             if (!(--l))
-            break;
-         }
-         break;
-
-          case 'X':		/* 2 digit, unsigned 8bit hex int */
-         if (l < 2) {
-             l = 0;
-             break;
-         }
-         n = va_arg(pvar, int);
-         *b++ = hexmap[(n & 0xF0) >> 4];
-         *b++ = hexmap[n & 0x0F];
-         l -= 2;
-         break;
-          default:
-         *b++ = *fmt;
-          }
-      } else {
+      } 
+      else 
+      {
           *b++ = *fmt;
           l--;
       }
+
       fmt++;
-    }
-    *b = 0;
+   }
+
+   *b = 0; // Add a 0 terminate
 }
 
 void snprintf(char *str, int len, char *fmt, ...)
@@ -254,15 +214,6 @@
 }
 
 void
-sprintf(char *dst, const char *fmt, ...)
-{
-    va_list args;
-    va_start(args, fmt);
-    va_snprintf(dst, MORE_THAN_YOU_WANT, fmt, args);
-    va_end(args);
-}
-
-void
 printf(const char* fmt, ...)
 {
     static char buf[MAX_STDOUT_CHARS];
--- a/cos/kernel/task.c	Sun Jan 15 13:39:49 2012 +0100
+++ b/cos/kernel/task.c	Mon Jan 16 13:46:06 2012 +0100
@@ -71,6 +71,8 @@
 */
 void task_scheduler()
 {
+   return;
+
    if (current_task == 0)
    {
       return;
--- a/cos/kernel/timer.c	Sun Jan 15 13:39:49 2012 +0100
+++ b/cos/kernel/timer.c	Mon Jan 16 13:46:06 2012 +0100
@@ -13,3 +13,8 @@
   return 55*ticks;
 }
 
+void timer_init()
+{
+   ticks = 0;
+}
+