Mercurial > lcfOS
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"); } } }