view cos/kernel/kernel.c @ 23:5dd47d6eebac

Added ubersimple malloc algorithm
author windel
date Thu, 01 Dec 2011 21:42:59 +0100
parents 69bc6d477b38
children d8627924d40d
line wrap: on
line source

#include "kernel.h"

static int shiftstate = 0;
static volatile uint8_t charAvail = 0;
static volatile char kbdchar = ' ';

static char keymap[128] = {
  '?','?','1','2', '3', '4', '5','6', '7', '8','9', '0', '-','=', 0xe, '?',
  'q','w','e','r', 't', 'y', 'u','i', 'o', 'p','[', ']', '\n','?', 'a', 's',
  'd','f','g','h', 'j', 'k', 'l',';', '\'', '?','?', '?', 'z','x', 'c', 'v',
  'b','n','m',',', '.', '/', '?','?', '?', ' ','?', '?', '?','?', '?', '?',

  '?','?','?','?', '?', '?', '?','?', '?', '?','?', '?', '?','?', '?', '?',
  '?','?','?','?', '?', '?', '?','?', '?', '?','?', '?', '?','?', '?', '?',
  '?','?','?','?', '?', '?', '?','?', '?', '?','?', '?', '?','?', '?', '?',
  '?','?','?','?', '?', '?', '?','?', '?', '?','?', '?', '?','?', '?', '?'
};

static char keymapUPPER[128] = {
  '?','?','!','@', '#', '$', '%','^', '&', '*','(', ')', '_','+', '?', '?',
  'Q','W','E','R', 'T', 'Y', 'U','I', 'O', 'P','{', '}', '|','?', 'A', 'S',
  'D','F','G','H', 'J', 'K', 'L',':', '"', '?','?', '?', 'Z','X', 'C', 'V',
  'B','N','M','<', '>', '?', '?','?', '?', ' ','?', '?', '?','?', '?', '?',

  '?','?','?','?', '?', '?', '?','?', '?', '?','?', '?', '?','?', '?', '?',
  '?','?','?','?', '?', '?', '?','?', '?', '?','?', '?', '?','?', '?', '?',
  '?','?','?','?', '?', '?', '?','?', '?', '?','?', '?', '?','?', '?', '?',
  '?','?','?','?', '?', '?', '?','?', '?', '?','?', '?', '?','?', '?', '?'
};

// IO port helpers:
void outb(uint16_t port, uint8_t value)
{
   asm volatile ("outb %1, %0" : : "dN" (port), "a" (value));
}

uint8_t inb(uint16_t port)
{
   uint8_t ret;
   asm volatile ("inb %1, %0" : "=a" (ret) : "dN" (port));
   return ret;
}

uint16_t inw(uint16_t port)
{
   uint16_t ret;
   asm volatile ("inw %1, %0" : "=a" (ret) : "dN" (port));
   return ret;
}


static uint64_t ticks = 0;
void timerDriverUpdate()
{
  ticks++;
}

uint64_t getTimeMS()
{
  return 55*ticks;
}

int strncmp(const char* s1, const char* s2, int size) {
  int i;
  for (i=0; i<size; i++) {
    if (s1[i] != s2[i]) return 0;
  }
  return 1;
}

void keyboardDriverUpdate(unsigned char scancode)
{
  switch(scancode) {
    case 0x2a:
      shiftstate = 1;
      break;
    case 0xaa:
      shiftstate = 0;
      break;
    default:
      if (scancode < 128) {
        if (charAvail == 0) {
          if (shiftstate == 0) {
            kbdchar = keymap[scancode];
          } else {
            kbdchar = keymapUPPER[scancode];
          }
          
          charAvail = 1;
        }
      } else {
        // Key release
        //printf("Unhandled scancode: 0x%x\n", scancode);
      }
      break;
  }
}

char getChar() {
  while (charAvail == 0);
  char c = kbdchar;
  charAvail = 0;
  return c;
}

void getline(char *buffer, int len) {
  char c;
  int i = 0;
  while (i < len-1) {
    c = getChar();
    if (c == '\n') {
      // Enter
      break;
    }
    if (c == 0x0e) {
      if (i>0) {
         printf(" ");
         i--;
      }
      continue;
    }
    buffer[i] = c;
    printf("%c", c);
    i++;
  }
  buffer[i] = 0;
}

#define HEAP_MAGIC 0xc0ffee
#define HEAP_START 0x400000
#define HEAP_SIZE  0x200000
#define HEAP_INUSE 1
#define HEAP_FREE 0

typedef struct {
   uint64_t magic;
   uint64_t state;
   uint64_t size;
} heap_t;

/*
  malloc and free divide the chunks of memory present at the heap
  of the kernel into smaller parts.
  The heap is located at: 0x
*/
static heap_t* kernel_heap = (heap_t*) 0x400000; // 4 MB - 6 MB is heap
/* Allocates 'size' bytes and returns the pointer if succesfull.
   Kernelpanic in case of failure..
*/

void* kmalloc(uint64_t size) {
   // printf("Malloc %d bytes\n", size);

   // Start at the beginning of our heap and search a free block:
   heap_t *current = kernel_heap;
   while (current->magic == HEAP_MAGIC)
   {
      if ((current->state == HEAP_FREE) && (current->size >= size))
      {
         // Mark block as used:
         current->state = HEAP_INUSE;

         // Insert a heap header if required:
         if (current->size > size + sizeof(heap_t) + 1)
         {
            // Calculate location of the inserted header:
            heap_t *newheader = (heap_t*) (((char*)current)+size+sizeof(heap_t));

            // Set the new header fields:
            newheader->size = current->size - size - sizeof(heap_t);
            newheader->state = HEAP_FREE;
            newheader->magic = HEAP_MAGIC;

            // Set the size of this block
            current->size = size; 
         }
         else
         {
            // We allocate this whole block
         }
         // Calculate the size of the block:
         char *address = ((char*)current)+sizeof(heap_t);
         return address;
         
      }
      // Goto next heap block:
      current = (heap_t*)(((char*) current) + current->size + sizeof(heap_t));
   }
   return 0x0;
}

void kfree(void* ptr) {
  printf("Free address %x\n", ptr);
}

void init_heap(void)
{
   // Initialize the kernel heap:
   kernel_heap->magic = HEAP_MAGIC;
   kernel_heap->state = HEAP_FREE;
   kernel_heap->size = HEAP_SIZE - sizeof(heap_t);
}

void startPython()
{
   // TODO: connect to Py_Main
   //PyRun_SimpleString("print('hello world')");

}

void testMalloc()
{
   char *a, *b;

   printf("Testing malloc\n");
   a = kmalloc(100);
   printf("Got a at %x\n", a);
   a[0] = 'A';
   b = kmalloc(22);
   printf("Got b at %x\n", b);
   b[0] = 'B';
   kfree(a);
}

void kmain()
{
  init_screen();
  setupIDT();
  init_heap();

  printf("Welcome!\n");

  while (1==1) 
  {
    char buffer[70];
    printf(">>>");
    getline(buffer, 70);
    // TODO: interpret this line with python :)
    printf("\n");
    printf("Got line: '%s'\n", buffer);
    if (buffer[0] == 'x') 
    {
      printf("System time in ms: %d\n", getTimeMS());
    }
    if (buffer[0] == 't')
    {
        testMalloc();
    }
    if ( strncmp(buffer, "help", 4)) 
    {
      printf("Help\n Try one of these commands:\n");
      printf(" x: print system time in ms\n");
    }
  }
}