diff --git a/kernel/arch/i386/crti.S b/kernel/arch/i386/crti.S deleted file mode 100644 index cebea3e..0000000 --- a/kernel/arch/i386/crti.S +++ /dev/null @@ -1,15 +0,0 @@ -.section .init -.global _init -.type _init, @function -_init: - push %ebp - movl %esp, %ebp - /* gcc will nicely put the contents of crtbegin.o's .init section here. */ - -.section .fini -.global _fini -.type _fini, @function -_fini: - push %ebp - movl %esp, %ebp - /* gcc will nicely put the contents of crtbegin.o's .fini section here. */ diff --git a/kernel/arch/i386/crtn.S b/kernel/arch/i386/crtn.S deleted file mode 100644 index 33957bf..0000000 --- a/kernel/arch/i386/crtn.S +++ /dev/null @@ -1,9 +0,0 @@ -.section .init - /* gcc will nicely put the contents of crtend.o's .init section here. */ - popl %ebp - ret - -.section .fini - /* gcc will nicely put the contents of crtend.o's .fini section here. */ - popl %ebp - ret diff --git a/kernel/arch/i386/include/paging.h b/kernel/arch/i386/include/paging.h deleted file mode 100644 index 05469f7..0000000 --- a/kernel/arch/i386/include/paging.h +++ /dev/null @@ -1,129 +0,0 @@ -/* Paging driver header - * - * Copyright (c) 2015 Feraru Mihail (mihailferaru2000@gmail.com). - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * Contains declarations of functions for paging driver and paging structures. - * paging is one of the memory management schemes by which a computer stores - * and retrieves data from the secondary storage for use in main memory. - * Structures: - * - page: structure used to store details about a block of memory - * - page table: structure used to store 1024 pages - * - page directory: structure used to store 1024 page entries and their - * physical addresses, in addition it stores physical address that will be loaded - * into CR3. - */ - -#ifndef _paging_h -#define _paging_h - -#include -#include -#include -#include - -typedef struct page -{ - uint32_t present : 1; // Page present in memory - uint32_t rw : 1; // Read-only if clear, read write if set - uint32_t user : 1; // Supervisor level only if clear - uint32_t accessed : 1; // Has the page been accessed since last refresh? - uint32_t dirty : 1; // Has the page been written to since last refresh? - uint32_t unused : 7; // Amalgamation of unused and reserved bits - uint32_t frame : 20; // Frame address (shifted right 12 bits) -} page_t; - -typedef struct page_table -{ - page_t pages[1024]; -} page_table_t; - -typedef struct page_directory -{ - page_table_t *tables[1024]; - uint32_t tablesPhysical[1024]; - uint32_t physicalAddr; -} page_directory_t; - -page_directory_t *kernel_directory; -page_directory_t *current_directory; -uint32_t mem_size_mb; -uint32_t mem_size_kb; - -extern void copy_page_physical(uint32_t src_frame, uint32_t dest_frame); -extern void flush_tlb(); - -/** - * Initialize paging. - */ -void init_paging(); - -/** - * Switch current page directory and load it. - */ -void switch_page_directory(page_directory_t *dir); - -/** - * It does what it does. :))) - */ -void enable_paging(); - -/** - * Get a free page. - */ -page_t *get_page(uint32_t address, int make, page_directory_t *dir); - -/** - * Page fault handler. - */ -void page_fault(registers_t *regs); - -/** - * Set frame bit. - */ -void set_frame(uint32_t frame_addr); - -/** - * Clear frame. - */ -void clear_frame(uint32_t frame_addr); - -/** - * Test the frame. - */ -uint32_t test_frame(uint32_t frame_addr); - -/** - * First free frame. - */ -uint32_t first_frame(); - -/** - * Alloc first free frame to page. - */ -void alloc_frame(page_t *page, int is_kernel, int is_writeable); - -/** - * Free frame from page. - */ -void free_frame(page_t *page); - -/** - * Copy data from a directory and return it as a pointer to a directory allocated on the heap. - */ -page_directory_t *clone_directory(page_directory_t *src); - -/** - * Copy data from a page and return it. - */ -page_table_t *clone_table(page_table_t *src, uint32_t *physAddr); - -/** - * Simply move the stack... - */ -void move_stack(void *new_stack, uint32_t size); - -#endif diff --git a/kernel/arch/i386/linker.ld b/kernel/arch/i386/linker.ld deleted file mode 100644 index cf4a39e..0000000 --- a/kernel/arch/i386/linker.ld +++ /dev/null @@ -1,32 +0,0 @@ -ENTRY(_start) - -SECTIONS -{ - . = 1M; - kernel_start = .; - - .text BLOCK(4K) : ALIGN(4K) - { - *(.multiboot) - *(.text) - } - - .rodata BLOCK(4K) : ALIGN(4K) - { - *(.rodata) - } - - .data BLOCK(4K) : ALIGN(4K) - { - *(.data) - } - - .bss BLOCK(4K) : ALIGN(4K) - { - *(COMMON) - *(.bss) - *(.bootstrap_stack) - } - - kernel_end = .; -} diff --git a/kernel/arch/i386/page.asm b/kernel/arch/i386/page.asm deleted file mode 100644 index 8a4131d..0000000 --- a/kernel/arch/i386/page.asm +++ /dev/null @@ -1,40 +0,0 @@ -[GLOBAL copy_page_physical] - -copy_page_physical: - push ebx - pushf - - cli - - mov ebx, [esp+12] - mov ecx, [esp+16] - - mov edx, cr0 - and edx, 0x7fffffff - mov cr0, edx - - mov edx, 1024 - - .loop: - mov eax, [ebx] - mov [ecx], eax - add ebx, 4 - add ecx, 4 - dec edx - jnz .loop - - mov edx, cr0 - or edx, 0x80000000 - mov cr0, edx - - popf - pop ebx - ret - -[GLOBAL flush_tlb] - -flush_tlb: - push ebx - mov cr3, ebx - mov ebx, cr3 - pop ebx diff --git a/kernel/arch/i386/paging.c b/kernel/arch/i386/paging.c deleted file mode 100644 index 525868a..0000000 --- a/kernel/arch/i386/paging.c +++ /dev/null @@ -1,269 +0,0 @@ -/* Paging driver - * - * Copyright (c) 2015 Feraru Mihail (mihailferaru2000@gmail.com). - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -uint32_t *frames; -uint32_t nframes; - -void set_frame(uint32_t frame_addr) -{ - uint32_t frame = frame_addr / 0x1000; - uint32_t idx = INDEX_FROM_BIT(frame); - uint32_t off = OFFSET_FROM_BIT(frame); - frames[idx] |= (0x1 << off); -} - -void clear_frame(uint32_t frame_addr) -{ - uint32_t frame = frame_addr / 0x1000; - uint32_t idx = INDEX_FROM_BIT(frame); - uint32_t off = OFFSET_FROM_BIT(frame); - frames[idx] &= ~(0x1 << off); -} - -uint32_t test_frame(uint32_t frame_addr) -{ - uint32_t frame = frame_addr / 0x1000; - uint32_t idx = INDEX_FROM_BIT(frame); - uint32_t off = INDEX_FROM_BIT(frame); - return (frames[idx] & (0x1 << off)); -} - -uint32_t first_frame() -{ - uint32_t i, j; - for (i = 0; i < INDEX_FROM_BIT(nframes); i++) { - if (frames[i] != 0xFFFFFFFF) { - for (j = 0; j < 32; j++) { - uint32_t toTest = 0x1 << j; - if (!(frames[i] & toTest)) { - return i * 4 * 8 + j; - } - } - } - } - return -1; -} - -void alloc_frame(page_t *page, int is_kernel, int is_writeable) -{ - if (page->frame != 0) { - return; - } else { - uint32_t idx = first_frame(); - if (idx == (uint32_t)-1) { - panic("No free frames!", __LINE__, __FILE__); - } - set_frame(idx * 0x1000); - page->present = 1; - page->rw = (is_writeable)?1:0; - page->user = (is_kernel)?0:1; - page->frame = idx; - } -} - -void free_frame(page_t *page) -{ - uint32_t frame; - if (!(frame = page->frame)) { - return; - } else { - clear_frame(frame); - page->frame = 0x0; - } -} - -void init_paging(multiboot *mboot_ptr) -{ - placement_address = (size_t)&kernel_end; - kheap = NULL; - - uint32_t mem_in_mb = mboot_ptr->mem_upper / 1024 + 2; - uint32_t mem_in_kb = mem_in_mb * 1024; - - mem_size_mb = mem_in_mb; - mem_size_kb = mem_in_kb; - - nframes = mem_in_kb / 4; - frames = (uint32_t*)kmalloc(INDEX_FROM_BIT(nframes)); - memset(frames, 0, INDEX_FROM_BIT(nframes)); - - kernel_directory = (page_directory_t*)kmalloc_a(sizeof(page_directory_t)); - memset(kernel_directory, 0, sizeof(page_directory_t)); - kernel_directory->physicalAddr = (uint32_t) kernel_directory->tablesPhysical; - - unsigned int i = 0; - for (i = KHEAP_START; i < KHEAP_START + KHEAP_INIT_SIZE; i += 0x1000) { - get_page(i, 1, kernel_directory); - } - - i = 0; - while (i < (size_t)&kernel_end + KHEAP_INIT_SIZE) { - alloc_frame(get_page(i, 1, kernel_directory), 0, 1); - i += 0x1000; - } - - for (i = KHEAP_START; i < KHEAP_START + KHEAP_INIT_SIZE; i += 0x1000) { - alloc_frame(get_page(i, 1, kernel_directory), 0, 1); - } - register_interrupt_handler(14, &page_fault); - current_directory = clone_directory(kernel_directory); - switch_page_directory(kernel_directory); - enable_paging(); - - kheap = create_heap(KHEAP_START, KHEAP_START + KHEAP_INIT_SIZE, 0xCFFFF000, 0, 0); -} - -void switch_page_directory(page_directory_t *dir) -{ - current_directory = dir; - asm volatile("mov %0, %%cr3":: "r"(&dir->tablesPhysical)); -} - -void enable_paging() -{ - uint32_t cr0; - asm volatile("mov %%cr0, %0": "=r"(cr0)); - cr0 |= 0x80000000; - asm volatile("mov %0, %%cr0":: "r"(cr0)); -} - -page_t *get_page(uint32_t address, int make, page_directory_t *dir) -{ - address /= 0x1000; - uint32_t table_idx = address / 1024; - if (dir->tables[table_idx]) { - return &dir->tables[table_idx]->pages[address % 1024]; - } else if (make) { - uint32_t tmp; - dir->tables[table_idx] = (page_table_t*)kmalloc_ap(sizeof(page_table_t), &tmp); - memset(dir->tables[table_idx], 0, 0x1000); - dir->tablesPhysical[table_idx] = tmp | 0x7; - return &dir->tables[table_idx]->pages[address % 1024]; - } else { - return 0; - } -} - -void page_fault(registers_t *regs) -{ - cli(); - print_regs(regs); - - printf("Kernel heap: %x\n", kheap); - - uint32_t fault_address; - asm volatile("mov %%cr2, %0" : "=r" (fault_address)); - - // The error code gives us details of what happened. - int present = !(regs->err_code & 0x1); // Page not present - int rw = regs->err_code & 0x2; // Write operation? - int us = regs->err_code & 0x4; // Processor was in user-mode? - int reserved = regs->err_code & 0x8; // Overwritten CPU-reserved bits of page entry? - int id = regs->err_code & 0x10; // Caused by an instruction fetch? - - printf("Page fault at %x! Id = %x ( ", fault_address, id); - if (present) printf("present "); - if (rw) printf("read-only "); - if (us) printf("user-mode "); - if (reserved) printf("reserved "); - printf(")\n"); - panic("Core dumped.", __LINE__, __FILE__); -} - -page_directory_t *clone_directory(page_directory_t *src) -{ - uint32_t phys; - page_directory_t *dir = (page_directory_t*) kmalloc_ap(sizeof(page_directory_t), &phys); - memset(dir, 0, sizeof(page_directory_t)); - - uint32_t offset = (uint32_t) dir->tablesPhysical - (uint32_t) dir; - dir->physicalAddr = phys + offset; - - int i; - for (i = 0; i < 1024; i++) { - if (!src->tables[i]) - continue; - - if (kernel_directory->tables[i] == src->tables[i]) { - dir->tables[i] = src->tables[i]; - dir->tablesPhysical[i] = src->tablesPhysical[i]; - } else { - uint32_t page_phys; - dir->tables[i] = clone_table((src->tables), &page_phys); - dir->tablesPhysical[i] = page_phys | 0x07; - } - } - return dir; -} - -page_table_t *clone_table(page_table_t *src, uint32_t *physAddr) -{ - page_table_t *table = (page_table_t*) kmalloc_ap(sizeof(page_table_t), physAddr); - memset(table, 0, sizeof(page_table_t)); - - int i; - for (i = 0; i < 1024; i++) { - if (!src->pages[i].frame) - continue; - alloc_frame(&table->pages[i], 0, 0); - if (src->pages[i].present) - table->pages[i].present = 1; - if (src->pages[i].rw) - table->pages[i].rw = 1; - if (src->pages[i].user) - table->pages[i].user = 1; - if (src->pages[i].accessed) - table->pages[i].accessed = 1; - if (src->pages[i].dirty) - table->pages[i].dirty = 1; - - copy_page_physical(src->pages[i].frame * 0x1000, table->pages[i].frame * 0x1000); - } - return table; -} - -void move_stack(void *new_stack, uint32_t size) -{ - for (uint32_t i = (uint32_t) new_stack; i >= (uint32_t) new_stack - size; i -= 0x1000) { - alloc_frame(get_page(i, 1, current_directory), 0, 1); - } - flush_tlb(); - - uint32_t old_stack_pointer; - asm volatile("mov %%esp, %0" : "=r" (old_stack_pointer)); - uint32_t old_base_pointer; - asm volatile("mov %%ebp, %0" : "=r" (old_base_pointer)); - - uint32_t stack_offset = (uint32_t) new_stack - init_esp; - uint32_t new_stack_pointer = old_stack_pointer + stack_offset; - uint32_t new_base_pointer = old_base_pointer + stack_offset; - - memcpy((void*) new_stack_pointer, (void*) old_stack_pointer, init_esp - old_stack_pointer); - - for(uint32_t i = (uint32_t) new_stack; i > (uint32_t) new_stack - size; i -= 4) { - uint32_t tmp = *(uint32_t*) i; - if (( old_stack_pointer < tmp) && (tmp < init_esp)) { - tmp = tmp + stack_offset; - uint32_t *tmp2 = (uint32_t*) i; - *tmp2 = tmp; - } - } - - asm volatile("mov %0, %%esp" : : "r" (new_stack_pointer)); - asm volatile("mov %0, %%ebp" : : "r" (new_base_pointer)); -} diff --git a/kernel/drivers/io.c b/kernel/drivers/io.c deleted file mode 100644 index 019efcf..0000000 --- a/kernel/drivers/io.c +++ /dev/null @@ -1,163 +0,0 @@ -/* Basic input/output - * - * Copyright (c) 2015 Feraru Mihail (mihailferaru2000@gmail.com). - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* output byte */ -void outb(uint32_t ad, uint8_t v) -{ - asm volatile("outb %%al, %%dx" :: "d" (ad), "a" (v));; -} -/* output word */ -void outw(uint32_t ad, uint16_t v) -{ - asm volatile("outw %%ax, %%dx" :: "d" (ad), "a" (v)); -} -/* output word */ -void outl(uint32_t ad, uint32_t v) -{ - asm volatile("outl %%eax, %%dx" : : "d" (ad), "a" (v)); -} -/* input byte */ -uint8_t inb(uint32_t ad) -{ - uint8_t _v; - asm volatile("inb %%dx, %%al" : "=a" (_v) : "d" (ad)); - return _v; -} -/* input word */ -uint16_t inw(uint32_t ad) -{ - uint16_t _v; - asm volatile("inw %%dx, %%ax" : "=a" (_v) : "d" (ad)); - return _v; -} -/* input word */ -uint32_t inl(uint32_t ad) -{ - uint32_t _v; - asm volatile("inl %%dx, %%eax" : "=a" (_v) : "d" (ad)); - return _v; -} - -void print_regs(registers_t *regs) -{ - printk("\nds: %d\tedi: %d\tesi: %d\n", regs->ds, regs->edi, regs->esi); - printk("ebp: %d\tesp: %d\tebx: %d\n", regs->ebp, regs->esp, regs->ebx); - printk("edx: %d\tecx: %d\teax: %d\n", regs->edx, regs->ecx, regs->eax); - printk("eip: %d\tcs: %d\teflags: %d\n", regs->eip, regs->cs, regs->eflags); - printk("useresp: %d\tss: %d\n", regs->useresp, regs->ss); - printk("int_no: %d\terr_code: %d\n\n", regs->int_no, regs->err_code); -} - -int write_char(const char c) -{ - //((unsigned char*) stdout)[out_crs] = c; - //out_crs++; - vga_putchar(c); - return 0; -} - -int write(const char *buf, size_t len) -{ - for ( size_t i = 0; i < len; i++ ) - write_char((int) ((const char*) buf)[i]); - return 0; -} - -int printk(const char* format, ...) -{ - va_list parameters; - va_start(parameters, format); - - int written = 0; - size_t amount; - bool rejected_bad_specifier = false; - - while ( *format != '\0' ) { - if ( *format != '%' ) { - print_c: - amount = 1; - while ( format[amount] && format[amount] != '%' ) - amount++; - write(format, amount); - format += amount; - written += amount; - continue; - } - - const char* format_begun_at = format; - - if ( *(++format) == '%' ) - goto print_c; - - if ( rejected_bad_specifier ) { - incomprehensible_conversion: - rejected_bad_specifier = true; - format = format_begun_at; - goto print_c; - } - if ( *format == 'c' ) { - format++; - char c = (char) va_arg(parameters, int /* char promotes to int */); - write(&c, sizeof(c)); - } else if ( *format == 's' ) { - format++; - const char* s = va_arg(parameters, const char*); - write(s, strlen(s)); - } else if ( *format == 'd' ) { - format++; - int n = va_arg(parameters, int); - if (n) { - char s[intlen(n, 10)]; - itoa(s, n, 10); - write(s, strlen(s)); - } else { - putchar('0'); - } - } else if ( *format == 'x') { - format++; - int n = va_arg(parameters, int); - if (n) { - char s[intlen(n, 16)]; - itoa(s, n, 16); - write(s, strlen(s)); - } else { - printk("0x0"); - } - } else { - goto incomprehensible_conversion; - } - } - - va_end(parameters); - return written; -} - -void call(int32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx, uint32_t esi, uint32_t edi) -{ - asm volatile (" \ - movl %0, %%eax; \ - movl %1, %%ebx; \ - movl %2, %%ecx; \ - movl %3, %%edx; \ - movl %4, %%esi; \ - movl %5, %%edi; \ - int $0x80; \ - " : : "r" (eax) , "r" (ebx) , "r" (ecx) , "r" (edx) , "r" (esi) , "r" (edi)); -} diff --git a/kernel/drivers/vga.c b/kernel/drivers/vga.c deleted file mode 100644 index e35f203..0000000 --- a/kernel/drivers/vga.c +++ /dev/null @@ -1,176 +0,0 @@ -/* VGA driver - * - * Copyright (c) 2015 Feraru Mihail (mihailferaru2000@gmail.com). - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#if !defined(__cplusplus) -#include /* C doesn't have booleans by default. */ -#endif -#include -#include -#include -#include - -uint16_t *vga_memory; -#ifdef _TEXTMODE -int tabstop; -size_t row; -size_t col; -enum vga_color default_bg = COLOR_BLACK; -enum vga_color default_fg = COLOR_LIGHT_GREY; - -uint8_t make_color(enum vga_color fg, enum vga_color bg) -{ - return fg | bg << 4; -} - -uint16_t make_vgaentry(char c, uint8_t color) -{ - uint16_t c16 = c; - uint16_t color16 = color; - return c16 | color16 << 8; -} -#endif - -void init_vga() -{ - #ifdef _TEXTMODE - vga_memory = (uint16_t*) 0xB8000; - row = 0; - col = 0; - tabstop = 4; - clear_vga(); - #endif -} - -void clear_vga() -{ - #ifdef _TEXTMODE - for ( size_t y = 0; y < VGA_HEIGHT; y++ ) - { - for ( size_t x = 0; x < VGA_WIDTH; x++ ) - { - const size_t index = y * VGA_WIDTH + x; - ((uint16_t*) vga_memory)[index] = make_vgaentry(' ', make_color(default_fg, default_bg)); - } - } - row = 0; - col = 0; - vga_move_cursor(row, col); - #endif -} - -int vga_scroll(size_t *row) -{ - #ifdef _TEXTMODE - uint16_t blank = make_vgaentry(' ', make_color(default_fg, default_bg)); - - if (*row >= 25) - { - int temp = *row - 25 + 1; - memcpy ((uint16_t*) vga_memory, (uint16_t*) vga_memory + temp * 80, (25 - temp) * 80 * 2); - - memsetw ((uint16_t*) vga_memory + (25 - temp) * 80, blank, 80); - *row = 24; - } - vga_move_cursor(row, col); - return 0; - #endif -} - -#ifdef _TEXTMODE -void vga_setcolor(enum vga_color fg, enum vga_color bg) -{ - default_bg = bg; - default_fg = fg; -} - -void vga_putentryat(char c, uint8_t color, size_t x, size_t y) -{ - const size_t index = y * VGA_WIDTH + x; - ((uint16_t*) vga_memory)[index] = make_vgaentry(c, color); -} -#endif - -void vga_putchar(char c) -{ - #ifdef _TEXTMODE - switch (c) { - case '\n': - row++; - col = -1; - break; - case '\t': - for (int i = 1; i < tabstop; i++) { - vga_putchar(' '); - } - break; - case '\b': - vga_putentryat(' ', make_color(default_fg, default_bg), --col, row); - --col; - break; - default: - vga_putentryat(c, make_color(default_fg, default_bg), col, row); - break; - } - if (++col >= 80) { - col = 0; - ++row; - } - vga_scroll(&row); - vga_move_cursor(row, col + 1); - #endif -} - -void vga_writestring(const char* data) -{ - #ifdef _TEXTMODE - size_t datalen = strlen(data); - for ( size_t i = 0; i < datalen; i++ ) - vga_putchar(data[i]); - #endif -} - -#ifdef _TEXTMODE -void vga_set_tab(int size) -{ - tabstop = size; -} - -void vga_move_cursor(int row, int column) -{ - uint16_t cursor_pos = row * 80 + column - 1; - outb(0x3D4, 14); - outb(0x3D5, cursor_pos >> 8); - outb(0x3D4, 15); - outb(0x3D5, cursor_pos); -} -#endif - -void vga_putchar_color(char c, enum vga_color fg) -{ - #ifdef _TEXTMODE - uint8_t temp_color = default_fg; - default_fg = fg; - vga_putchar(c); - default_fg = temp_color; - #endif -} - -void wstr_color(const char* data, enum vga_color fg) -{ - #ifdef _TEXTMODE - for ( size_t i = 0, n = strlen(data); i < n; i++ ) - vga_putchar_color((int) ((const unsigned char*) data)[i], fg); - #endif -} - -#ifndef _TEXTMODE -#error "Graphic Mode not ready!" -#endif diff --git a/kernel/include/icxxabi.h b/kernel/include/icxxabi.h deleted file mode 100644 index 802088a..0000000 --- a/kernel/include/icxxabi.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _ICXXABI_H - #define _ICXXABI_H - - #define ATEXIT_MAX_FUNCS 128 - - #ifdef __cplusplus - extern "C" { - #endif - -typedef unsigned uarch_t; - -struct atexit_func_entry_t -{ - /* - * Each member is at least 4 bytes large. Such that each entry is 12bytes. - * 128 * 12 = 1.5KB exact. - **/ - void (*destructor_func)(void *); - void *obj_ptr; - void *dso_handle; -}; - -int __cxa_atexit(void (*f)(void *), void *objptr, void *dso); -void __cxa_finalize(void *f); - - #ifdef __cplusplus - }; - #endif - -#endif diff --git a/kernel/include/init.h b/kernel/include/init.h deleted file mode 100644 index 9089351..0000000 --- a/kernel/include/init.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _init_h -#define _init_h - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define FREQ 100 -uint8_t *inbuffer; -char *outbuffer; - -/** - * Initialize standard i/o. - */ -void init_stdio(); - -/** - * Initialize all system. - */ -void init(multiboot *mboot_ptr, uint32_t init_stack); - -/** - * Print welcome screen. - */ -void welcome(); - -/** - * Log in to system. - */ -void login(); - -#endif diff --git a/kernel/include/kernel_class.h b/kernel/include/kernel_class.h deleted file mode 100644 index 8f88def..0000000 --- a/kernel/include/kernel_class.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _kernel_class_h -#define _kernel_class_h - -class KernelClass { - private: - int ID_number; - char version[30]; - char version_name[50]; - public: - KernelClass(); - ~KernelClass(); - void setID(int ID); - void setVersion(const char *version); - int getID(); - char *getVersion(); -}; - -#endif diff --git a/kernel/include/kheap.h b/kernel/include/kheap.h deleted file mode 100644 index 373173f..0000000 --- a/kernel/include/kheap.h +++ /dev/null @@ -1,101 +0,0 @@ -#ifndef _kheap_h -#define _kheap_h - -#include -#include -#include -#include - -#define KHEAP_START 0xC0000000 -#define KHEAP_INIT_SIZE 0x100000 -#define HEAP_INDEX_SIZE 0x20000 -#define HEAP_MAGIC 0x123890AB -#define HEAP_MIN_SIZE 0x70000 - -size_t placement_address; - -typedef struct { - uint32_t magic; - uint8_t is_hole; - uint32_t size; -} header_t; - -typedef struct { - uint32_t magic; - header_t *header; -} footer_t; - -typedef struct { - list_t index; - uint32_t start_address; - uint32_t end_address; - uint32_t max_address; - uint8_t supervisor; - uint8_t readonly; -} heap_t; - -heap_t *kheap; - -/** - * Create a new heap. - */ -heap_t *create_heap(uint32_t start, uint32_t end, uint32_t max, uint8_t supervisor, uint8_t readonly); - -/** - * Allocate a block of memory of 'size'. If page_align == 1, it creates that block starting on a page boundary. - */ -void *alloc(uint32_t size, uint8_t page_align, heap_t *heap_t); - -/** - * Relase a block of memory. - */ -void free(void *p, heap_t *heap); - -/** - * Find the smallest hole that will fit. - */ -int32_t find_hole(uint32_t size, uint8_t page_align, heap_t *heap); - -/** - * Header_t 'less than' checker. - */ -int8_t header_t_lessthan(type_t a, type_t b); - -/** - * Expand the heap. - */ -void expand(uint32_t new_size, heap_t *heap); - -/** - * Contract the heap. - */ -uint32_t contract(uint32_t new_size, heap_t *heap); - -/** - * Alloc a block of memory with specific options. - */ -size_t kmalloc_int(size_t sz, int align, size_t *phys); - -/** - * Alloc a block of memory with page aligned. - */ -size_t kmalloc_a(size_t sz); - -/** - * Alloc a block of memory and returns physical address. - */ -size_t kmalloc_p(size_t sz, size_t *phys); - -/** - * Alloc a block of memory with with page aligned and returns physical address. - */ -size_t kmalloc_ap(size_t sz, size_t *phys); - -/** - * Alloc a block of memory for kernel. - */ -size_t kmalloc(size_t sz); - -void kfree(void *p); - -#endif diff --git a/kernel/include/multiboot.h b/kernel/include/multiboot.h deleted file mode 100644 index 2683d73..0000000 --- a/kernel/include/multiboot.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef __MULTIBOOT_H -#define __MULTIBOOT_H - -#define MULTIBOOT_FLAG_MEM 0x001 -#define MULTIBOOT_FLAG_DEVICE 0x002 -#define MULTIBOOT_FLAG_CMDLINE 0x004 -#define MULTIBOOT_FLAG_MODS 0x008 -#define MULTIBOOT_FLAG_AOUT 0x010 -#define MULTIBOOT_FLAG_ELF 0x020 -#define MULTIBOOT_FLAG_MMAP 0x040 -#define MULTIBOOT_FLAG_CONFIG 0x080 -#define MULTIBOOT_FLAG_LOADER 0x100 -#define MULTIBOOT_FLAG_APM 0x200 -#define MULTIBOOT_FLAG_VBE 0x400 - -typedef struct multiboot -{ - uint32_t flags; - uint32_t mem_lower; - uint32_t mem_upper; - uint32_t boot_device; - uint32_t cmdline; - uint32_t mods_count; - uint32_t mods_addr; - uint32_t num; - uint32_t size; - uint32_t addr; - uint32_t shndx; - uint32_t mmap_length; - uint32_t mmap_addr; - uint32_t drives_length; - uint32_t drives_addr; - uint32_t config_table; - uint32_t boot_loader_name; - uint32_t apm_table; - uint32_t vbe_control_info; - uint32_t vbe_mode_info; - uint32_t vbe_mode; - uint32_t vbe_interface_seg; - uint32_t vbe_interface_off; - uint32_t vbe_interface_len; -} multiboot; - -#endif diff --git a/kernel/include/system.h b/kernel/include/system.h deleted file mode 100644 index d3d533d..0000000 --- a/kernel/include/system.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef _system_h -#define _system_h - -#include -#include -#include -#include - -#define OS_Name "PhotonOS" -#define Version "v0.0.1cpp" -#define Relase_Date "16 July 2015" -#define Author "Feraru Mihail" - -#define sti() asm volatile("sti") -#define cli() asm volatile("cli") -#define hlt() asm volatile("hlt") -#define keep_running() while(true) { hlt(); } - -#define INDEX_FROM_BIT(a) (a/(8*4)) -#define OFFSET_FROM_BIT(a) (a%(8*4)) - -typedef struct registers -{ - uint32_t ds; // Data segment selector - uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha. - uint32_t int_no, err_code; // Interrupt number and error code (if applicable) - uint32_t eip, cs, eflags, useresp, ss; // Pushed by the processor automatically. -} registers_t; // registers for interrupts - -typedef struct g_regs -{ - uint32_t edi; - uint32_t esi; - uint32_t edx; - uint32_t ecx; - uint32_t ebx; - uint32_t eax; -} g_regs_t; // general registers for system calls - -typedef struct t_regs { - uint32_t eax, ebx, ecx, edx, esi, edi, esp, ebp, eip, eflags, cr3; -} t_regs_t; // task registers - -typedef void (*isr_t)(registers_t*); -void register_interrupt_handler(uint8_t n, isr_t handler); - -typedef void* type_t; -extern size_t kernel_end; -extern size_t kernel_start; -extern uint32_t init_esp; - -extern char user[20]; -extern char machine[30]; - -void panic(const char *msg, int line, char *file); -void reboot(); -void shell(char *str); -void prompt(); - -#endif diff --git a/kernel/init/icxxabi.cpp b/kernel/init/icxxabi.cpp deleted file mode 100644 index 980b13b..0000000 --- a/kernel/init/icxxabi.cpp +++ /dev/null @@ -1,107 +0,0 @@ -#include - - #ifdef __cplusplus - extern "C" { - #endif - -atexit_func_entry_t __atexit_funcs[ATEXIT_MAX_FUNCS]; -uarch_t __atexit_func_count = 0; - -//void *__dso_handle = 0; //Attention! Optimally, you should remove the '= 0' part and define this in your asm script. - -extern "C" void __cxa_pure_virtual() -{ - // Do nothing... -} - -int __cxa_atexit(void (*f)(void *), void *objptr, void *dso) -{ - if (__atexit_func_count >= ATEXIT_MAX_FUNCS) {return -1;}; - __atexit_funcs[__atexit_func_count].destructor_func = f; - __atexit_funcs[__atexit_func_count].obj_ptr = objptr; - __atexit_funcs[__atexit_func_count].dso_handle = dso; - __atexit_func_count++; - return 0; /*I would prefer if functions returned 1 on success, but the ABI says...*/ -}; - -void __cxa_finalize(void *f) -{ - uarch_t i = __atexit_func_count; - if (!f) - { - /* - * According to the Itanium C++ ABI, if __cxa_finalize is called without a - * function ptr, then it means that we should destroy EVERYTHING MUAHAHAHA!! - * - * TODO: - * Note well, however, that deleting a function from here that contains a __dso_handle - * means that one link to a shared object file has been terminated. In other words, - * We should monitor this list (optional, of course), since it tells us how many links to - * an object file exist at runtime in a particular application. This can be used to tell - * when a shared object is no longer in use. It is one of many methods, however. - **/ - - while (i--) - { - if (__atexit_funcs[i].destructor_func) - { - /* ^^^ That if statement is a safeguard... - * To make sure we don't call any entries that have already been called and unset at runtime. - * Those will contain a value of 0, and calling a function with value 0 - * will cause undefined behaviour. Remember that linear address 0, - * in a non-virtual address space (physical) contains the IVT and BDA. - * - * In a virtual environment, the kernel will receive a page fault, and then probably - * map in some trash, or a blank page, or something stupid like that. - * This will result in the processor executing trash, and...we don't want that. - **/ - (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr); - }; - }; - return; - }; - - for ( ; i >= 0; --i) - { - /* - * The ABI states that multiple calls to the __cxa_finalize(destructor_func_ptr) function - * should not destroy objects multiple times. Only one call is needed to eliminate multiple - * entries with the same address. - * - * FIXME: - * This presents the obvious problem: all destructors must be stored in the order they - * were placed in the list. I.e: the last initialized object's destructor must be first - * in the list of destructors to be called. But removing a destructor from the list at runtime - * creates holes in the table with unfilled entries. - * Remember that the insertion algorithm in __cxa_atexit simply inserts the next destructor - * at the end of the table. So, we have holes with our current algorithm - * This function should be modified to move all the destructors above the one currently - * being called and removed one place down in the list, so as to cover up the hole. - * Otherwise, whenever a destructor is called and removed, an entire space in the table is wasted. - **/ - if (__atexit_funcs[i].destructor_func == f) - { - /* - * Note that in the next line, not every destructor function is a class destructor. - * It is perfectly legal to register a non class destructor function as a simple cleanup - * function to be called on program termination, in which case, it would not NEED an - * object This pointer. A smart programmer may even take advantage of this and register - * a C function in the table with the address of some structure containing data about - * what to clean up on exit. - * In the case of a function that takes no arguments, it will simply be ignore within the - * function itself. No worries. - **/ - (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr); - __atexit_funcs[i].destructor_func = 0; - - /* - * Notice that we didn't decrement __atexit_func_count: this is because this algorithm - * requires patching to deal with the FIXME outlined above. - **/ - }; - }; -}; - - #ifdef __cplusplus - }; - #endif diff --git a/kernel/init/init.c b/kernel/init/init.c deleted file mode 100644 index 2040def..0000000 --- a/kernel/init/init.c +++ /dev/null @@ -1,173 +0,0 @@ -/* Initialization interface - * - * Copyright (c) 2015 Feraru Mihail (mihailferaru2000@gmail.com). - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern int detect_cpu(void); - -#define FREQ 100 - -void init_stdio() { - inbuffer = (uint8_t*) kmalloc(sizeof(uint8_t) * STDIO_SIZE); - outbuffer = (char*) kmalloc(sizeof(char) * STDIO_SIZE); - - stdin = (uint8_t*) inbuffer; - stdout = (char*) outbuffer; - - for (int i = 0; i <= STDIO_SIZE; i++) { - inbuffer[i] = 0; - outbuffer[i] = 0; - } -} - -void init(multiboot *mboot_ptr, uint32_t init_stack) { - init_esp = init_stack; - - init_vga(); - init_stdio(); - init_gdt(); - init_idt(); - init_paging(mboot_ptr); - init_timer(FREQ); - install_keyboard(); - - // mask some interrupts - IRQ_set_mask(2); - IRQ_set_mask(3); - IRQ_set_mask(4); - IRQ_set_mask(5); - IRQ_set_mask(6); - IRQ_set_mask(7); - IRQ_set_mask(8); - IRQ_set_mask(9); - IRQ_set_mask(10); - IRQ_set_mask(11); - IRQ_set_mask(12); - IRQ_set_mask(13); - IRQ_set_mask(14); - IRQ_set_mask(15); - - printk("%s %s (%s) by %s. Copyright C 2015 %s. All rights reserved.\n", OS_Name, Version, Relase_Date, Author, Author); - detect_cpu(); - printk("\n-------------------------------------------------------------------\n"); - - printk("VGA driver was installed!\n"); - printk("Initialize tty. "); - wstr_color("[OK]\n", COLOR_GREEN); - - printk("Initialize paging. "); - wstr_color("[OK]\n", COLOR_GREEN); - printk("Memory info:\n"); - printk("\tKernel starts at: %x\n", (size_t)&kernel_start); - printk("\tKernel ends at: %x\n", (size_t)&kernel_end); - printk("\tRAM: %d MB\n", mem_size_mb); - - printk("Initialize stdio (allow using of stdio header). "); - wstr_color("[OK]\n", COLOR_GREEN); - - printk("Initialize GDT. "); - wstr_color("[OK]\n", COLOR_GREEN); - - printk("Initialize IDT and interrupts. "); - wstr_color("[OK]\n", COLOR_GREEN); - - printk("Install timer and clock. "); - wstr_color("[OK]\n", COLOR_GREEN); - - printk("Install keyboard support. "); - wstr_color("[OK]\n", COLOR_GREEN); - - /* tasking is useless, because switcher crashes every time - init_tasking(); - - uint32_t cr3, eflags; - asm volatile("movl %%cr3, %%eax; movl %%eax, %0;":"=r"(cr3)::"%eax"); - asm volatile("pushfl; movl (%%esp), %%eax; movl %%eax, %0; popfl;":"=r"(eflags)::"%eax"); - - task_t *clock_task = create_task(clock_task, &update_time, eflags, cr3); - */ - - wstr_color("\nDONE!\n", COLOR_GREEN); - - sti(); - - getch(); -} - -void welcome() { - clear_vga(); - - wstr_color(" |\\ /|( ____ \\( \\ ( ____ \\( ___ )( )( ____ \\\n", COLOR_RED); - wstr_color(" | ) ( || ( \\/| ( | ( \\/| ( ) || () () || ( \\/\n", COLOR_RED); - wstr_color(" | | _ | || (__ | | | | | | | || || || || (\\\n", COLOR_RED); - wstr_color(" | |( )| || __) | | | | | | | || |(_)| || __)\\\n", COLOR_RED); - wstr_color(" | || || || ( | | | | | | | || | | || (\\\n", COLOR_RED); - wstr_color(" | () () || (____/\\| (____/\\| (____/\\| (___) || ) ( || (____/\\\n", COLOR_RED); - wstr_color(" (_______)(_______/(_______/(_______/(_______)|/ \\|(_______/\n\n", COLOR_RED); - - wstr_color(" \\__ __/( ___ )\n", COLOR_YELLOW); - wstr_color(" ) ( | ( ) |\n", COLOR_YELLOW); - wstr_color(" | | | | | |\n", COLOR_YELLOW); - wstr_color(" | | | | | |\n", COLOR_YELLOW); - wstr_color(" | | | | | |\n", COLOR_YELLOW); - wstr_color(" | | | (___) |\n", COLOR_YELLOW); - wstr_color(" )_( (_______)\n\n", COLOR_YELLOW); - - wstr_color(" _______ _______ _________ _______ _ _______ _______ \n", COLOR_BLUE); - wstr_color("( ____ )|\\ /|( ___ )\\__ __/( ___ )( ( /|( ___ )( ____ \\\\\n", COLOR_BLUE); - wstr_color("| ( )|| ) ( || ( ) | ) ( | ( ) || \\ ( || ( ) || ( \\/\n", COLOR_BLUE); - wstr_color("| (____)|| (___) || | | | | | | | | || \\ | || | | || (_____ \n", COLOR_BLUE); - wstr_color("| _____)| ___ || | | | | | | | | || (\\ \\) || | | |(_____ )\n", COLOR_BLUE); - wstr_color("| ( | ( ) || | | | | | | | | || | \\ || | | | ) |\n", COLOR_BLUE); - wstr_color("| ) | ) ( || (___) | | | | (___) || ) \\ || (___) |/\\____) |\n", COLOR_BLUE); - wstr_color("|/ |/ \\|(_______) )_( (_______)|/ )_)(_______)\\_______)\n", COLOR_BLUE); - - printk(" by Feraru Mihail"); - - getch(); - clear_vga(); -} - -void login() { - wstr_color(" _______ _______ _________ _______ _ _______ _______ \n", COLOR_BLUE); - wstr_color("( ____ )|\\ /|( ___ )\\__ __/( ___ )( ( /|( ___ )( ____ \\\\\n", COLOR_BLUE); - wstr_color("| ( )|| ) ( || ( ) | ) ( | ( ) || \\ ( || ( ) || ( \\/\n", COLOR_BLUE); - wstr_color("| (____)|| (___) || | | | | | | | | || \\ | || | | || (_____ \n", COLOR_BLUE); - wstr_color("| _____)| ___ || | | | | | | | | || (\\ \\) || | | |(_____ )\n", COLOR_BLUE); - wstr_color("| ( | ( ) || | | | | | | | | || | \\ || | | | ) |\n", COLOR_BLUE); - wstr_color("| ) | ) ( || (___) | | | | (___) || ) \\ || (___) |/\\____) |\n", COLOR_BLUE); - wstr_color("|/ |/ \\|(_______) )_( (_______)|/ )_)(_______)\\_______)\n", COLOR_BLUE); - - printk("Log in please.\n"); - printk("Username: "); - gets(user); - printk("Machine: "); - gets(machine); - printk("Loged in!\n"); -} diff --git a/kernel/init/main.cpp b/kernel/init/main.cpp deleted file mode 100644 index 6baeb96..0000000 --- a/kernel/init/main.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* All starts here! - * - * Copyright (c) 2015 Feraru Mihail (mihailferaru2000@gmail.com). - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void kmain(multiboot *mboot_ptr, uint32_t init_stack) { - init(mboot_ptr, init_stack); - welcome(); - login(); - - /* C++ Test */ - printk("\n"); - - KernelClass my_kernel; - my_kernel.setID(16072015); - my_kernel.setVersion("v0.0.1cpp"); - int ID = my_kernel.getID(); - char version[30]; - memcpy(version, my_kernel.getVersion(), strlen(my_kernel.getVersion()) + 1); - - printk("KERNEL ID: %d\n", ID); - printk("KERNEL VERSION: %s\n", version); - - printk("\n"); - - prompt(); - panic("Shell exited!", __LINE__, __FILE__); -} - -#ifdef __cplusplus -} -#endif diff --git a/kernel/system/cpu.c b/kernel/system/cpu.c deleted file mode 100644 index dd1710b..0000000 --- a/kernel/system/cpu.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright (c) 2006-2007 - http://brynet.biz.tm - - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include /* for printk(); */ - -/* Required Declarations */ -int do_intel(void); -int do_amd(void); -void printregs(int eax, int ebx, int ecx, int edx); - -#define cpuid(in, a, b, c, d) __asm__("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in)); - -/* Simply call this function detect_cpu(); */ -int detect_cpu(void) { /* or main() if your trying to port this as an independant application */ - unsigned long ebx, unused; - cpuid(0, unused, ebx, unused, unused); - switch(ebx) { - case 0x756e6547: /* Intel Magic Code */ - do_intel(); - break; - case 0x68747541: /* AMD Magic Code */ - do_amd(); - break; - default: - printk("Unknown x86 CPU Detected\n"); - break; - } - return 0; -} - -/* Intel Specific brand list */ -char *Intel[] = { - "Brand ID Not Supported.", - "Intel(R) Celeron(R) processor", - "Intel(R) Pentium(R) III processor", - "Intel(R) Pentium(R) III Xeon(R) processor", - "Intel(R) Pentium(R) III processor", - "Reserved", - "Mobile Intel(R) Pentium(R) III processor-M", - "Mobile Intel(R) Celeron(R) processor", - "Intel(R) Pentium(R) 4 processor", - "Intel(R) Pentium(R) 4 processor", - "Intel(R) Celeron(R) processor", - "Intel(R) Xeon(R) Processor", - "Intel(R) Xeon(R) processor MP", - "Reserved", - "Mobile Intel(R) Pentium(R) 4 processor-M", - "Mobile Intel(R) Pentium(R) Celeron(R) processor", - "Reserved", - "Mobile Genuine Intel(R) processor", - "Intel(R) Celeron(R) M processor", - "Mobile Intel(R) Celeron(R) processor", - "Intel(R) Celeron(R) processor", - "Mobile Geniune Intel(R) processor", - "Intel(R) Pentium(R) M processor", - "Mobile Intel(R) Celeron(R) processor" -}; - -/* This table is for those brand strings that have two values depending on the processor signature. It should have the same number of entries as the above table. */ -char *Intel_Other[] = { - "Reserved", - "Reserved", - "Reserved", - "Intel(R) Celeron(R) processor", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Intel(R) Xeon(R) processor MP", - "Reserved", - "Reserved", - "Intel(R) Xeon(R) processor", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved", - "Reserved" -}; - -/* Intel-specific information */ -int do_intel(void) { - printk("Intel Specific Features:\n"); - unsigned long eax, ebx, ecx, edx, max_eax, signature, unused; - int model, family, type, brand, stepping, reserved; - int extended_family = -1; - cpuid(1, eax, ebx, unused, unused); - model = (eax >> 4) & 0xf; - family = (eax >> 8) & 0xf; - type = (eax >> 12) & 0x3; - brand = ebx & 0xff; - stepping = eax & 0xf; - reserved = eax >> 14; - signature = eax; - printk("Type %d - ", type); - switch(type) { - case 0: - printk("Original OEM"); - break; - case 1: - printk("Overdrive"); - break; - case 2: - printk("Dual-capable"); - break; - case 3: - printk("Reserved"); - break; - } - printk("\n"); - printk("Family %d - ", family); - switch(family) { - case 3: - printk("i386"); - break; - case 4: - printk("i486"); - break; - case 5: - printk("Pentium"); - break; - case 6: - printk("Pentium Pro"); - break; - case 15: - printk("Pentium 4"); - } - printk("\n"); - if(family == 15) { - extended_family = (eax >> 20) & 0xff; - printk("Extended family %d\n", extended_family); - } - printk("Model %d - ", model); - switch(family) { - case 3: - break; - case 4: - switch(model) { - case 0: - case 1: - printk("DX"); - break; - case 2: - printk("SX"); - break; - case 3: - printk("487/DX2"); - break; - case 4: - printk("SL"); - break; - case 5: - printk("SX2"); - break; - case 7: - printk("Write-back enhanced DX2"); - break; - case 8: - printk("DX4"); - break; - } - break; - case 5: - switch(model) { - case 1: - printk("60/66"); - break; - case 2: - printk("75-200"); - break; - case 3: - printk("for 486 system"); - break; - case 4: - printk("MMX"); - break; - } - break; - case 6: - switch(model) { - case 1: - printk("Pentium Pro"); - break; - case 3: - printk("Pentium II Model 3"); - break; - case 5: - printk("Pentium II Model 5/Xeon/Celeron"); - break; - case 6: - printk("Celeron"); - break; - case 7: - printk("Pentium III/Pentium III Xeon - external L2 cache"); - break; - case 8: - printk("Pentium III/Pentium III Xeon - internal L2 cache"); - break; - } - break; - case 15: - break; - } - printk("\n"); - cpuid(0x80000000, max_eax, unused, unused, unused); - /* Quok said: If the max extended eax value is high enough to support the processor brand string - (values 0x80000002 to 0x80000004), then we'll use that information to return the brand information. - Otherwise, we'll refer back to the brand tables above for backwards compatibility with older processors. - According to the Sept. 2006 Intel Arch Software Developer's Guide, if extended eax values are supported, - then all 3 values for the processor brand string are supported, but we'll test just to make sure and be safe. */ - if(max_eax >= 0x80000004) { - printk("Brand: "); - if(max_eax >= 0x80000002) { - cpuid(0x80000002, eax, ebx, ecx, edx); - printregs(eax, ebx, ecx, edx); - } - if(max_eax >= 0x80000003) { - cpuid(0x80000003, eax, ebx, ecx, edx); - printregs(eax, ebx, ecx, edx); - } - if(max_eax >= 0x80000004) { - cpuid(0x80000004, eax, ebx, ecx, edx); - printregs(eax, ebx, ecx, edx); - } - printk("\n"); - } else if(brand > 0) { - printk("Brand %d - ", brand); - if(brand < 0x18) { - if(signature == 0x000006B1 || signature == 0x00000F13) { - printk("%s\n", Intel_Other[brand]); - } else { - printk("%s\n", Intel[brand]); - } - } else { - printk("Reserved\n"); - } - } - printk("Stepping: %d Reserved: %d\n", stepping, reserved); - return 0; -} - -/* Print Registers */ -void printregs(int eax, int ebx, int ecx, int edx) { - int j; - char string[17]; - string[16] = '\0'; - for(j = 0; j < 4; j++) { - string[j] = eax >> (8 * j); - string[j + 4] = ebx >> (8 * j); - string[j + 8] = ecx >> (8 * j); - string[j + 12] = edx >> (8 * j); - } - printk("%s", string); -} - -/* AMD-specific information */ -int do_amd(void) { - printk("AMD Specific Features:\n"); - unsigned long extended, eax, ebx, ecx, edx, unused; - int family, model, stepping, reserved; - cpuid(1, eax, unused, unused, unused); - model = (eax >> 4) & 0xf; - family = (eax >> 8) & 0xf; - stepping = eax & 0xf; - reserved = eax >> 12; - printk("Family: %d Model: %d [", family, model); - switch(family) { - case 4: - printk("486 Model %d", model); - break; - case 5: - switch(model) { - case 0: - case 1: - case 2: - case 3: - case 6: - case 7: - printk("K6 Model %d", model); - break; - case 8: - printk("K6-2 Model 8"); - break; - case 9: - printk("K6-III Model 9"); - break; - default: - printk("K5/K6 Model %d", model); - break; - } - break; - case 6: - switch(model) { - case 1: - case 2: - case 4: - printk("Athlon Model %d", model); - break; - case 3: - printk("Duron Model 3"); - break; - case 6: - printk("Athlon MP/Mobile Athlon Model 6"); - break; - case 7: - printk("Mobile Duron Model 7"); - break; - default: - printk("Duron/Athlon Model %d", model); - break; - } - break; - } - printk("]\n"); - cpuid(0x80000000, extended, unused, unused, unused); - if(extended == 0) { - return 0; - } - if(extended >= 0x80000002) { - unsigned int j; - printk("Detected Processor Name: "); - for(j = 0x80000002; j <= 0x80000004; j++) { - cpuid(j, eax, ebx, ecx, edx); - printregs(eax, ebx, ecx, edx); - } - printk("\n"); - } - if(extended >= 0x80000007) { - cpuid(0x80000007, unused, unused, unused, edx); - if(edx & 1) { - printk("Temperature Sensing Diode Detected!\n"); - } - } - printk("Stepping: %d Reserved: %d\n", stepping, reserved); - return 0; -} diff --git a/kernel/system/kheap.c b/kernel/system/kheap.c deleted file mode 100644 index 33837ef..0000000 --- a/kernel/system/kheap.c +++ /dev/null @@ -1,359 +0,0 @@ -/* Kernel heap driver - * - * Copyright (c) 2015 Feraru Mihail (mihailferaru2000@gmail.com). - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include -#include -#include -#include - -int32_t find_hole(uint32_t size, uint8_t page_align, heap_t *heap) -{ - uint32_t iterator = 0; - while (iterator < heap->index.size) { - header_t *header = (header_t*) lookup_list(iterator, &heap->index); - if (page_align > 0) { - uint32_t location = (uint32_t) header; - int32_t offset = 0; - if (((location + sizeof(header_t)) & 0xFFFFF000) != 0) { - offset = 0x1000 - (location + sizeof(header_t) % 0x1000); - } - int32_t hole_size = (int32_t) header->size - offset; - if (hole_size >= (int32_t) size) { - break; - } - } else if (header->size >= size) { - break; - } - iterator++; - } - if (iterator == heap->index.size) { - return -1; - } else { - return iterator; - } -} - -int8_t header_t_lessthan(type_t a, type_t b) -{ - return (((header_t*)a)->size < ((header_t*)b)->size)?1:0; -} - -heap_t *create_heap(uint32_t start, uint32_t end, uint32_t max, uint8_t supervisor, uint8_t readonly) -{ - heap_t *heap = (heap_t*) kmalloc(sizeof(heap_t)); - ASSERT((start % 0x1000 == 0)); - ASSERT((end % 0x1000 == 0)); - - heap->index = place_list((type_t*) start, HEAP_INDEX_SIZE, &header_t_lessthan); - - start += sizeof(type_t) * HEAP_INDEX_SIZE; - - if ((start & 0xFFFFF000) != 0) { - start &= 0xFFFFF000; - start += 0x1000; - } - - heap->start_address = start; - heap->end_address = end; - heap->max_address = max; - heap->supervisor = supervisor; - heap->readonly = readonly; - - header_t *hole = (header_t*) start; - hole->size = end - start; - hole->magic = HEAP_MAGIC; - hole->is_hole = 1; - insert_list((type_t) hole, &heap->index); - - return heap; -} - -void *alloc(uint32_t size, uint8_t page_align, heap_t *heap) -{ - uint32_t new_size = size + sizeof(header_t) + sizeof(footer_t); - int32_t iterator = find_hole(new_size, page_align, heap); - - if (iterator == (int32_t) -1) { - uint32_t old_length = heap->end_address - heap->start_address; - uint32_t old_end_address = heap->end_address; - - expand(old_length+new_size, heap); - uint32_t new_length = heap->end_address-heap->start_address; - - iterator = 0; - - int32_t idx = -1; - uint32_t value = 0x0; - while (iterator < (int32_t) heap->index.size) - { - uint32_t tmp = (uint32_t)lookup_list(iterator, &heap->index); - if (tmp > value) - { - value = tmp; - idx = iterator; - } - iterator++; - } - - if (idx == -1) - { - header_t *header = (header_t *)old_end_address; - header->magic = HEAP_MAGIC; - header->size = new_length - old_length; - header->is_hole = 1; - footer_t *footer = (footer_t *) (old_end_address + header->size - sizeof(footer_t)); - footer->magic = HEAP_MAGIC; - footer->header = header; - insert_list((void*)header, &heap->index); - } - else - { - header_t *header = lookup_list(idx, &heap->index); - header->size += new_length - old_length; - footer_t *footer = (footer_t *) ( (uint32_t)header + header->size - sizeof(footer_t) ); - footer->header = header; - footer->magic = HEAP_MAGIC; - } - - return alloc(size, page_align, heap); - } - - header_t *orig_hole_header = (header_t *)lookup_list(iterator, &heap->index); - uint32_t orig_hole_pos = (uint32_t) orig_hole_header; - uint32_t orig_hole_size = orig_hole_header->size; - - if (orig_hole_size - new_size < sizeof(header_t) + sizeof(footer_t)) { - size += orig_hole_size - new_size; - new_size = orig_hole_size; - } - - if (page_align && (orig_hole_pos & 0xFFFFF000)) { - uint32_t new_location = orig_hole_pos + 0x1000 - (orig_hole_pos & 0xFFF) - sizeof(header_t); - header_t *hole_header = (header_t*) orig_hole_pos; - hole_header->size = 0x1000; - hole_header->magic = HEAP_MAGIC; - hole_header->is_hole = 1; - footer_t *hole_footer = (footer_t*) ((uint32_t) new_location - sizeof(footer_t)); - hole_footer->magic = HEAP_MAGIC; - hole_footer->header = hole_header; - orig_hole_pos = new_location; - orig_hole_size = orig_hole_size - hole_header->size; - } else { - remove_list(iterator, &heap->index); - } - - header_t *block_header = (header_t*) orig_hole_pos; - block_header->magic = HEAP_MAGIC; - block_header->is_hole = 0; - block_header->size = new_size; - - footer_t *block_footer = (footer_t*) (orig_hole_pos + sizeof(header_t) + size); - block_footer->header = block_header; - - if (orig_hole_size - new_size > 0) { - header_t *hole_header = (header_t*) (orig_hole_pos + sizeof(header_t) + size + sizeof(footer_t)); - hole_header->magic = HEAP_MAGIC; - hole_header->is_hole = 1; - hole_header->size = orig_hole_size - new_size; - footer_t *hole_footer = (footer_t*) ((uint32_t) hole_header + orig_hole_size - new_size - sizeof(footer_t)); - - if ((uint32_t) hole_footer < heap->end_address) { - hole_footer->magic = HEAP_MAGIC; - hole_footer->header = hole_header; - } - insert_list((void*)hole_header, &heap->index); - } - return (void*) ((uint32_t) block_header + sizeof(header_t)); -} - -void free(void *p, heap_t *heap) -{ - // Exit gracefully for null pointers. - if (p == 0) - return; - - // Get the header and footer associated with this pointer. - header_t *header = (header_t*) ( (uint32_t)p - sizeof(header_t) ); - footer_t *footer = (footer_t*) ( (uint32_t)header + header->size - sizeof(footer_t) ); - - // Sanity checks. - ASSERT(header->magic == HEAP_MAGIC); - ASSERT(footer->magic == HEAP_MAGIC); - - // Make us a hole. - header->is_hole = 1; - - // Do we want to add this header into the 'free holes' index? - char do_add = 1; - - // Unify left - // If the thing immediately to the left of us is a footer... - footer_t *test_footer = (footer_t*) ( (uint32_t)header - sizeof(footer_t) ); - if (test_footer->magic == HEAP_MAGIC && - test_footer->header->is_hole == 1) - { - uint32_t cache_size = header->size; // Cache our current size. - header = test_footer->header; // Rewrite our header with the new one. - footer->header = header; // Rewrite our footer to point to the new header. - header->size += cache_size; // Change the size. - do_add = 0; // Since this header is already in the index, we don't want to add it again. - } - - // Unify right - // If the thing immediately to the right of us is a header... - header_t *test_header = (header_t*) ( (uint32_t)footer + sizeof(footer_t) ); - if (test_header->magic == HEAP_MAGIC && - test_header->is_hole) - { - header->size += test_header->size; // Increase our size. - test_footer = (footer_t*) ( (uint32_t)test_header + // Rewrite it's footer to point to our header. - test_header->size - sizeof(footer_t) ); - footer = test_footer; - // Find and remove this header from the index. - uint32_t iterator = 0; - while ( (iterator < heap->index.size) && - (lookup_list(iterator, &heap->index) != (void*)test_header) ) - iterator++; - - // Make sure we actually found the item. - ASSERT(iterator < heap->index.size); - // Remove it. - remove_list(iterator, &heap->index); - } - - // If the footer location is the end address, we can contract. - if ( (uint32_t)footer+sizeof(footer_t) == heap->end_address) - { - uint32_t old_length = heap->end_address-heap->start_address; - uint32_t new_length = contract( (uint32_t)header - heap->start_address, heap); - // Check how big we will be after resizing. - if (header->size - (old_length-new_length) > 0) - { - // We will still exist, so resize us. - header->size -= old_length-new_length; - footer = (footer_t*) ( (uint32_t)header + header->size - sizeof(footer_t) ); - footer->magic = HEAP_MAGIC; - footer->header = header; - } - else - { - // We will no longer exist :(. Remove us from the index. - uint32_t iterator = 0; - while ( (iterator < heap->index.size) && - (lookup_list(iterator, &heap->index) != (void*)test_header) ) - iterator++; - // If we didn't find ourselves, we have nothing to remove. - if (iterator < heap->index.size) - remove_list(iterator, &heap->index); - } - } - - // If required, add us to the index. - if (do_add == 1) - insert_list((void*)header, &heap->index); - -} - -void expand(uint32_t new_size, heap_t *heap) -{ - ASSERT(new_size > heap->end_address - heap->start_address); - - if ((new_size & 0xFFFFF000) != 0) { - new_size &= 0xFFFFF000; - new_size += 0x1000; - } - - ASSERT(heap->start_address + new_size <= heap->max_address); - - uint32_t old_size = heap->end_address-heap->start_address; - uint32_t i = old_size; - while (i < new_size) { - alloc_frame( get_page(heap->start_address+i, 1, kernel_directory), - (heap->supervisor)?1:0, (heap->readonly)?0:1); - i += 0x1000; - } - heap->end_address = heap->start_address+new_size; -} - -uint32_t contract(uint32_t new_size, heap_t *heap) -{ - ASSERT(new_size < heap->end_address - heap->start_address); - - if (new_size & 0x1000) { - new_size &= 0x1000; - new_size += 0x1000; - } - - if (new_size < HEAP_MIN_SIZE) { - new_size = HEAP_MIN_SIZE; - } - uint32_t old_size = heap->end_address - heap->start_address; - uint32_t i = old_size - 0x1000; - - while (new_size < i) { - free_frame(get_page(heap->start_address + i, 0, kernel_directory)); - i -= 0x1000; - } - heap->end_address = heap->start_address + new_size; - - return new_size; -} - -size_t kmalloc_int(size_t sz, int align, size_t *phys) -{ - if (kheap == NULL) { - if (align == 1 && (placement_address & 0xFFFFF000)) { - placement_address &= 0xFFFFF000; - placement_address += 0x1000; - } - if (phys) { - *phys = placement_address; - } - size_t tmp = placement_address; - placement_address += sz; - return tmp; - } else { - void *addr = alloc(sz, (uint8_t) align, kheap); - if (phys != NULL) { - page_t *page = get_page((uint32_t) addr, 0, kernel_directory); - *phys = page->frame * 0x1000 + ((uint32_t) addr & 0xFFF); - } - return (uint32_t) addr; - } -} - -size_t kmalloc_a(size_t sz) -{ - return kmalloc_int(sz, 1, 0); -} - -size_t kmalloc_p(size_t sz, size_t *phys) -{ - return kmalloc_int(sz, 0, phys); -} - -size_t kmalloc_ap(size_t sz, size_t *phys) -{ - return kmalloc_int(sz, 1, phys); -} - -size_t kmalloc(size_t sz) -{ - return kmalloc_int(sz, 0, 0); -} - -void kfree(void *p) -{ - if (p != NULL) { - free(p, kheap); - p = NULL; - } -} diff --git a/kernel/system/system.c b/kernel/system/system.c deleted file mode 100644 index 25e5d98..0000000 --- a/kernel/system/system.c +++ /dev/null @@ -1,226 +0,0 @@ -/* Basic System Interface - * - * Copyright (c) 2015 Feraru Mihail (mihailferaru2000@gmail.com). - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern uint32_t stack_top; -uint32_t init_esp; - -char user[20]; -char machine[30]; - -static void testing_shell(char *str) -{ - - while (true) { - printk("\nEnter test name> "); - gets(str); - - if (!strcmp(str, "exit")) { - break; - } else if (!strcmp(str, "print-stdin")) { - printk("%s\n", (uint8_t*)stdin); - } else if (!strcmp(str, "size")) { - printk("Sizes:\n"); - printk("Char: %d\nInt: %d\nFloat: %d\nSize_t: %d\n", sizeof(char), sizeof(int), sizeof(float), sizeof(size_t)); - printk("Kernel:\n"); - printk("Start: %x\nEnd: %x\n", (size_t)&kernel_start, (size_t)&kernel_end); - printk("RAM: %d MB\n", mem_size_mb); - } else if (!strcmp(str, "page-fault")) { - printk("Test fault...\n"); - uint32_t *ptr = (uint32_t*)0xA123142300; - printk("%d\n", *ptr); - } else if (!strcmp(str, "address")) { - printk("This is a test of memory manager. Warning! You are in kernel mode!\n"); - printk("Kernel:\n"); - printk("Start: %x\nEnd: %x\n", (size_t)&kernel_start, (size_t)&kernel_end); - getch(); - printk("stack_top: %x\n", stack_top); - printk("&stack_top: %x\n", &stack_top); - getch(); - printk("placement_address: %x\n", placement_address); - printk("&placement_address: %x\n", &placement_address); - getch(); - printk("kheap: %x\n", kheap); - printk("&kheap: %x\n", &kheap); - printk("*kheap: %x\n", *kheap); - getch(); - - int *num = (int*) kmalloc(sizeof(int)); - *num = 0x123ABC; - printk("num: %x\n", num); - printk("&num: %x\n", &num); - printk("*num: %x\n", *num); - - int snum = 0xABC123; - printk("snum: %x\n", snum); - printk("&snum: %x\n", &snum); - getch(); - - printk("Kernel:\n"); - printk("Start: %x\nEnd: %x\n", (size_t)&kernel_start, (size_t)&kernel_end); - getch(); - printk("stack_top: %x\n", stack_top); - printk("&stack_top: %x\n", &stack_top); - getch(); - - printk("placement_address: %x\n", placement_address); - printk("&placement_address: %x\n", &placement_address); - getch(); - - printk("kheap: %x\n", kheap); - printk("&kheap: %x\n", &kheap); - printk("*kheap: %x\n", *kheap); - getch(); - - kfree(num); - } else if (!strcmp(str, "alloc")) { - printk("SIZE OF INT: %d\n", sizeof(int)); - int *a = (int *)kmalloc(sizeof(int)); - *a = 6; - printk("a: %x\n", a); - printk("a: %x\n", *a); - - int *b = (int *)kmalloc(sizeof(int)); - *b = 5; - printk("b: %x\n", b); - printk("b: %x\n", *b); - kfree(b); - - int *c = (int *)kmalloc(sizeof(int)); - *c = 8; - printk("c: %x\n", c); - printk("c: %x\n", *c); - - kfree(a); - kfree(b); - kfree(c); - //------------------------------------------------------- - char *stmp = (char *)kmalloc(sizeof(char) * 11); - memcpy(stmp, "This is.\0", 9); - printk(stmp); - printk("\n&stmp[0]: %x &stmp[9]: %x\n", stmp, stmp + sizeof(char) * 11); - - kfree(stmp); - - char *tmp = (char *)kmalloc(sizeof(char) * 10); - memcpy(tmp, "THIS WAS.\0", 10); - printk(tmp); - printk("\n&tmp[0]: %x &tmp[9]: %x\n", tmp, tmp + sizeof(char) * 11); - - kfree(tmp); - } else if (!strcmp(str, "vga")) { - printk("Ab_C\b\b\nNew\tLineWasWritten NUM~%x%s%c%c\n", 0x123ABC, "test", 'f', 55); - printk("Expected:\nAb\nNew LineWasWritten NUM~0x123abctestf7\n"); - } else { - printk("Command not found!\n"); - } - } -} - -void panic(const char *msg, int line, char *file) -{ - cli(); - printk("[KERNEL PANIC]"); - printk("%s. Error at line %d in file %s.", msg, line, file); - keep_running(); -} - -void reboot() -{ - uint8_t good = 0x02; - while (good & 0x02) - good = inb(0x64); - outb(0x64, 0xFE); - hlt(); -} - -void shell(char *str) { - if (!strcmp(str, "exit")) { - panic("Exit.", __LINE__, __FILE__); - } else if (!strcmp(str, "test")) { - testing_shell(str); - - } else if (!strcmp(str, "time")) { - print_time(); - printk("\n"); - - } else if (!strcmp(str, "tick")) { - printk("Tick: %d\n", get_tick()); - - } else if (!strcmp(str, "clock")) { - printk("WARN: no clock yet\n"); - } else if (!strcmp(str, "clear")) { - clear_vga(); - - } else if (!strcmp(str, "reset-clock")) { - hours = 0; - minutes = 0; - seconds = 0; - - } else if (!strcmp(str, "write")) { - char *to_write = (char*) kmalloc(sizeof(char) * 30); - size_t len = strlen("\nLet's write this...\n"); - - memcpy(to_write, "Let's write this...\n\0", len + 1); - call(1, (uint32_t) to_write, (uint32_t) len, 0, 0, 0); - kfree(to_write); - - } else if (!strcmp(str, "reboot")) { - reboot(); - } else if (!strcmp(str, "usermode")) { - printk("CPU will jump to usermode, this will stop shell, because it is running only in kernel mode.\n"); - init_usermode(); - char s[] = "Welcome in usermode!\n"; - call(1, (uint32_t) s, (uint32_t) strlen(s), 0, 0, 0); - } else if (!strcmp(str, "sys-info")) { - printk("%s %s (%s) by %s.\nCopyright C 2015 %s.\nAll rights reserved.\n", OS_Name, Version, Relase_Date, Author, Author); - - } else if (!strcmp(str, "help")) { - printk("After kernel boots up, user must enter user name and machine name. Now, a shell has started. Here user can use some commands:\n"); - printk(" -> help -> display this page\n"); - printk(" -> time -> display current time\n"); - printk(" -> tick -> display current tick\n"); - printk(" -> clock -> start a clock that can be stoped when ESC is pressed\n"); - printk(" -> clear -> clear the screen\n"); - printk(" -> reset-clock -> set clock to 0\n"); - printk(" -> sys->info -> prints info about system\n"); - printk(" -> test -> enter into testing shell that allows testing kernel functions\n"); - printk(" -> exit -> close shell\n\n"); - - printk("Testing shell:\n"); - printk(" Tests avabile in testing shell:\n"); - printk(" -> exit -> close testing shell\n"); - printk(" -> print-stdin -> print all data from standard input\n"); - printk(" -> size -> print sizes of types, of kernel and RAM\n"); - printk(" -> page-fault -> generate page fault\n"); - printk(" -> address -> print addresses of all kernel variables and of some temporary\n"); - printk(" -> alloc -> test kmalloc and kfree\n"); - - } else { - printk("\"%s\" not recognized as internal command or program. Please try again.\n", str); - } -} - -void prompt() { - char cmd[1024]; - while (true) { - printk("%s@%s:$ ", user, machine); - gets(cmd); - shell(cmd); - } -} diff --git a/libc/arch/i386/crt0.S b/libc/arch/i386/crt0.S deleted file mode 100644 index 1c7ae13..0000000 --- a/libc/arch/i386/crt0.S +++ /dev/null @@ -1,37 +0,0 @@ -.section .text - -.global _start -.type _start, @function -_start: - # TODO: Locate argc, argv, envp according to System V ABI (i386 supplement) - # Figure 3-31: Initial Process Stack (3-28, Page 54). - - # Set up end of the stack frame linked list. - xorl %ebp, %ebp - pushl %ebp # rip=0 - pushl %ebp # rbp=0 - movl %esp, %ebp - - # Initialize the standard library. - push $0 # TODO: argc - push $0 # TODO: argv - push $0 # TODO: envp - call __init_libc # void(int, char**, char**) - addl $12, %esp - - # Run the global constructors. -#if !defined(__HAS_NO_CRT_INIT) - call _init # void(void) -#endif - - # Run main - push $0 # TODO: argc - push $0 # TODO: argv - push $0 # TODO: envp - call main # int(int, char**, char**) - addl $12, %esp - - # Terminate the process with main's exit code. - push %eax - call exit -.size _start, .-_start diff --git a/libc/arch/i386/crti.S b/libc/arch/i386/crti.S deleted file mode 100644 index cebea3e..0000000 --- a/libc/arch/i386/crti.S +++ /dev/null @@ -1,15 +0,0 @@ -.section .init -.global _init -.type _init, @function -_init: - push %ebp - movl %esp, %ebp - /* gcc will nicely put the contents of crtbegin.o's .init section here. */ - -.section .fini -.global _fini -.type _fini, @function -_fini: - push %ebp - movl %esp, %ebp - /* gcc will nicely put the contents of crtbegin.o's .fini section here. */ diff --git a/libc/arch/i386/crtn.S b/libc/arch/i386/crtn.S deleted file mode 100644 index 33957bf..0000000 --- a/libc/arch/i386/crtn.S +++ /dev/null @@ -1,9 +0,0 @@ -.section .init - /* gcc will nicely put the contents of crtend.o's .init section here. */ - popl %ebp - ret - -.section .fini - /* gcc will nicely put the contents of crtend.o's .fini section here. */ - popl %ebp - ret diff --git a/libc/phapi/list.c b/libc/phapi/list.c deleted file mode 100644 index ee190d8..0000000 --- a/libc/phapi/list.c +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include -#include -#include -#include -#include - -int8_t std_lessthan_pred(type_t a, type_t b) -{ - return (a < b) ? 1 : 0; -} - -list_t create_list(uint32_t max_size, lessthan_pred_t lessthan) -{ - list_t ret; - ret.array = (void*) kmalloc(max_size * sizeof(type_t)); - memset(ret.array, 0, max_size * sizeof(type_t)); - ret.size = 0; - ret.max_size = max_size; - ret.lessthan = lessthan; - return ret; -} - -list_t place_list(void *addr, uint32_t max_size, lessthan_pred_t lessthan) -{ - list_t ret; - ret.array = (type_t*) addr; - memset(ret.array, 0, max_size * sizeof(type_t)); - ret.size = 0; - ret.max_size = max_size; - ret.lessthan = lessthan; - return ret; -} - -void destroy_list(list_t *array) -{ - kfree(array->array); -} - -void insert_list(type_t item, list_t *array) -{ - ASSERT(array->lessthan); - uint32_t iterator = 0; - while (iterator < array->size && array->lessthan(array->array[iterator], item)) { - iterator++; - } - - if (iterator == array->size) { - array->array[array->size++] = item; - } else { - type_t tmp = array->array[iterator]; - array->array[iterator] = item; - while (iterator < array->size) { - iterator++; - type_t tmp2 = array->array[iterator]; - array->array[iterator] = tmp; - tmp = tmp2; - } - array->size++; - } -} - -type_t lookup_list(uint32_t i, list_t *array) -{ - ASSERT(i < array->size); - return array->array[i]; -} - -void remove_list(uint32_t i, list_t *array) -{ - while (i < array->size) { - array->array[i] = array->array[i + 1]; - i++; - } - array->size--; -} diff --git a/libc/stdio/getch.c b/libc/stdio/getch.c deleted file mode 100644 index e9c4509..0000000 --- a/libc/stdio/getch.c +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include -#include - -int getch() -{ - for (;;) { - if (((uint8_t*)stdin)[in_size] != 0) { - in_size++; - break; - } - } - int c = ((uint8_t*)stdin)[in_size - 1]; - - return c; -} diff --git a/libc/stdio/getchar.c b/libc/stdio/getchar.c deleted file mode 100644 index c3181a9..0000000 --- a/libc/stdio/getchar.c +++ /dev/null @@ -1,10 +0,0 @@ -#include -#include - -int getchar() -{ - int c = getch(); - putchar(c); - - return c; -} diff --git a/libc/stdio/gets.c b/libc/stdio/gets.c deleted file mode 100644 index 95ae77e..0000000 --- a/libc/stdio/gets.c +++ /dev/null @@ -1,20 +0,0 @@ -#include - -char *gets(char *str) -{ - int c = getch(); - int i = 0; - while (c != '\n') { - if (c != '\b') { - str[i++] = c; - putchar(c); - } else if (c == '\b' && i > 0) { - str[--i] = 0; - putchar(c); - } - c = getch(); - } - str[i] = '\0'; - putchar('\n'); - return str; -} diff --git a/libc/stdio/printf.c b/libc/stdio/printf.c deleted file mode 100644 index 03a9c93..0000000 --- a/libc/stdio/printf.c +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -int printf(const char* restrict format, ...) -{ - va_list parameters; - va_start(parameters, format); - - int written = 0; - size_t amount; - bool rejected_bad_specifier = false; - - while ( *format != '\0' ) { - if ( *format != '%' ) { - print_c: - amount = 1; - while ( format[amount] && format[amount] != '%' ) - amount++; - write(format, amount); - format += amount; - written += amount; - continue; - } - - const char* format_begun_at = format; - - if ( *(++format) == '%' ) - goto print_c; - - if ( rejected_bad_specifier ) { - incomprehensible_conversion: - rejected_bad_specifier = true; - format = format_begun_at; - goto print_c; - } - if ( *format == 'c' ) { - format++; - char c = (char) va_arg(parameters, int /* char promotes to int */); - write(&c, sizeof(c)); - } else if ( *format == 's' ) { - format++; - const char* s = va_arg(parameters, const char*); - call(1, (uint32_t) s, strlen(s), 0, 0, 0); - } else if ( *format == 'd' ) { - format++; - int n = va_arg(parameters, int); - if (n) { - char s[intlen(n, 10)]; - itoa(s, n, 10); - call(1, (uint32_t) s, strlen(s), 0, 0, 0); - } else { - printf("0"); - } - } else if ( *format == 'x') { - format++; - int n = va_arg(parameters, int); - if (n) { - char s[intlen(n, 16)]; - itoa(s, n, 16); - call(1, (uint32_t) s, strlen(s), 0, 0, 0); - } else { - printf("0x0"); - } - } else { - goto incomprehensible_conversion; - } - } - - va_end(parameters); - - return written; -} diff --git a/libc/stdio/putchar.c b/libc/stdio/putchar.c deleted file mode 100644 index cfc0869..0000000 --- a/libc/stdio/putchar.c +++ /dev/null @@ -1,8 +0,0 @@ -#include -#include -#include - -void putchar(char c) -{ - write_char(c); -} diff --git a/libc/stdio/puts.c b/libc/stdio/puts.c deleted file mode 100644 index b4cac29..0000000 --- a/libc/stdio/puts.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int puts(const char* string) -{ - return printf("%s\n", string); -} diff --git a/libc/stdlib/abort.c b/libc/stdlib/abort.c deleted file mode 100644 index 9f8745c..0000000 --- a/libc/stdlib/abort.c +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include -#include - -__attribute__((__noreturn__)) -void abort(void) -{ -#if __STDC_HOSTED__ - // TODO: Properly implement abort(). - exit(1); -#elif defined(__is_photon_kernel) - // TODO: Add proper kernel panic. - printf("Kernel Panic: abort()\n"); - while ( 1 ) { } -#else -#error "You need to implement abort() in this freestanding environment." -#endif - __builtin_unreachable(); -} diff --git a/libc/stdlib/exit.c b/libc/stdlib/exit.c deleted file mode 100644 index e167af4..0000000 --- a/libc/stdlib/exit.c +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include - -void exit(int status) -{ - while ( true ) - { - // TODO: Implement the exit system call. - (void) status; - } -} diff --git a/libc/stdlib/intlen.c b/libc/stdlib/intlen.c deleted file mode 100644 index fa78ac6..0000000 --- a/libc/stdlib/intlen.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -int intlen(int n, int base) -{ - int len; - for(len = 0; n != 0; n /= base, len++) {} - return len; -} diff --git a/libc/stdlib/itoa.c b/libc/stdlib/itoa.c deleted file mode 100644 index 3b27475..0000000 --- a/libc/stdlib/itoa.c +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include - -static void add_hex_prefix(char *buf) -{ - int len = strlen(buf); - for (int i = len - 1; i >= 0; i--) { - buf[i + 2] = buf[i]; - } - buf[len + 2] = '\0'; - buf[0] = '0'; - buf[1] = 'x'; -} - -void itoa(char *buf, unsigned long int n, int base) -{ - unsigned long int tmp; - int i; - - tmp = n; - i = 0; - - do { - tmp = n % base; - buf[i++] = (tmp < 10) ? (tmp + '0') : (tmp + 'a' - 10); - } while (n /= base); - buf[i] = '\0'; - - strrev(buf); - if (base == 16) { - add_hex_prefix(buf); - } -} diff --git a/libc/string/memcmp.c b/libc/string/memcmp.c deleted file mode 100644 index d8608f9..0000000 --- a/libc/string/memcmp.c +++ /dev/null @@ -1,13 +0,0 @@ -#include - -int memcmp(const void* aptr, const void* bptr, size_t size) -{ - const unsigned char* a = (const unsigned char*) aptr; - const unsigned char* b = (const unsigned char*) bptr; - for ( size_t i = 0; i < size; i++ ) - if ( a[i] < b[i] ) - return -1; - else if ( b[i] < a[i] ) - return 1; - return 0; -} diff --git a/all.sh b/src/all.sh similarity index 100% rename from all.sh rename to src/all.sh diff --git a/build.sh b/src/build.sh similarity index 100% rename from build.sh rename to src/build.sh diff --git a/clean.sh b/src/clean.sh similarity index 100% rename from clean.sh rename to src/clean.sh diff --git a/config.sh b/src/config.sh similarity index 100% rename from config.sh rename to src/config.sh diff --git a/default-host.sh b/src/default-host.sh similarity index 100% rename from default-host.sh rename to src/default-host.sh diff --git a/headers.sh b/src/headers.sh similarity index 100% rename from headers.sh rename to src/headers.sh diff --git a/iso.sh b/src/iso.sh similarity index 100% rename from iso.sh rename to src/iso.sh diff --git a/kernel/Makefile b/src/kernel/Makefile similarity index 88% rename from kernel/Makefile rename to src/kernel/Makefile index e5f6e02..4e30b83 100644 --- a/kernel/Makefile +++ b/src/kernel/Makefile @@ -1,7 +1,7 @@ HOST?=$(shell ../default-host.sh) HOSTARCH:=$(shell ../target-triplet-to-arch.sh $(HOST)) -CFLAGS?=-O2 -g +CFLAGS?=-O0 -g CPPFLAGS?= LDFLAGS?= LIBS?= -L../libc @@ -12,8 +12,8 @@ EXEC_PREFIX?=$(PREFIX) BOOTDIR?=$(EXEC_PREFIX)/boot INCLUDEDIR?=$(PREFIX)/include -CFLAGS:=$(CFLAGS) -ffreestanding -Wall -Wextra -CPPFLAGS:=$(CPPFLAGS) -D__is_photon_kernel -D_TEXTMODE -Iinclude -Iarch/i386/include -I../libc/include +CFLAGS:=$(CFLAGS) -ffreestanding -Wall -Wextra -fstack-protector-all +CPPFLAGS:=$(CPPFLAGS) -DBITMAP_FRAME_ALLOCATOR -D__is_photon_kernel -D_TEXTMODE -Iinclude -Iarch/i386/include -I../libc/include LDFLAGS:=$(LDFLAGS) LIBS:=$(LIBS) -nostdlib -lk -lgcc @@ -31,15 +31,17 @@ init/icxxabi.o \ init/kernel_class.o \ $(KERNEL_ARCH_OBJS) \ system/cpu.o \ -system/task.o \ drivers/keyboard.o \ drivers/io.o \ drivers/vga.o \ -system/kheap.o \ -init/init.o \ init/main.o \ system/system.o \ system/time.o \ +system/task.o \ +system/heap.o \ +system/ui.o \ +system/shell.o \ +system/stack_protector.o \ CRTI_OBJ:=$(ARCHDIR)/crti.o CRTBEGIN_OBJ:=$(shell $(CC) $(CFLAGS) $(LDFLAGS) -print-file-name=crtbegin.o) diff --git a/src/kernel/arch/i386/a20.asm b/src/kernel/arch/i386/a20.asm new file mode 100644 index 0000000..3a80b9e --- /dev/null +++ b/src/kernel/arch/i386/a20.asm @@ -0,0 +1,48 @@ +[bits 32] +[section .text] + +[global enable_A20] +enable_A20: + cli + + call a20wait + mov al,0xAD + out 0x64,al + + call a20wait + mov al,0xD0 + out 0x64,al + + call a20wait2 + in al,0x60 + push eax + + call a20wait + mov al,0xD1 + out 0x64,al + + call a20wait + pop eax + or al,2 + out 0x60,al + + call a20wait + mov al,0xAE + out 0x64,al + + call a20wait + sti + ret + +a20wait: + in al,0x64 + test al,2 + jnz a20wait + ret + + +a20wait2: + in al,0x64 + test al,1 + jz a20wait2 + ret diff --git a/kernel/arch/i386/boot/boot.asm b/src/kernel/arch/i386/boot/boot.asm similarity index 62% rename from kernel/arch/i386/boot/boot.asm rename to src/kernel/arch/i386/boot/boot.asm index ee689cb..6799987 100644 --- a/kernel/arch/i386/boot/boot.asm +++ b/src/kernel/arch/i386/boot/boot.asm @@ -17,15 +17,17 @@ CHECKSUM equ -(MAGIC + FLAGS) section .multiboot align 4 - dd MAGIC - dd FLAGS - dd CHECKSUM + dd MAGIC + dd FLAGS + dd CHECKSUM ; reserve space for kernel stack section .bootstrap_stack -align 4 + align 4 +global stack_bottom stack_bottom: -times 16384 db 0 + times 16384 db 0 + global stack_top stack_top: @@ -33,13 +35,20 @@ stack_top: section .text global _start _start: - mov esp, stack_top ; set stack - push esp ; push stack pointer - push ebx ; push multiboot structure - cli - extern kmain - call kmain ; let's GO!!! - cli ; if kmain ends, disable interrupts and go to infinite loop + extern kernel_main + extern kernel_init + + mov esp, stack_top ; set stack + push esp ; push stack pointer + push ebx ; push multiboot structure + + cli + + call kernel_init + call kernel_main + + cli ; if kmain ends, disable interrupts and go to infinite loop + .hang: - hlt ; if I am here, something went wrong :P - jmp .hang + hlt ; if I am here, something went wrong :P + jmp .hang diff --git a/src/kernel/arch/i386/crti.S b/src/kernel/arch/i386/crti.S new file mode 100644 index 0000000..06112f9 --- /dev/null +++ b/src/kernel/arch/i386/crti.S @@ -0,0 +1,15 @@ +.section .init +.global _init +.type _init, @function +_init: + push %ebp + movl %esp, %ebp + /* gcc will nicely put the contents of crtbegin.o's .init section here. */ + +.section .fini +.global _fini +.type _fini, @function +_fini: + push %ebp + movl %esp, %ebp + /* gcc will nicely put the contents of crtbegin.o's .fini section here. */ diff --git a/src/kernel/arch/i386/crtn.S b/src/kernel/arch/i386/crtn.S new file mode 100644 index 0000000..0d58006 --- /dev/null +++ b/src/kernel/arch/i386/crtn.S @@ -0,0 +1,9 @@ +.section .init + /* gcc will nicely put the contents of crtend.o's .init section here. */ + popl %ebp + ret + +.section .fini + /* gcc will nicely put the contents of crtend.o's .fini section here. */ + popl %ebp + ret diff --git a/kernel/arch/i386/descriptor_tables.asm b/src/kernel/arch/i386/descriptor_tables.asm similarity index 94% rename from kernel/arch/i386/descriptor_tables.asm rename to src/kernel/arch/i386/descriptor_tables.asm index 7bfff94..afc942b 100644 --- a/kernel/arch/i386/descriptor_tables.asm +++ b/src/kernel/arch/i386/descriptor_tables.asm @@ -34,12 +34,12 @@ idt_flush: [GLOBAL tss_flush] tss_flush: - mov ax, 0x2B - ltr ax - ret - + mov ax, 0x2B + ltr ax + ret + [GLOBAL read_eip] read_eip: - pop eax - jmp eax + pop eax + jmp eax diff --git a/kernel/arch/i386/gdt.c b/src/kernel/arch/i386/gdt.c similarity index 91% rename from kernel/arch/i386/gdt.c rename to src/kernel/arch/i386/gdt.c index 08f6b95..9ab40d7 100644 --- a/kernel/arch/i386/gdt.c +++ b/src/kernel/arch/i386/gdt.c @@ -7,12 +7,15 @@ * any later version. */ -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include + +gdt_entry_t gdt_entries[5]; +gdt_ptr_t gdt_ptr; +tss_entry_t tss_entry; void init_gdt() { diff --git a/kernel/arch/i386/handlers.c b/src/kernel/arch/i386/handlers.c similarity index 78% rename from kernel/arch/i386/handlers.c rename to src/kernel/arch/i386/handlers.c index 256ad77..bf3dc6b 100644 --- a/kernel/arch/i386/handlers.c +++ b/src/kernel/arch/i386/handlers.c @@ -1,13 +1,18 @@ -#include -#include -#include #include -#include -#include -#include +#include +#include +#include +#include +int tick; isr_t interrupt_handlers[256]; +void std_handler(registers_t *regs) +{ + print_regs(regs); + panic("Unsupported error occured.\n", __LINE__, __FILE__); +} + void init_irq() { outb(0x20, 0x11); @@ -41,31 +46,31 @@ void init_irq() void irq_handler(registers_t regs) { - cli(); - // If interrupt involve the slave - if (regs.int_no >= 40) { - // Send reset signal. - outb(0xA0, 0x20); - } + cli(); + // If interrupt involve the slave + if (regs.int_no >= 40) { + // Send reset signal. + outb(0xA0, 0x20); + } - // Reset signal to master. - outb(0x20, 0x20); + // Reset signal to master. + outb(0x20, 0x20); - if (interrupt_handlers[regs.int_no] != 0) { - isr_t handler = interrupt_handlers[regs.int_no]; - handler(®s); - } - sti(); + if (interrupt_handlers[regs.int_no] != 0) { + isr_t handler = interrupt_handlers[regs.int_no]; + handler(®s); + } + sti(); } static void zero_division_handler(__attribute__((unused)) registers_t *regs) { - panic("Division by 0!", __LINE__, __FILE__); + panic("Division by 0!", __LINE__, __FILE__); } void init_isr() { - idt_set_gate( 0, (uint32_t)isr0 , 0x08, 0x8E); + idt_set_gate( 0, (uint32_t)isr0 , 0x08, 0x8E); idt_set_gate( 1, (uint32_t)isr1 , 0x08, 0x8E); idt_set_gate( 2, (uint32_t)isr2 , 0x08, 0x8E); idt_set_gate( 3, (uint32_t)isr3 , 0x08, 0x8E); @@ -99,6 +104,10 @@ void init_isr() idt_set_gate(31, (uint32_t)isr31, 0x08, 0x8E); idt_set_gate(128, (uint32_t)isr128, 0x08, 0x8E); + for (int i = 0; i < 256; i++) { + register_interrupt_handler(i, &std_handler); + } + register_interrupt_handler(0, &zero_division_handler); register_interrupt_handler(128, &syscall_handler); } @@ -106,13 +115,13 @@ void init_isr() // This gets called from our ASM interrupt handler stub. void isr_handler(registers_t regs) { - cli(); - regs.int_no &= 0xFF; - interrupt_handlers[regs.int_no](®s); - sti(); + cli(); + regs.int_no &= 0xFF; + interrupt_handlers[regs.int_no](®s); + sti(); } void register_interrupt_handler(uint8_t n, isr_t handler) { - interrupt_handlers[n] = handler; + interrupt_handlers[n] = handler; } diff --git a/kernel/arch/i386/idt.c b/src/kernel/arch/i386/idt.c similarity index 77% rename from kernel/arch/i386/idt.c rename to src/kernel/arch/i386/idt.c index c216f59..02d44dd 100644 --- a/kernel/arch/i386/idt.c +++ b/src/kernel/arch/i386/idt.c @@ -7,18 +7,19 @@ * any later version. */ -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include + +idt_entry_t idt_entries[256]; +idt_ptr_t idt_ptr; static void unhandled_interrupt(__attribute__((unused)) registers_t *regs) { - print_regs(regs); - panic("Interrupt unhandled!", __LINE__, __FILE__); + print_regs(regs); + panic("Interrupt unhandled!", __LINE__, __FILE__); } void init_idt() @@ -28,12 +29,12 @@ void init_idt() memset(&idt_entries, 0, sizeof(idt_entry_t)*256); - for (int n = 0; n < 256; n++) { - register_interrupt_handler(n, &unhandled_interrupt); - } + for (int n = 0; n < 256; n++) { + register_interrupt_handler(n, &unhandled_interrupt); + } - init_isr(); - init_irq(); + init_isr(); + init_irq(); idt_flush((uint32_t)&idt_ptr); } diff --git a/kernel/arch/i386/include/gdt.h b/src/kernel/arch/i386/include/gdt.h similarity index 96% rename from kernel/arch/i386/include/gdt.h rename to src/kernel/arch/i386/include/gdt.h index 72bdc5c..711b185 100644 --- a/kernel/arch/i386/include/gdt.h +++ b/src/kernel/arch/i386/include/gdt.h @@ -17,10 +17,11 @@ #ifndef _gdt_h #define _gdt_h -#include -#include -#include #include +#include +#include +#include +#include /* The GDT */ @@ -83,8 +84,6 @@ struct tss_entry_struct } __attribute__((packed)); typedef struct tss_entry_struct tss_entry_t; -tss_entry_t tss_entry; - /** * Flush the TSS. */ @@ -100,9 +99,6 @@ void write_tss(int32_t num, uint16_t ss0, uint32_t esp0); */ void set_kernel_stack(uint32_t stack); -gdt_entry_t gdt_entries[5]; -gdt_ptr_t gdt_ptr; - /** * Flush the GDT. Extern function implemented in 'asm_dt.asm'. */ diff --git a/kernel/arch/i386/include/handlers.h b/src/kernel/arch/i386/include/handlers.h similarity index 97% rename from kernel/arch/i386/include/handlers.h rename to src/kernel/arch/i386/include/handlers.h index eab5020..4fe54c9 100644 --- a/kernel/arch/i386/include/handlers.h +++ b/src/kernel/arch/i386/include/handlers.h @@ -16,9 +16,11 @@ #ifndef _handlers_h #define _handlers_h -#include -#include #include +#include +#include +#include +#include /** * Initialize the ISR. @@ -65,8 +67,6 @@ extern void isr30(); extern void isr31(); extern void isr128(); -extern isr_t interrupt_handlers[256]; - #define IRQ0 32 // Programmable Interrupt Timer Interrupt (handled) #define IRQ1 33 // Keyboard Interrupt (handled) #define IRQ2 34 // Cascade (used internally by the two PICs. never raised) diff --git a/kernel/arch/i386/include/idt.h b/src/kernel/arch/i386/include/idt.h similarity index 80% rename from kernel/arch/i386/include/idt.h rename to src/kernel/arch/i386/include/idt.h index c0ddca3..028aa75 100644 --- a/kernel/arch/i386/include/idt.h +++ b/src/kernel/arch/i386/include/idt.h @@ -14,10 +14,11 @@ #ifndef _idt_h #define _idt_h -#include -#include -#include #include +#include +#include +#include +#include /* The IDT */ @@ -26,11 +27,11 @@ */ struct idt_entry_struct { - uint16_t base_lo; - uint16_t sel; - uint8_t always0; - uint8_t flags; - uint16_t base_hi; + uint16_t base_lo; + uint16_t sel; + uint8_t always0; + uint8_t flags; + uint16_t base_hi; } __attribute__((packed)); typedef struct idt_entry_struct idt_entry_t; @@ -39,14 +40,11 @@ typedef struct idt_entry_struct idt_entry_t; */ struct idt_ptr_struct { - uint16_t limit; - uint32_t base; + uint16_t limit; + uint32_t base; } __attribute__((packed)); typedef struct idt_ptr_struct idt_ptr_t; -idt_entry_t idt_entries[256]; -idt_ptr_t idt_ptr; - /** * Flush the IDT. Extern function implemented in 'asm_dt.asm'. */ diff --git a/kernel/arch/i386/include/pic.h b/src/kernel/arch/i386/include/pic.h similarity index 100% rename from kernel/arch/i386/include/pic.h rename to src/kernel/arch/i386/include/pic.h diff --git a/kernel/arch/i386/include/pit.h b/src/kernel/arch/i386/include/pit.h similarity index 91% rename from kernel/arch/i386/include/pit.h rename to src/kernel/arch/i386/include/pit.h index 9068d63..ecc22fe 100644 --- a/kernel/arch/i386/include/pit.h +++ b/src/kernel/arch/i386/include/pit.h @@ -14,11 +14,11 @@ #ifndef _clock_h #define _clock_h -#include -#include -#include #include - +#include +#include +#include +#include /** * Function called by PIT handler. */ diff --git a/src/kernel/arch/i386/include/pmm.h b/src/kernel/arch/i386/include/pmm.h new file mode 100644 index 0000000..1534df9 --- /dev/null +++ b/src/kernel/arch/i386/include/pmm.h @@ -0,0 +1,38 @@ +/* Paging driver header + * + * Copyright (c) 2015 Feraru Mihail (mihailferaru2000@gmail.com). + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * Contains declarations of functions for pmm driver and pmm structures. + * pmm is one of the memory management schemes by which a computer stores + * and retrieves data from the secondary storage for use in main memory. + * Structures: + * - page: structure used to store details about a block of memory + * - page table: structure used to store 1024 pages + * - page directory: structure used to store 1024 page entries and their + * physical addresses, in addition it stores physical address that will be loaded + * into CR3. + */ + +#ifndef _pmm_h +#define _pmm_h + +#include +#include +#include +#include +#include + +#define FRAME_SIZE 0x1000 +#define PAGE_ALIGN(x) (x & 0xFFFFF000) + +void init_pmm(uint32_t mem_size); +uint32_t find_frame(); +uint32_t alloc_frame(); +void free_frame(uint32_t address); + +#endif + diff --git a/src/kernel/arch/i386/include/vmm.h b/src/kernel/arch/i386/include/vmm.h new file mode 100644 index 0000000..4815353 --- /dev/null +++ b/src/kernel/arch/i386/include/vmm.h @@ -0,0 +1,35 @@ +#ifndef _vmm_h +#define _vmm_h + +#include +#include +#include +#include +#include + +#define PAGE_PRESENT 0x1 +#define PAGE_READ_WRITE 0x2 +#define PAGE_USER 0x4 +#define PAGE_WRITE_THROUGH 0x8 +#define PAGE_CACHE_DISABLE 0x16 +#define PAGE_ACCESSED 0x32 +#define PAGE_DIRTY 0x64 +#define PAGE_GLOBAL 0x128 + +typedef struct page_table { + uint32_t pages[1024]; +} page_table_t; + +typedef struct page_directory { + uint32_t phys_tables[1024]; + page_table_t *virt_tables[1024]; +} page_directory_t; + +void init_vmm(); +void switch_page_directory(page_directory_t *dir); +void enable_paging(); +void map(uint32_t va, uint32_t pa, uint32_t flags); +void unmap(uint32_t va); +void page_fault_handler(registers_t *regs); + +#endif diff --git a/kernel/arch/i386/interrupt.asm b/src/kernel/arch/i386/interrupt.asm similarity index 100% rename from kernel/arch/i386/interrupt.asm rename to src/kernel/arch/i386/interrupt.asm diff --git a/src/kernel/arch/i386/linker.ld b/src/kernel/arch/i386/linker.ld new file mode 100644 index 0000000..161dfd0 --- /dev/null +++ b/src/kernel/arch/i386/linker.ld @@ -0,0 +1,32 @@ +ENTRY(_start) + +SECTIONS +{ + . = 0x100000; + kernel_start = .; + + .text BLOCK(4K) : ALIGN(4K) + { + *(.multiboot) + *(.text) + } + + .rodata BLOCK(4K) : ALIGN(4K) + { + *(.rodata) + } + + .data BLOCK(4K) : ALIGN(4K) + { + *(.data) + } + + .bss BLOCK(4K) : ALIGN(4K) + { + *(COMMON) + *(.bss) + *(.bootstrap_stack) + } + + kernel_end = .; +} diff --git a/kernel/arch/i386/make.config b/src/kernel/arch/i386/make.config similarity index 84% rename from kernel/arch/i386/make.config rename to src/kernel/arch/i386/make.config index 3aed067..6abb644 100644 --- a/kernel/arch/i386/make.config +++ b/src/kernel/arch/i386/make.config @@ -11,6 +11,8 @@ $(ARCHDIR)/idt.o \ $(ARCHDIR)/interrupt.o \ $(ARCHDIR)/handlers.o \ $(ARCHDIR)/page.o \ -$(ARCHDIR)/paging.o \ +$(ARCHDIR)/pmm.o \ +$(ARCHDIR)/vmm.o \ $(ARCHDIR)/pit.o \ $(ARCHDIR)/pic.o \ +$(ARCHDIR)/a20.o \ diff --git a/src/kernel/arch/i386/page.asm b/src/kernel/arch/i386/page.asm new file mode 100644 index 0000000..4fea1e7 --- /dev/null +++ b/src/kernel/arch/i386/page.asm @@ -0,0 +1,34 @@ +[global flush_tlb] +flush_tlb: + push ebx + mov cr3, ebx + mov ebx, cr3 + pop ebx + +[global read_cr0] +read_cr0: + mov eax, cr0 + retn + +[global write_cr0] +write_cr0: + push ebp + mov ebp, esp + mov eax, [ebp+8] + mov cr0, eax + pop ebp + retn + +[global read_cr3] +read_cr3: + mov eax, cr3 + retn + +[global write_cr3] +write_cr3: + push ebp + mov ebp, esp + mov eax, [ebp+8] + mov cr3, eax + pop ebp + retn diff --git a/kernel/arch/i386/pic.c b/src/kernel/arch/i386/pic.c similarity index 84% rename from kernel/arch/i386/pic.c rename to src/kernel/arch/i386/pic.c index 3ae65fd..db33f96 100644 --- a/kernel/arch/i386/pic.c +++ b/src/kernel/arch/i386/pic.c @@ -1,6 +1,8 @@ -#include -#include -#include +#include +#include +#include +#include +#include void IRQ_set_mask(unsigned char IRQline) { uint16_t port; diff --git a/kernel/arch/i386/pit.c b/src/kernel/arch/i386/pit.c similarity index 83% rename from kernel/arch/i386/pit.c rename to src/kernel/arch/i386/pit.c index 21a924d..8ff22aa 100644 --- a/kernel/arch/i386/pit.c +++ b/src/kernel/arch/i386/pit.c @@ -7,27 +7,25 @@ * any later version. */ -#include -#include -#include -#include -#include +#include #include #include -#include -#include -#include -#include +#include +#include -int tick; +extern mem_heap_t *kernel_heap; +extern int tick; +extern volatile int in_size; void timer_callback(__attribute__ ((unused)) registers_t *regs) { - cli(); - tick++; - update_time(); - //preempt(); useless, because it crashes - sti(); + cli(); + tick++; + update_time(); + if (in_size >= STDIO_SIZE) { + in_size = 0; + } + sti(); } void init_timer(uint32_t frequency) @@ -56,5 +54,5 @@ void init_timer(uint32_t frequency) int get_tick() { - return tick; + return tick; } diff --git a/src/kernel/arch/i386/pmm.c b/src/kernel/arch/i386/pmm.c new file mode 100644 index 0000000..205844c --- /dev/null +++ b/src/kernel/arch/i386/pmm.c @@ -0,0 +1,75 @@ +/* Paging driver + * + * Copyright (c) 2015 Feraru Mihail (mihailferaru2000@gmail.com). + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include +#include +#include +#include +#include + +uint32_t phys_ram_bytes; +uint32_t phys_ram_kb; +uint32_t phys_ram_mb; +uint32_t phys_ram_gb; +uint32_t placement_addr = (uint32_t) &kernel_end; +int paging_enabled = 0; + +#ifdef BITMAP_FRAME_ALLOCATOR + +#include + +uint32_t nframes; +uint32_t *frames; +uint32_t free_frames; + +void init_pmm(uint32_t mem_size) +{ + nframes = (mem_size * 1024) / FRAME_SIZE; + frames = kmalloc(sizeof(uint32_t) * nframes / 8 + + sizeof(uint32_t) * nframes % 8, + 0, + 0); + free_frames = nframes; + + for (uint32_t i = 0; i < nframes; i++) { + free_bit(frames, i); + } +} + +uint32_t find_frame() +{ + for (uint32_t i = 0; i < nframes; i++) { + if (test_bit(frames, i)) { + return i; + } + } + return -1; +} + +uint32_t alloc_frame() +{ + int frame_index = find_frame(); + if (frame_index != -1) { + use_bit(frames, frame_index); + free_frames--; + return frame_index * FRAME_SIZE; + } + + panic("No free frames!", __LINE__, __FILE__); + return -1; +} + +void free_frame(uint32_t address) +{ + uint32_t frame_index = address / FRAME_SIZE; + free_bit(frames, frame_index); + free_frames++; +} + +#endif diff --git a/src/kernel/arch/i386/vmm.c b/src/kernel/arch/i386/vmm.c new file mode 100644 index 0000000..71cead8 --- /dev/null +++ b/src/kernel/arch/i386/vmm.c @@ -0,0 +1,97 @@ +#include +#include +#include +#include +#include + +extern uint32_t placement_addr; +extern uint32_t paging_enabled; + +page_directory_t *kernel_directory; +page_directory_t *current_directory; +multiboot *kernel_mboot; +uint32_t kernel_init_stack; +uint32_t init_esp; +uint32_t mapped_pages; + +static void map_area(uint32_t from_va, uint32_t to_va) +{ + for (uint32_t va = from_va; va < to_va; va += 0x1000) { + uint32_t pa = alloc_frame(); + map(va, pa, PAGE_READ_WRITE | PAGE_PRESENT); + } +} + +void init_vmm() +{ + mapped_pages = 0; + + register_interrupt_handler(14, page_fault_handler); + + kernel_directory = kmalloc(sizeof(page_directory_t), 1, 0); + memset(kernel_directory, 0, sizeof(page_directory_t)); + + for (int i = 0; i < 1024; i++) { + kernel_directory->phys_tables[i] = 0x0 | PAGE_READ_WRITE; + } + + current_directory = kernel_directory; + + // Map kernel + 1 MiB + uint32_t mem_to_map = (size_t) &kernel_end + 0x10000; + map_area(0x0, mem_to_map); + + switch_page_directory(kernel_directory); + enable_paging(); +} + +void switch_page_directory(page_directory_t *dir) +{ + current_directory = dir; + write_cr3(current_directory); +} + +void enable_paging() +{ + uint32_t cr0 = read_cr0(); + cr0 |= 0x80000000; + write_cr0(cr0); + paging_enabled = 1; +} + +void map(uint32_t va, uint32_t pa, uint32_t flags) +{ + uint32_t page_num = (va / 4096) % 1024; + uint32_t table_num = (va / 4096) / 1024; + + if (!current_directory->virt_tables[table_num]) { + uint32_t phys; + current_directory->virt_tables[table_num] = kmalloc(sizeof(page_table_t), + 1, + &phys); + + current_directory->phys_tables[table_num] = phys | PAGE_READ_WRITE | PAGE_PRESENT; + } + current_directory->virt_tables[table_num]->pages[page_num] = pa | flags; + mapped_pages++; +} + +void unmap(uint32_t va) +{ + uint32_t page_num = (va / 4096) % 1024; + uint32_t table_num = (va / 4096) / 1024; + + current_directory->virt_tables[table_num]->pages[page_num] = 0x0; + + asm volatile ("invlpg (%0)" : : "a" (va)); + mapped_pages--; +} + +void page_fault_handler(registers_t *regs) +{ + uint32_t cr2; + asm volatile ("mov %%cr2, %0": "=r" (cr2)); + printk("Page fault at %x, faulting address %x\n", regs->eip, cr2); + printk("Error code %x\n", regs->err_code); + panic("Core dumb.\n", __LINE__, __FILE__); +} diff --git a/src/kernel/drivers/io.c b/src/kernel/drivers/io.c new file mode 100644 index 0000000..417e26a --- /dev/null +++ b/src/kernel/drivers/io.c @@ -0,0 +1,158 @@ +/* Basic input/output + * + * Copyright (c) 2015 Feraru Mihail (mihailferaru2000@gmail.com). + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include +#include +#include +#include +#include + +/* output byte */ +void outb(uint32_t ad, uint8_t v) +{ + asm volatile("outb %%al, %%dx" :: "d" (ad), "a" (v));; +} +/* output word */ +void outw(uint32_t ad, uint16_t v) +{ + asm volatile("outw %%ax, %%dx" :: "d" (ad), "a" (v)); +} +/* output word */ +void outl(uint32_t ad, uint32_t v) +{ + asm volatile("outl %%eax, %%dx" : : "d" (ad), "a" (v)); +} +/* input byte */ +uint8_t inb(uint32_t ad) +{ + uint8_t _v; + asm volatile("inb %%dx, %%al" : "=a" (_v) : "d" (ad)); + return _v; +} +/* input word */ +uint16_t inw(uint32_t ad) +{ + uint16_t _v; + asm volatile("inw %%dx, %%ax" : "=a" (_v) : "d" (ad)); + return _v; +} +/* input word */ +uint32_t inl(uint32_t ad) +{ + uint32_t _v; + asm volatile("inl %%dx, %%eax" : "=a" (_v) : "d" (ad)); + return _v; +} + +void print_regs(registers_t *regs) +{ + printk("\nds: %d\tedi: %d\tesi: %d\n", regs->ds, regs->edi, regs->esi); + printk("ebp: %d\tesp: %d\tebx: %d\n", regs->ebp, regs->esp, regs->ebx); + printk("edx: %d\tecx: %d\teax: %d\n", regs->edx, regs->ecx, regs->eax); + printk("eip: %d\tcs: %d\teflags: %d\n", regs->eip, regs->cs, regs->eflags); + printk("useresp: %d\tss: %d\n", regs->useresp, regs->ss); + printk("int_no: %d\terr_code: %d\n\n", regs->int_no, regs->err_code); +} + +int write_char(const char c) +{ + //((unsigned char*) stdout)[out_crs] = c; + //out_crs++; + vga_putchar(c); // temp + return 0; +} + +int write(const char *buf, size_t len) +{ + for ( size_t i = 0; i < len; i++ ) + write_char((int) ((const char*) buf)[i]); + return 0; +} + +int printk(const char* format, ...) +{ + va_list parameters; + va_start(parameters, format); + + int written = 0; + size_t amount; + bool rejected_bad_specifier = false; + + while ( *format != '\0' ) { + if ( *format != '%' ) { + print_c: + amount = 1; + while ( format[amount] && format[amount] != '%' ) + amount++; + write(format, amount); + format += amount; + written += amount; + continue; + } + + const char* format_begun_at = format; + + if ( *(++format) == '%' ) + goto print_c; + + if ( rejected_bad_specifier ) { + incomprehensible_conversion: + rejected_bad_specifier = true; + format = format_begun_at; + goto print_c; + } + if ( *format == 'c' ) { + format++; + char c = (char) va_arg(parameters, int /* char promotes to int */); + write(&c, sizeof(c)); + } else if ( *format == 's' ) { + format++; + const char* s = va_arg(parameters, const char*); + write(s, strlen(s)); + } else if ( *format == 'd' ) { + format++; + int n = va_arg(parameters, int); + if (n) { + char s[intlen(n, 10)]; + itoa(s, n, 10); + write(s, strlen(s)); + } else { + putchar('0'); + } + } else if ( *format == 'x') { + format++; + int n = va_arg(parameters, int); + if (n) { + char s[intlen(n, 16)]; + itoa(s, n, 16); + write(s, strlen(s)); + } else { + printk("0x0"); + } + } else { + goto incomprehensible_conversion; + } + } + + va_end(parameters); + return written; +} + +void call(int32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx, uint32_t esi, uint32_t edi) +{ + asm volatile (" \ + movl %0, %%eax; \ + movl %1, %%ebx; \ + movl %2, %%ecx; \ + movl %3, %%edx; \ + movl %4, %%esi; \ + movl %5, %%edi; \ + int $0x80; \ + " : : "r" (eax) , "r" (ebx) , "r" (ecx) , "r" (edx) , "r" (esi) , "r" (edi)); +} diff --git a/kernel/drivers/keyboard.c b/src/kernel/drivers/keyboard.c similarity index 53% rename from kernel/drivers/keyboard.c rename to src/kernel/drivers/keyboard.c index f40c15c..52789c1 100644 --- a/kernel/drivers/keyboard.c +++ b/src/kernel/drivers/keyboard.c @@ -7,17 +7,16 @@ * any later version. */ -#include -#include #include -#include +#include #include -#include -#include +#include +#include - /* USA keyboard. */ -// Non-Shifted scancodes to ASCII: -static char USasciiNonShift[] = { +void (*keyboard_handler)(uint8_t *buf, uint16_t size); + +// Keyboard map +char USasciiNonShift[] = { 0, ESC, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', BACKSPACE, TAB, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', ENTER, 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\', @@ -26,7 +25,7 @@ KF1, KF2, KF3, KF4, KF5, KF6, KF7, KF8, KF9, KF10, 0, 0, KHOME, KUP, KPGUP,'-', KLEFT, '5', KRIGHT, '+', KEND, KDOWN, KPGDN, KINS, KDEL, 0, 0, 0, KF11, KF12 }; // Shifted scancodes to ASCII: -static char USasciiShift[] = { +char USasciiShift[] = { 0, ESC, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', BACKSPACE, TAB, 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', ENTER, 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '\"', '~', 0, '|', @@ -34,59 +33,68 @@ TAB, 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', ENTER, 0, KF1, KF2, KF3, KF4, KF5, KF6, KF7, KF8, KF9, KF10, 0, 0, KHOME, KUP, KPGUP, '-', KLEFT, '5', KRIGHT, '+', KEND, KDOWN, KPGDN, KINS, KDEL, 0, 0, 0, KF11, KF12 }; +uint8_t kb_buffer[KEYBOARD_BUFFER_SIZE]; +int last; +int shift; +char *ascii_s; +char *ascii_S; + +extern void *stdin; +extern uint32_t in_size; + void install_keyboard() { - in_size = 0; - - ascii_s = USasciiNonShift; - ascii_S = USasciiShift; - last = 0; - - keyboard_set_handler(&read_kb_buff); - register_interrupt_handler(IRQ1, &keyboard_interrupt_handler); + in_size = 0; + + ascii_s = USasciiNonShift; + ascii_S = USasciiShift; + last = 0; + + keyboard_set_handler(&read_kb_buff); + register_interrupt_handler(IRQ1, &keyboard_interrupt_handler); } void keyboard_set_handler(void (*callback)(uint8_t *buf, uint16_t size)) { - keyboard_handler = callback; + keyboard_handler = callback; } void keyboard_interrupt_handler(__attribute__ ((unused)) registers_t *regs) { - uint8_t scancode = inb(0x60); - int special = 0; - - if (scancode & 0x80) { - scancode &= 0x7F; - if (scancode == KRLEFT_SHIFT || scancode == KRRIGHT_SHIFT) { - shift = 0; - special = 1; - } - } else { - if (scancode == KRLEFT_SHIFT || scancode == KRRIGHT_SHIFT) { - shift = 1; - special = 1; - } - - if (shift) { - kb_buffer[last++] = ascii_S[scancode]; - } else { - kb_buffer[last++] = ascii_s[scancode]; - } - - if (special != 1) { - cli(); - keyboard_handler(kb_buffer, last); - sti(); - } - - if (last == KEYBOARD_BUFFER_SIZE) { - last = 0; - } - } + cli(); + uint8_t scancode = inb(0x60); + int special = 0; + + if (scancode & 0x80) { + scancode &= 0x7F; + if (scancode == KRLEFT_SHIFT || scancode == KRRIGHT_SHIFT) { + shift = 0; + special = 1; + } + } else { + if (scancode == KRLEFT_SHIFT || scancode == KRRIGHT_SHIFT) { + shift = 1; + special = 1; + } + + if (shift) { + kb_buffer[last++] = ascii_S[scancode]; + } else { + kb_buffer[last++] = ascii_s[scancode]; + } + + if (special != 1) { + keyboard_handler(kb_buffer, last); + } + + if (last == KEYBOARD_BUFFER_SIZE) { + last = 0; + } + } + sti(); } void read_kb_buff(uint8_t *buf, uint16_t size) { - ((uint8_t*) stdin)[in_size] = buf[size - 1]; + ((uint8_t*) stdin)[in_size] = buf[size - 1]; } diff --git a/src/kernel/drivers/vga.c b/src/kernel/drivers/vga.c new file mode 100644 index 0000000..12d5133 --- /dev/null +++ b/src/kernel/drivers/vga.c @@ -0,0 +1,190 @@ +/* VGA driver + * + * Copyright (c) 2015 Feraru Mihail (mihailferaru2000@gmail.com). + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include +#include +#include +#include +#include + +uint16_t *vga_memory; +#ifdef _TEXTMODE +int tabstop; +size_t row; +size_t col; +enum vga_color default_bg = COLOR_BLACK; +enum vga_color default_fg = COLOR_LIGHT_GREY; +static const size_t VGA_WIDTH = 80; +static const size_t VGA_HEIGHT = 25; +#endif + +extern void cmd_dbg(); + +#ifdef _TEXTMODE +uint8_t make_color(enum vga_color fg, enum vga_color bg) +{ + return fg | bg << 4; +} + +uint16_t make_vgaentry(char c, uint8_t color) +{ + uint16_t c16 = c; + uint16_t color16 = color; + return c16 | color16 << 8; +} +#endif + +void init_vga() +{ + #ifdef _TEXTMODE + vga_memory = (uint16_t*) 0xB8000; + row = 0; + col = 0; + tabstop = 4; + default_bg = COLOR_BLACK; + default_fg = COLOR_LIGHT_GREY; + clear_vga(); + #endif +} + +void clear_vga() +{ + #ifdef _TEXTMODE + for ( size_t y = 0; y < VGA_HEIGHT; y++ ) + { + for ( size_t x = 0; x < VGA_WIDTH; x++ ) + { + const size_t index = y * VGA_WIDTH + x; + ((uint16_t*) vga_memory)[index] = make_vgaentry(' ', make_color(default_fg, default_bg)); + } + } + row = 0; + col = 0; + vga_move_cursor(row, col); + #endif +} + +int vga_scroll(size_t *row) +{ + #ifdef _TEXTMODE + uint16_t blank = make_vgaentry(' ', make_color(default_fg, default_bg)); + + if (*row >= 25) + { + int temp = *row - 25 + 1; + memcpy ((uint16_t*) vga_memory, (uint16_t*) vga_memory + temp * 80, (25 - temp) * 80 * 2); + + memsetw ((uint16_t*) vga_memory + (25 - temp) * 80, blank, 80); + *row = 24; + } + vga_move_cursor(*row, col); + return 0; + #endif +} + +#ifdef _TEXTMODE +void vga_setcolor(enum vga_color fg, enum vga_color bg) +{ + default_bg = bg; + default_fg = fg; +} + +void vga_putentryat(char c, uint8_t color, size_t x, size_t y) +{ + const size_t index = y * VGA_WIDTH + x; + ((uint16_t*) vga_memory)[index] = make_vgaentry(c, color); +} +#endif + +void vga_putchar(char c) +{ + #ifdef _TEXTMODE + switch (c) { + case '\n': + row++; + col = -1; + break; + case '\t': + for (int i = 1; i < tabstop; i++) { + vga_putchar(' '); + } + break; + case '\b': + vga_putentryat(' ', make_color(default_fg, default_bg), --col, row); + --col; + break; + case '~': + printk("[INFO] Halt char printed.\n STOP."); + keep_running(); + break; + case '`': + cmd_dbg(); + break; + case 0: + printk("!000!"); + break; + default: + vga_putentryat(c, make_color(default_fg, default_bg), col, row); + break; + } + if (++col >= 80) { + col = -1; + ++row; + } + vga_scroll(&row); + vga_move_cursor(row, col + 1); + #endif +} + +void vga_writestring(const char* data) +{ + #ifdef _TEXTMODE + size_t datalen = strlen(data); + for ( size_t i = 0; i < datalen; i++ ) + vga_putchar(data[i]); + #endif +} + +#ifdef _TEXTMODE +void vga_set_tab(int size) +{ + tabstop = size; +} + +void vga_move_cursor(int row, int column) +{ + uint16_t cursor_pos = row * 80 + column - 1; + outb(0x3D4, 14); + outb(0x3D5, cursor_pos >> 8); + outb(0x3D4, 15); + outb(0x3D5, cursor_pos); +} +#endif + +void vga_putchar_color(char c, enum vga_color fg) +{ + #ifdef _TEXTMODE + uint8_t temp_color = default_fg; + default_fg = fg; + vga_putchar(c); + default_fg = temp_color; + #endif +} + +void wstr_color(const char* data, enum vga_color fg) +{ + #ifdef _TEXTMODE + for ( size_t i = 0, n = strlen(data); i < n; i++ ) + vga_putchar_color((int) ((const unsigned char*) data)[i], fg); + #endif +} + +#ifndef _TEXTMODE +#error "Graphic Mode not ready!" +#endif diff --git a/src/kernel/include/heap.h b/src/kernel/include/heap.h new file mode 100644 index 0000000..ed68299 --- /dev/null +++ b/src/kernel/include/heap.h @@ -0,0 +1,43 @@ +#ifndef _heap_h +#define _heap_h + +#include +#include +#include +#include +#include + +#define KERNEL_HEAP_SIZE 0x10000 + +typedef struct mem_chunk { + char used; + size_t size; +} mem_chunk_t; + +typedef struct mem_heap { + int magic; + size_t mem_size; + size_t mem_used; + size_t mem_free; + Llist_t *head; +} mem_heap_t; + +#define MEM_HEADER_SIZE (sizeof(Llist_t) + sizeof(mem_chunk_t)) + +void init_heap (); + +void *kmalloc (size_t size, int align, uint32_t *phys); + +void kfree (void *p); + +Llist_t *split_mem_chunk(Llist_t *chunk, size_t size); + +void glue_mem_chunk(Llist_t *chunk1, Llist_t *chunk2); + +Llist_t *find_mem_chunk(mem_heap_t *heap, size_t size); + +Llist_t *alloc_mem_chunk(mem_heap_t *heap, size_t size); + +void free_mem_chunk(mem_heap_t *heap, Llist_t *mem); + +#endif diff --git a/src/kernel/include/icxxabi.h b/src/kernel/include/icxxabi.h new file mode 100644 index 0000000..c12b6fa --- /dev/null +++ b/src/kernel/include/icxxabi.h @@ -0,0 +1,30 @@ +#ifndef _ICXXABI_H + #define _ICXXABI_H + + #define ATEXIT_MAX_FUNCS 128 + + #ifdef __cplusplus + extern "C" { + #endif + +typedef unsigned uarch_t; + +struct atexit_func_entry_t +{ + /* + * Each member is at least 4 bytes large. Such that each entry is 12bytes. + * 128 * 12 = 1.5KB exact. + **/ + void (*destructor_func)(void *); + void *obj_ptr; + void *dso_handle; +}; + +int __cxa_atexit(void (*f)(void *), void *objptr, void *dso); +void __cxa_finalize(void *f); + + #ifdef __cplusplus + }; + #endif + +#endif diff --git a/kernel/include/io.h b/src/kernel/include/io.h similarity index 82% rename from kernel/include/io.h rename to src/kernel/include/io.h index a5a7bc3..9257b13 100644 --- a/kernel/include/io.h +++ b/src/kernel/include/io.h @@ -1,13 +1,11 @@ #ifndef _io_h #define _io_h -#if !defined(__cplusplus) -#include /* C doesn't have booleans by default. */ -#endif -#include -#include -#include #include +#include +#include +#include +#include /* output byte */ void outb(uint32_t ad, uint8_t v); diff --git a/src/kernel/include/kernel_class.h b/src/kernel/include/kernel_class.h new file mode 100644 index 0000000..ff97d92 --- /dev/null +++ b/src/kernel/include/kernel_class.h @@ -0,0 +1,18 @@ +#ifndef _kernel_class_h +#define _kernel_class_h + +class KernelClass { + private: + int ID_number; + char version[30]; + char version_name[50]; + public: + KernelClass(); + ~KernelClass(); + void setID(int ID); + void setVersion(const char *version); + int getID(); + char *getVersion(); +}; + +#endif diff --git a/kernel/include/keyboard.h b/src/kernel/include/keyboard.h similarity index 87% rename from kernel/include/keyboard.h rename to src/kernel/include/keyboard.h index 4736e82..c01d364 100644 --- a/kernel/include/keyboard.h +++ b/src/kernel/include/keyboard.h @@ -1,21 +1,15 @@ #ifndef _keyboard_h #define _keyboard_h -#include -#include -#include #include - /* Defines. */ -void (*keyboard_handler)(uint8_t *buf, uint16_t size); +#include +#include +#include +#include + /* Defines. */ #define KEYBOARD_BUFFER_SIZE 32 -uint8_t kb_buffer[KEYBOARD_BUFFER_SIZE]; -int last; -int shift; -char *ascii_s; -char *ascii_S; - #define ESC 27 #define BACKSPACE '\b' #define TAB '\t' diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h new file mode 100644 index 0000000..188ba66 --- /dev/null +++ b/src/kernel/include/multiboot.h @@ -0,0 +1,44 @@ +#ifndef __MULTIBOOT_H +#define __MULTIBOOT_H + +#define MULTIBOOT_FLAG_MEM 0x001 +#define MULTIBOOT_FLAG_DEVICE 0x002 +#define MULTIBOOT_FLAG_CMDLINE 0x004 +#define MULTIBOOT_FLAG_MODS 0x008 +#define MULTIBOOT_FLAG_AOUT 0x010 +#define MULTIBOOT_FLAG_ELF 0x020 +#define MULTIBOOT_FLAG_MMAP 0x040 +#define MULTIBOOT_FLAG_CONFIG 0x080 +#define MULTIBOOT_FLAG_LOADER 0x100 +#define MULTIBOOT_FLAG_APM 0x200 +#define MULTIBOOT_FLAG_VBE 0x400 + +typedef struct multiboot +{ + uint32_t flags; + uint32_t mem_lower; + uint32_t mem_upper; + uint32_t boot_device; + uint32_t cmdline; + uint32_t mods_count; + uint32_t mods_addr; + uint32_t num; + uint32_t size; + uint32_t addr; + uint32_t shndx; + uint32_t mmap_length; + uint32_t mmap_addr; + uint32_t drives_length; + uint32_t drives_addr; + uint32_t config_table; + uint32_t boot_loader_name; + uint32_t apm_table; + uint32_t vbe_control_info; + uint32_t vbe_mode_info; + uint32_t vbe_mode; + uint32_t vbe_interface_seg; + uint32_t vbe_interface_off; + uint32_t vbe_interface_len; +} multiboot; + +#endif diff --git a/src/kernel/include/shell.h b/src/kernel/include/shell.h new file mode 100644 index 0000000..a8f4c80 --- /dev/null +++ b/src/kernel/include/shell.h @@ -0,0 +1,17 @@ +#ifndef _shell_h +#define _shell_h + +#include +#include +#include +#include +#include + +typedef struct shell_cmd { + char *name; + void (*func)(void); +} shell_cmd_t; + +int shell(char *cmd); + +#endif diff --git a/src/kernel/include/system.h b/src/kernel/include/system.h new file mode 100644 index 0000000..361f8c5 --- /dev/null +++ b/src/kernel/include/system.h @@ -0,0 +1,94 @@ +#ifndef _system_h +#define _system_h + +#define LOW_TASK_TIME 1 +#define NORMAL_TASK_TIME 10 +#define HIGH_TASK_TIME 100 + +/* Standard headers */ +#include +#include +#include +#include +#include + +/* Kernel Data Structures */ +typedef struct registers +{ + uint32_t ds; // Data segment selector + uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha. + uint32_t int_no, err_code; // Interrupt number and error code (if applicable) + uint32_t eip, cs, eflags, useresp, ss; // Pushed by the processor automatically. +} registers_t; // registers for interrupts + +typedef struct g_regs +{ + uint32_t edi; + uint32_t esi; + uint32_t edx; + uint32_t ecx; + uint32_t ebx; + uint32_t eax; +} g_regs_t; // general registers for system calls + +typedef struct t_regs { + uint32_t eax, ebx, ecx, edx, esi, edi, esp, ebp, eip, eflags, cr3; +} t_regs_t; // task registers + +typedef void (*isr_t)(registers_t*); +void register_interrupt_handler(uint8_t n, isr_t handler); + +typedef void* type_t; + +/* Kernel headers */ + +/* Arch i386 headers */ +#include +#include +#include +#include +#include +#include +#include + +/* General headers */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Kernel defines */ +#define OS_Name "PhotonOS" +#define Version "v0.0.1core" +#define Relase_Date "2 October 2015" +#define Author "Feraru Mihail" + +#define sti() asm volatile("sti") +#define cli() asm volatile("cli") +#define hlt() asm volatile("hlt") +#define keep_running() while(true) { hlt(); } + +/* Kernel ASM variables */ +extern uint32_t stack_top; +extern uint32_t stack_bottom; +extern uint32_t kernel_end; +extern uint32_t kernel_start; + +/* Kernel ASM functions */ +extern void enable_A20(); +extern int detect_cpu(void); +extern void write_cr3(); +extern void write_cr0(); +extern uint32_t read_cr3(); +extern uint32_t read_cr0(); + +/* Kernel system functions */ +void panic(const char *msg, int line, char *file); +void reboot(); + +#endif diff --git a/kernel/include/task.h b/src/kernel/include/task.h similarity index 76% rename from kernel/include/task.h rename to src/kernel/include/task.h index a540c2d..c20c832 100644 --- a/kernel/include/task.h +++ b/src/kernel/include/task.h @@ -1,18 +1,18 @@ #ifndef _task_h #define _task_h -#include +#include +#include +#include +#include +#include typedef struct task { - uint32_t pid; - t_regs_t regs; - struct task *next; + uint32_t pid; + t_regs_t regs; + struct task *next; } task_t; -task_t *current_task; -task_t *start_task; -uint32_t pid; - /** * Init user mode. */ diff --git a/kernel/include/time.h b/src/kernel/include/time.h similarity index 75% rename from kernel/include/time.h rename to src/kernel/include/time.h index 31fd200..ce9a432 100644 --- a/kernel/include/time.h +++ b/src/kernel/include/time.h @@ -2,11 +2,10 @@ #define _time_h #include - -int mseconds; -int seconds; -int minutes; -int hours; +#include +#include +#include +#include /** * Init clock to 0:0:0:0. diff --git a/src/kernel/include/ui.h b/src/kernel/include/ui.h new file mode 100644 index 0000000..e03c24a --- /dev/null +++ b/src/kernel/include/ui.h @@ -0,0 +1,15 @@ +#ifndef _ui_h +#define _ui_h + +#include +#include +#include +#include +#include + +void prompt(); +void welcome(); +void logo(); +void login(); + +#endif diff --git a/kernel/include/vga.h b/src/kernel/include/vga.h similarity index 71% rename from kernel/include/vga.h rename to src/kernel/include/vga.h index 50b2eb1..b7436a3 100644 --- a/kernel/include/vga.h +++ b/src/kernel/include/vga.h @@ -1,33 +1,32 @@ #ifndef _vga_h #define _vga_h -#if !defined(__cplusplus) -#include /* C doesn't have booleans by default. */ -#endif -#include -#include #include +#include +#include +#include +#include extern uint16_t *vga_memory; enum vga_color { - COLOR_BLACK = 0, - COLOR_BLUE = 1, - COLOR_GREEN = 2, - COLOR_CYAN = 3, - COLOR_RED = 4, - COLOR_MAGENTA = 5, - COLOR_BROWN = 6, - COLOR_LIGHT_GREY = 7, - COLOR_DARK_GREY = 8, - COLOR_LIGHT_BLUE = 9, - COLOR_LIGHT_GREEN = 10, - COLOR_LIGHT_CYAN = 11, - COLOR_LIGHT_RED = 12, - COLOR_LIGHT_MAGENTA = 13, - COLOR_YELLOW = 14, - COLOR_WHITE = 15, + COLOR_BLACK = 0, + COLOR_BLUE = 1, + COLOR_GREEN = 2, + COLOR_CYAN = 3, + COLOR_RED = 4, + COLOR_MAGENTA = 5, + COLOR_BROWN = 6, + COLOR_LIGHT_GREY = 7, + COLOR_DARK_GREY = 8, + COLOR_LIGHT_BLUE = 9, + COLOR_LIGHT_GREEN = 10, + COLOR_LIGHT_CYAN = 11, + COLOR_LIGHT_RED = 12, + COLOR_LIGHT_MAGENTA = 13, + COLOR_YELLOW = 14, + COLOR_WHITE = 15, }; /** @@ -100,7 +99,4 @@ void putchar_color(char c, enum vga_color fg); */ void wstr_color(const char* data, enum vga_color fg); -static const size_t VGA_WIDTH = 80; -static const size_t VGA_HEIGHT = 25; - #endif diff --git a/src/kernel/init/icxxabi.cpp b/src/kernel/init/icxxabi.cpp new file mode 100644 index 0000000..d2e7cb3 --- /dev/null +++ b/src/kernel/init/icxxabi.cpp @@ -0,0 +1,107 @@ +#include + + #ifdef __cplusplus + extern "C" { + #endif + +atexit_func_entry_t __atexit_funcs[ATEXIT_MAX_FUNCS]; +uarch_t __atexit_func_count = 0; + +//void *__dso_handle = 0; //Attention! Optimally, you should remove the '= 0' part and define this in your asm script. + +extern "C" void __cxa_pure_virtual() +{ + // Do nothing... +} + +int __cxa_atexit(void (*f)(void *), void *objptr, void *dso) +{ + if (__atexit_func_count >= ATEXIT_MAX_FUNCS) {return -1;}; + __atexit_funcs[__atexit_func_count].destructor_func = f; + __atexit_funcs[__atexit_func_count].obj_ptr = objptr; + __atexit_funcs[__atexit_func_count].dso_handle = dso; + __atexit_func_count++; + return 0; /*I would prefer if functions returned 1 on success, but the ABI says...*/ +}; + +void __cxa_finalize(void *f) +{ + uarch_t i = __atexit_func_count; + if (!f) + { + /* + * According to the Itanium C++ ABI, if __cxa_finalize is called without a + * function ptr, then it means that we should destroy EVERYTHING MUAHAHAHA!! + * + * TODO: + * Note well, however, that deleting a function from here that contains a __dso_handle + * means that one link to a shared object file has been terminated. In other words, + * We should monitor this list (optional, of course), since it tells us how many links to + * an object file exist at runtime in a particular application. This can be used to tell + * when a shared object is no longer in use. It is one of many methods, however. + **/ + + while (i--) + { + if (__atexit_funcs[i].destructor_func) + { + /* ^^^ That if statement is a safeguard... + * To make sure we don't call any entries that have already been called and unset at runtime. + * Those will contain a value of 0, and calling a function with value 0 + * will cause undefined behaviour. Remember that linear address 0, + * in a non-virtual address space (physical) contains the IVT and BDA. + * + * In a virtual environment, the kernel will receive a page fault, and then probably + * map in some trash, or a blank page, or something stupid like that. + * This will result in the processor executing trash, and...we don't want that. + **/ + (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr); + }; + }; + return; + }; + + for ( ; i >= 0; --i) + { + /* + * The ABI states that multiple calls to the __cxa_finalize(destructor_func_ptr) function + * should not destroy objects multiple times. Only one call is needed to eliminate multiple + * entries with the same address. + * + * FIXME: + * This presents the obvious problem: all destructors must be stored in the order they + * were placed in the list. I.e: the last initialized object's destructor must be first + * in the list of destructors to be called. But removing a destructor from the list at runtime + * creates holes in the table with unfilled entries. + * Remember that the insertion algorithm in __cxa_atexit simply inserts the next destructor + * at the end of the table. So, we have holes with our current algorithm + * This function should be modified to move all the destructors above the one currently + * being called and removed one place down in the list, so as to cover up the hole. + * Otherwise, whenever a destructor is called and removed, an entire space in the table is wasted. + **/ + if (__atexit_funcs[i].destructor_func == f) + { + /* + * Note that in the next line, not every destructor function is a class destructor. + * It is perfectly legal to register a non class destructor function as a simple cleanup + * function to be called on program termination, in which case, it would not NEED an + * object This pointer. A smart programmer may even take advantage of this and register + * a C function in the table with the address of some structure containing data about + * what to clean up on exit. + * In the case of a function that takes no arguments, it will simply be ignore within the + * function itself. No worries. + **/ + (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr); + __atexit_funcs[i].destructor_func = 0; + + /* + * Notice that we didn't decrement __atexit_func_count: this is because this algorithm + * requires patching to deal with the FIXME outlined above. + **/ + }; + }; +}; + + #ifdef __cplusplus + }; + #endif diff --git a/kernel/init/kernel_class.cpp b/src/kernel/init/kernel_class.cpp similarity index 59% rename from kernel/init/kernel_class.cpp rename to src/kernel/init/kernel_class.cpp index 8efb9f1..522aaf1 100644 --- a/kernel/init/kernel_class.cpp +++ b/src/kernel/init/kernel_class.cpp @@ -13,30 +13,30 @@ extern "C" { void KernelClass::setID(const int ID) { - this->ID_number = ID; + this->ID_number = ID; } void KernelClass::setVersion(const char *version) { - memcpy(this->version, version, strlen(version) + 1); + memcpy(this->version, version, strlen(version) + 1); } int KernelClass::getID() { - return this->ID_number; + return this->ID_number; } char *KernelClass::getVersion() { - return version; + return version; } KernelClass::KernelClass() { - printk("C++ support enabled. Kernel Class created.\n"); + printk("C++ support enabled. Kernel Class created.\n"); } KernelClass::~KernelClass() { - printk("Kernel Class destroyed. Kernel go down."); + printk("Kernel Class destroyed. Kernel go down."); } diff --git a/src/kernel/init/main.cpp b/src/kernel/init/main.cpp new file mode 100644 index 0000000..44b1760 --- /dev/null +++ b/src/kernel/init/main.cpp @@ -0,0 +1,144 @@ +/* All starts here! + * + * Copyright (c) 2015 Feraru Mihail (mihailferaru2000@gmail.com). + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include + +#define TIMER_FREQ 100 + +extern uint32_t kernel_init_stack; +extern multiboot *kernel_mboot; + +extern uint32_t nframes; +extern uint32_t init_esp; +extern uint32_t kernel_init_stack; +extern multiboot *kernel_mboot; +extern mem_heap_t *kernel_heap; + +extern char user[20]; +extern char machine[30]; + +void* stdout; +void* stdin; +volatile int in_size; +int out_crs; + +uint8_t inbuffer[STDIO_SIZE]; +char outbuffer[STDIO_SIZE]; + +static uint32_t get_total_memory() +{ + // return memory in MiB + return nframes * FRAME_SIZE / 1024 / 1024; +} + +void kernel_init(multiboot *mboot_ptr, uint32_t init_stack) +{ + kernel_init_stack = init_stack; + kernel_mboot = mboot_ptr; + + cli(); + init_esp = kernel_init_stack; + + init_vga(); + + printk("%s %s (%s) by %s. Copyright C 2015 %s. All rights reserved.\n", OS_Name, Version, Relase_Date, Author, Author); + detect_cpu(); + printk("\n-------------------------------------------------------------------\n"); + + printk("VGA driver was installed!"); + wstr_color("[OK]\n", COLOR_GREEN); + + printk("Initialize GDT. "); + init_gdt(); + wstr_color("[OK]\n", COLOR_GREEN); + + printk("Initialize IDT and interrupts. "); + init_idt(); + wstr_color("[OK]\n", COLOR_GREEN); + + + // mask some interrupts + IRQ_set_mask(2); + IRQ_set_mask(3); + IRQ_set_mask(4); + IRQ_set_mask(5); + IRQ_set_mask(6); + IRQ_set_mask(7); + IRQ_set_mask(8); + IRQ_set_mask(9); + IRQ_set_mask(10); + IRQ_set_mask(11); + IRQ_set_mask(12); + IRQ_set_mask(13); + IRQ_set_mask(14); + IRQ_set_mask(15); + + printk("Install timer and clock. "); + init_timer(TIMER_FREQ); + wstr_color("[OK]\n", COLOR_GREEN); + + printk("Install keyboard support. "); + install_keyboard(); + wstr_color("[OK]\n", COLOR_GREEN); + + printk("Enable A20. "); + enable_A20(); + wstr_color("[OK]\n", COLOR_GREEN); + + printk("Initialize PMM and VMM. "); + init_pmm(kernel_mboot->mem_lower + kernel_mboot->mem_upper); + init_vmm(); + wstr_color("[OK]\n", COLOR_GREEN); + + printk("Total system memory: %d MiB in %d frames.\n", get_total_memory(), + nframes); + + printk("Initialize stdio (allow using of stdio header). "); + + stdin = (uint8_t*) inbuffer; + stdout = (char*) outbuffer; + + for (int i = 0; i < STDIO_SIZE; i++) { + inbuffer[i] = 0; + outbuffer[i] = 0; + } + wstr_color("[OK]\n", COLOR_GREEN); + + printk("Initialize kernel heap. "); + init_heap(); + wstr_color("[OK]\n", COLOR_GREEN); + printk("Initialized kernel heap at %x and created main block of %d bytes.\n", + (size_t) kernel_heap + MEM_HEADER_SIZE, kernel_heap->mem_size); + + wstr_color("\nDONE!\n", COLOR_GREEN); + + sti(); + getch(); +} + +void kernel_main() +{ + welcome(); + login(); + prompt(); +} + +#ifdef __cplusplus +} +#endif diff --git a/src/kernel/system/cpu.c b/src/kernel/system/cpu.c new file mode 100644 index 0000000..86dfc2f --- /dev/null +++ b/src/kernel/system/cpu.c @@ -0,0 +1,366 @@ +/* + * Copyright (c) 2006-2007 - http://brynet.biz.tm - + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include /* for printk(); */ + +/* Required Declarations */ +int do_intel(void); +int do_amd(void); +void printregs(int eax, int ebx, int ecx, int edx); + +#define cpuid(in, a, b, c, d) __asm__("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in)); + +/* Simply call this function detect_cpu(); */ +int detect_cpu(void) { /* or main() if your trying to port this as an independant application */ + unsigned long ebx, unused; + cpuid(0, unused, ebx, unused, unused); + switch(ebx) { + case 0x756e6547: /* Intel Magic Code */ + do_intel(); + break; + case 0x68747541: /* AMD Magic Code */ + do_amd(); + break; + default: + printk("Unknown x86 CPU Detected\n"); + break; + } + return 0; +} + +/* Intel Specific brand list */ +char *Intel[] = { + "Brand ID Not Supported.", + "Intel(R) Celeron(R) processor", + "Intel(R) Pentium(R) III processor", + "Intel(R) Pentium(R) III Xeon(R) processor", + "Intel(R) Pentium(R) III processor", + "Reserved", + "Mobile Intel(R) Pentium(R) III processor-M", + "Mobile Intel(R) Celeron(R) processor", + "Intel(R) Pentium(R) 4 processor", + "Intel(R) Pentium(R) 4 processor", + "Intel(R) Celeron(R) processor", + "Intel(R) Xeon(R) Processor", + "Intel(R) Xeon(R) processor MP", + "Reserved", + "Mobile Intel(R) Pentium(R) 4 processor-M", + "Mobile Intel(R) Pentium(R) Celeron(R) processor", + "Reserved", + "Mobile Genuine Intel(R) processor", + "Intel(R) Celeron(R) M processor", + "Mobile Intel(R) Celeron(R) processor", + "Intel(R) Celeron(R) processor", + "Mobile Geniune Intel(R) processor", + "Intel(R) Pentium(R) M processor", + "Mobile Intel(R) Celeron(R) processor" +}; + +/* This table is for those brand strings that have two values depending on the processor signature. It should have the same number of entries as the above table. */ +char *Intel_Other[] = { + "Reserved", + "Reserved", + "Reserved", + "Intel(R) Celeron(R) processor", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Intel(R) Xeon(R) processor MP", + "Reserved", + "Reserved", + "Intel(R) Xeon(R) processor", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved" +}; + +/* Intel-specific information */ +int do_intel(void) { + printk("Intel Specific Features:\n"); + unsigned long eax, ebx, ecx, edx, max_eax, signature, unused; + int model, family, type, brand, stepping, reserved; + int extended_family = -1; + cpuid(1, eax, ebx, unused, unused); + model = (eax >> 4) & 0xf; + family = (eax >> 8) & 0xf; + type = (eax >> 12) & 0x3; + brand = ebx & 0xff; + stepping = eax & 0xf; + reserved = eax >> 14; + signature = eax; + printk("Type %d - ", type); + switch(type) { + case 0: + printk("Original OEM"); + break; + case 1: + printk("Overdrive"); + break; + case 2: + printk("Dual-capable"); + break; + case 3: + printk("Reserved"); + break; + } + printk("\n"); + printk("Family %d - ", family); + switch(family) { + case 3: + printk("i386"); + break; + case 4: + printk("i486"); + break; + case 5: + printk("Pentium"); + break; + case 6: + printk("Pentium Pro"); + break; + case 15: + printk("Pentium 4"); + } + printk("\n"); + if(family == 15) { + extended_family = (eax >> 20) & 0xff; + printk("Extended family %d\n", extended_family); + } + printk("Model %d - ", model); + switch(family) { + case 3: + break; + case 4: + switch(model) { + case 0: + case 1: + printk("DX"); + break; + case 2: + printk("SX"); + break; + case 3: + printk("487/DX2"); + break; + case 4: + printk("SL"); + break; + case 5: + printk("SX2"); + break; + case 7: + printk("Write-back enhanced DX2"); + break; + case 8: + printk("DX4"); + break; + } + break; + case 5: + switch(model) { + case 1: + printk("60/66"); + break; + case 2: + printk("75-200"); + break; + case 3: + printk("for 486 system"); + break; + case 4: + printk("MMX"); + break; + } + break; + case 6: + switch(model) { + case 1: + printk("Pentium Pro"); + break; + case 3: + printk("Pentium II Model 3"); + break; + case 5: + printk("Pentium II Model 5/Xeon/Celeron"); + break; + case 6: + printk("Celeron"); + break; + case 7: + printk("Pentium III/Pentium III Xeon - external L2 cache"); + break; + case 8: + printk("Pentium III/Pentium III Xeon - internal L2 cache"); + break; + } + break; + case 15: + break; + } + printk("\n"); + cpuid(0x80000000, max_eax, unused, unused, unused); + /* Quok said: If the max extended eax value is high enough to support the processor brand string + (values 0x80000002 to 0x80000004), then we'll use that information to return the brand information. + Otherwise, we'll refer back to the brand tables above for backwards compatibility with older processors. + According to the Sept. 2006 Intel Arch Software Developer's Guide, if extended eax values are supported, + then all 3 values for the processor brand string are supported, but we'll test just to make sure and be safe. */ + if(max_eax >= 0x80000004) { + printk("Brand: "); + if(max_eax >= 0x80000002) { + cpuid(0x80000002, eax, ebx, ecx, edx); + printregs(eax, ebx, ecx, edx); + } + if(max_eax >= 0x80000003) { + cpuid(0x80000003, eax, ebx, ecx, edx); + printregs(eax, ebx, ecx, edx); + } + if(max_eax >= 0x80000004) { + cpuid(0x80000004, eax, ebx, ecx, edx); + printregs(eax, ebx, ecx, edx); + } + printk("\n"); + } else if(brand > 0) { + printk("Brand %d - ", brand); + if(brand < 0x18) { + if(signature == 0x000006B1 || signature == 0x00000F13) { + printk("%s\n", Intel_Other[brand]); + } else { + printk("%s\n", Intel[brand]); + } + } else { + printk("Reserved\n"); + } + } + printk("Stepping: %d Reserved: %d\n", stepping, reserved); + return 0; +} + +/* Print Registers */ +void printregs(int eax, int ebx, int ecx, int edx) { + int j; + char string[17]; + string[16] = '\0'; + for(j = 0; j < 4; j++) { + string[j] = eax >> (8 * j); + string[j + 4] = ebx >> (8 * j); + string[j + 8] = ecx >> (8 * j); + string[j + 12] = edx >> (8 * j); + } + printk("%s", string); +} + +/* AMD-specific information */ +int do_amd(void) { + printk("AMD Specific Features:\n"); + unsigned long extended, eax, ebx, ecx, edx, unused; + int family, model, stepping, reserved; + cpuid(1, eax, unused, unused, unused); + model = (eax >> 4) & 0xf; + family = (eax >> 8) & 0xf; + stepping = eax & 0xf; + reserved = eax >> 12; + printk("Family: %d Model: %d [", family, model); + switch(family) { + case 4: + printk("486 Model %d", model); + break; + case 5: + switch(model) { + case 0: + case 1: + case 2: + case 3: + case 6: + case 7: + printk("K6 Model %d", model); + break; + case 8: + printk("K6-2 Model 8"); + break; + case 9: + printk("K6-III Model 9"); + break; + default: + printk("K5/K6 Model %d", model); + break; + } + break; + case 6: + switch(model) { + case 1: + case 2: + case 4: + printk("Athlon Model %d", model); + break; + case 3: + printk("Duron Model 3"); + break; + case 6: + printk("Athlon MP/Mobile Athlon Model 6"); + break; + case 7: + printk("Mobile Duron Model 7"); + break; + default: + printk("Duron/Athlon Model %d", model); + break; + } + break; + } + printk("]\n"); + cpuid(0x80000000, extended, unused, unused, unused); + if(extended == 0) { + return 0; + } + if(extended >= 0x80000002) { + unsigned int j; + printk("Detected Processor Name: "); + for(j = 0x80000002; j <= 0x80000004; j++) { + cpuid(j, eax, ebx, ecx, edx); + printregs(eax, ebx, ecx, edx); + } + printk("\n"); + } + if(extended >= 0x80000007) { + cpuid(0x80000007, unused, unused, unused, edx); + if(edx & 1) { + printk("Temperature Sensing Diode Detected!\n"); + } + } + printk("Stepping: %d Reserved: %d\n", stepping, reserved); + return 0; +} diff --git a/src/kernel/system/heap.c b/src/kernel/system/heap.c new file mode 100644 index 0000000..a321061 --- /dev/null +++ b/src/kernel/system/heap.c @@ -0,0 +1,214 @@ +/* Kernel heap driver + * + * Copyright (c) 2015 Feraru Mihail (mihailferaru2000@gmail.com). + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include +#include +#include +#include +#include + +// TODO: resolve size recalculation bug after kfree() + +extern uint32_t placement_addr; + +int kheap_initialized = 0; +mem_heap_t *kernel_heap; +Llist_t *kernel_free_mem_head; +mem_chunk_t *free_mem_chunk_head; + +void init_heap () +{ + kernel_heap = kmalloc(sizeof(mem_heap_t), 0, 0); + kernel_free_mem_head = kmalloc(sizeof(Llist_t), 0, 0); + free_mem_chunk_head = kmalloc(sizeof(mem_chunk_t), 0, 0); + + kernel_heap->magic = 0xbeefbeef; + kernel_heap->head = kernel_free_mem_head; + kernel_heap->head->prev = NULL; + kernel_heap->head->next = NULL; + kernel_heap->head->data = (void*) free_mem_chunk_head; + free_mem_chunk_head->used = 0; + free_mem_chunk_head->size = KERNEL_HEAP_SIZE; + kernel_heap->mem_size = KERNEL_HEAP_SIZE; + kernel_heap->mem_free = KERNEL_HEAP_SIZE; + kernel_heap->mem_used = 0; + kheap_initialized = 1; +} + +/* Kernel only allocator */ +void *kmalloc(size_t size, int align, uint32_t *phys) +{ + if (kheap_initialized) { + Llist_t *mem_chunk = alloc_mem_chunk(kernel_heap, size); + if (mem_chunk == NULL) { + return NULL; + } + + void *ret_p = (void*) ((size_t) mem_chunk + MEM_HEADER_SIZE); + return ret_p; + } else { + if (align && (placement_addr & 0xFFFFF000)) { + placement_addr &= 0xFFFFF000; + placement_addr += 0x1000; + } + + if (phys) { + *phys = placement_addr; + } + uint32_t ret_addr = placement_addr; + placement_addr += size; + void *ret_p = (void*) ret_addr; + + return ret_p; + } + return NULL; +} + +void kfree(void *p) +{ + if (kheap_initialized) { + Llist_t *chunk = (Llist_t*) ((size_t) p - MEM_HEADER_SIZE); + free_mem_chunk(kernel_heap, chunk); + } else { + return; + } +} +/* ------------------------------------ */ + +Llist_t *split_mem_chunk(Llist_t *chunk, size_t size) +{ + mem_chunk_t *chunk_data = (mem_chunk_t*) chunk->data; + + Llist_t *next = chunk->next; + + if (size >= chunk_data->size) { + return NULL; + } + + size_t new_chunk_size = chunk_data->size - size - MEM_HEADER_SIZE; + + chunk_data->size = size; + chunk->next = (Llist_t*) ((size_t) chunk + MEM_HEADER_SIZE + chunk_data->size); + chunk->next->data = (void*) chunk->next + sizeof(int) * 3; + + mem_chunk_t *new_chunk_data = (mem_chunk_t*) chunk->next->data; + new_chunk_data->used = chunk_data->used; + new_chunk_data->size = new_chunk_size; + chunk->next->next = next; + chunk->next->prev = chunk; + + if (next != NULL) { + next->prev = chunk->next; + } + + return chunk; +} + +void glue_mem_chunk(Llist_t *chunk1, Llist_t *chunk2) +{ + Llist_t *next = chunk2->next; + Llist_t *prev = chunk1->prev; + + mem_chunk_t *chunk1_data = (mem_chunk_t*) chunk1->data; + mem_chunk_t *chunk2_data = (mem_chunk_t*) chunk2->data; + + size_t new_size = chunk1_data->size + chunk2_data->size + MEM_HEADER_SIZE; + chunk1_data->size = new_size; + + chunk1->next = next; + chunk1->prev = prev; + + if (next != NULL) { + next->prev = chunk1; + } + + if (prev != NULL) { + prev->next = chunk1; + } +} + +Llist_t *find_mem_chunk(mem_heap_t *heap, size_t size) +{ + if (heap->mem_free < size) { + return NULL; + } + + Llist_t *chunk = heap->head; + mem_chunk_t *header = (mem_chunk_t*) chunk->data; + + while (chunk != NULL) { + if (header->size >= size && header->used == 0) { + return chunk; + } + chunk = chunk->next; + + if (chunk != NULL) { + header = (mem_chunk_t*) chunk->data; + } + } + + return NULL; +} + +Llist_t *alloc_mem_chunk(mem_heap_t *heap, size_t size) +{ + Llist_t *free_chunk = find_mem_chunk(heap, size); + if (free_chunk == NULL) { + return NULL; + } + + mem_chunk_t *chunk_data = (mem_chunk_t*) free_chunk->data; + + if (chunk_data->size == size) { + chunk_data->used = 1; + heap->mem_free -= size; + heap->mem_used += size; + + return free_chunk; + } else { + Llist_t *allocated_chunk = split_mem_chunk(free_chunk, size); + + if (allocated_chunk == NULL) { + return NULL; + } + + chunk_data = (mem_chunk_t*) allocated_chunk->data; + heap->mem_free -= (size + MEM_HEADER_SIZE); + heap->mem_used += (size + MEM_HEADER_SIZE); + + chunk_data->used = 1; + return allocated_chunk; + } + + return NULL; +} + +void free_mem_chunk(mem_heap_t *heap, Llist_t *mem) +{ + mem_chunk_t *data = (mem_chunk_t*) mem->data; + data->used = 0; + heap->mem_free += data->size; + heap->mem_used -= data->size; + + if (mem->prev != NULL) { + mem_chunk_t *prev_data = (mem_chunk_t*) mem->prev->data; + if (prev_data->used == 0) { + Llist_t *new_chunk = mem->prev; + glue_mem_chunk(mem->prev, mem); + mem = new_chunk; + } + } + + if (mem->next != NULL) { + mem_chunk_t *next_data = (mem_chunk_t*) mem->next->data; + if (next_data->used == 0) { + glue_mem_chunk(mem, mem->next); + } + } +} diff --git a/src/kernel/system/shell.c b/src/kernel/system/shell.c new file mode 100644 index 0000000..f2f1276 --- /dev/null +++ b/src/kernel/system/shell.c @@ -0,0 +1,96 @@ +#include +#include +#include +#include +#include + +extern int detect_cpu(); + +extern uint32_t free_frames; +extern uint32_t mapped_pages; +extern mem_heap_t *kernel_heap; +extern uint32_t nframes; + +uint32_t get_memory() +{ + return ((nframes * 4) / 1024); +} + +uint32_t get_mapped_mem() +{ + return ((mapped_pages * 4) / 1024); +} + +void cmd_help() +{ + printk("""Help:\n \ +-> hw - print hardware info\n \ +-> time - display the time\n \ +-> free - display info about memory\n \ +-> clear - clear screen\n \ +"""); +} + +void cmd_hw() +{ + detect_cpu(); +} + +void cmd_time() +{ + print_time(); +} + +void cmd_free() +{ + printk("Toatal memory: %d MiB (%d pages)\n", get_memory(), nframes); + printk("Mapped memory: %d MiB (%d pages) Free memory: %d MiB\n", + get_mapped_mem(), + mapped_pages, + get_memory() - get_mapped_mem()); + printk("Usable memory (allocated only for kernel): %d MiB = %d Bytes\n", + kernel_heap->mem_size / 1024 / 1024, + kernel_heap->mem_size); + printk("Usable memory (allocated for user-space): %d MiB (%s)\n", + 0, + "User-space isn't available!"); + printk("Allocated memory: %d MiB Free memory: %d MiB\n", + kernel_heap->mem_used / 1024 / 1024, + kernel_heap->mem_free / 1024 / 1024); + printk("Allocated memory: %d Bytes Free memory: %d Bytes\n", + kernel_heap->mem_used, + kernel_heap->mem_free); +} + +void cmd_clear() +{ + clear_vga(); + logo(); +} + +void cmd_dbg() +{ + printk("WHEN MULTI-TASKING WILL BE AVAILABLE THIS SHOULD GO INTO KERNEL THREAD BASED SHELL AND KILL USER SHELL TASK.\n"); +} + +int cmd_limit = 6; + +shell_cmd_t cmd_table[] = { + {"help", cmd_help}, + {"hw", cmd_hw}, + {"time", cmd_time}, + {"free", cmd_free}, + {"clear", cmd_clear}, + {"dbg", cmd_dbg} +}; + +int shell(char *cmd) +{ + for (int i = 0; i < cmd_limit; i++) { + if (!strcmp(cmd, cmd_table[i].name)) { + cmd_table[i].func(); + return 0; + } + } + return 1; +} diff --git a/src/kernel/system/stack_protector.c b/src/kernel/system/stack_protector.c new file mode 100644 index 0000000..aa97798 --- /dev/null +++ b/src/kernel/system/stack_protector.c @@ -0,0 +1,23 @@ +#include +#include +#include +#include +#include + +#if UINT32_MAX == UINTPTR_MAX +#define STACK_CHK_GUARD 0xe2dee396 +#else +#define STACK_CHK_GUARD 0x595e9fbd94fda766 +#endif + +uintptr_t __stack_chk_guard = STACK_CHK_GUARD; + +__attribute__((noreturn)) +void __stack_chk_fail(void) +{ +#if __STDC_HOSTED__ + abort(); +#elif __is_photon_kernel + panic("Stack smashing detected", __LINE__, __FILE__); +#endif +} diff --git a/kernel/system/tty.c b/src/kernel/system/system.c similarity index 50% rename from kernel/system/tty.c rename to src/kernel/system/system.c index 2ec41fb..09b75eb 100644 --- a/kernel/system/tty.c +++ b/src/kernel/system/system.c @@ -1,4 +1,4 @@ -/* Terminal Interface +/* Basic System Interface * * Copyright (c) 2015 Feraru Mihail (mihailferaru2000@gmail.com). * This program is free software; you can redistribute it and/or modify it @@ -7,16 +7,25 @@ * any later version. */ -#include -#include -#if !defined(__cplusplus) -#include /* C doesn't have booleans by default. */ -#endif -#include -#include -#include +#include +#include #include -#include -#include +#include +#include +void panic(const char *msg, int line, char *file) +{ + cli(); + printk("[KERNEL PANIC]"); + printk("%s. Error at line %d in file %s.", msg, line, file); + keep_running(); +} +void reboot() +{ + uint8_t good = 0x02; + while (good & 0x02) + good = inb(0x64); + outb(0x64, 0xFE); + hlt(); +} diff --git a/kernel/system/task.c b/src/kernel/system/task.c similarity index 93% rename from kernel/system/task.c rename to src/kernel/system/task.c index 5523696..816db96 100644 --- a/kernel/system/task.c +++ b/src/kernel/system/task.c @@ -7,13 +7,15 @@ * any later version. */ -#include -#include -#include -#include #include +#include +#include +#include +#include -extern uint32_t stack_top; +task_t *current_task; +task_t *start_task; +uint32_t pid; void *syscalls[] = { &write @@ -80,7 +82,7 @@ void init_tasking() task_t *create_task(task_t *new_task, void (*main)(), int32_t flags, uint32_t pagedir) { - new_task = (task_t*) kmalloc(sizeof(task_t)); + new_task = (task_t*) kmalloc(sizeof(task_t), 0, 0); new_task->pid = pid; new_task->regs.eax = 0; new_task->regs.ebx = 0; @@ -91,7 +93,7 @@ task_t *create_task(task_t *new_task, void (*main)(), int32_t flags, uint32_t pa new_task->regs.eflags = flags; new_task->regs.eip = (uint32_t) main; new_task->regs.cr3 = (uint32_t) pagedir; - new_task->regs.esp = (uint32_t) kmalloc(2000); + new_task->regs.esp = (uint32_t) kmalloc(2000, 0, 0); new_task->next = 0; if (pid != (uint32_t) 1) { diff --git a/kernel/system/time.c b/src/kernel/system/time.c similarity index 85% rename from kernel/system/time.c rename to src/kernel/system/time.c index 1855830..6ab7855 100644 --- a/kernel/system/time.c +++ b/src/kernel/system/time.c @@ -7,10 +7,16 @@ * any later version. */ -#include -#include +#include +#include #include -#include +#include +#include + +int mseconds; +int seconds; +int minutes; +int hours; void init_time() { @@ -49,4 +55,5 @@ void print_time() } else { printk("pm"); } + printk("\n"); } diff --git a/src/kernel/system/ui.c b/src/kernel/system/ui.c new file mode 100644 index 0000000..2fa38fa --- /dev/null +++ b/src/kernel/system/ui.c @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include + +char user[20]; +char machine[30]; + +void prompt() { + char cmd[1024]; + while (true) { + memset(cmd, 0, 1023); + printk("%s@%s:$ ", user, machine); + gets(cmd); + if (cmd[0] != 0) { + if(shell(cmd)) { + printk("Command '%s' not found.\n", cmd); + } + } + } +} + +void welcome() { + vga_setcolor(COLOR_LIGHT_GREY, COLOR_GREEN); + clear_vga(); + + wstr_color(" |\\ /|( ____ \\( \\ ( ____ \\( ___ )( )( ____ \\\n", COLOR_RED); + wstr_color(" | ) ( || ( \\/| ( | ( \\/| ( ) || () () || ( \\/\n", COLOR_RED); + wstr_color(" | | _ | || (__ | | | | | | | || || || || (\\\n", COLOR_RED); + wstr_color(" | |( )| || __) | | | | | | | || |(_)| || __)\\\n", COLOR_RED); + wstr_color(" | || || || ( | | | | | | | || | | || (\\\n", COLOR_RED); + wstr_color(" | () () || (____/\\| (____/\\| (____/\\| (___) || ) ( || (____/\\\n", COLOR_RED); + wstr_color(" (_______)(_______/(_______/(_______/(_______)|/ \\|(_______/\n\n", COLOR_RED); + + wstr_color(" \\__ __/( ___ )\n", COLOR_YELLOW); + wstr_color(" ) ( | ( ) |\n", COLOR_YELLOW); + wstr_color(" | | | | | |\n", COLOR_YELLOW); + wstr_color(" | | | | | |\n", COLOR_YELLOW); + wstr_color(" | | | | | |\n", COLOR_YELLOW); + wstr_color(" | | | (___) |\n", COLOR_YELLOW); + wstr_color(" )_( (_______)\n\n", COLOR_YELLOW); + + wstr_color(" _______ _______ _________ _______ _ _______ _______ \n", COLOR_BLUE); + wstr_color("( ____ )|\\ /|( ___ )\\__ __/( ___ )( ( /|( ___ )( ____ \\\n", COLOR_BLUE); + wstr_color("| ( )|| ) ( || ( ) | ) ( | ( ) || \\ ( || ( ) || ( \\/\n", COLOR_BLUE); + wstr_color("| (____)|| (___) || | | | | | | | | || \\ | || | | || (_____ \n", COLOR_BLUE); + wstr_color("| _____)| ___ || | | | | | | | | || (\\ \\) || | | |(_____ )\n", COLOR_BLUE); + wstr_color("| ( | ( ) || | | | | | | | | || | \\ || | | | ) |\n", COLOR_BLUE); + wstr_color("| ) | ) ( || (___) | | | | (___) || ) \\ || (___) |/\\____) |\n", COLOR_BLUE); + wstr_color("|/ |/ \\|(_______) )_( (_______)|/ )_)(_______)\\_______)\n", COLOR_BLUE); + + printk(" by Feraru Mihail"); + + getch(); + vga_setcolor(COLOR_LIGHT_GREY, COLOR_BLACK); + clear_vga(); +} + +void logo() +{ + vga_setcolor(COLOR_LIGHT_GREY, COLOR_RED); + wstr_color(" _______ _______ _________ _______ _ _______ _______ ", COLOR_BLUE); + wstr_color("( ____ )|\\ /|( ___ )\\__ __/( ___ )( ( /|( ___ )( ____ \\ ", COLOR_BLUE); + wstr_color("| ( )|| ) ( || ( ) | ) ( | ( ) || \\ ( || ( ) || ( \\/ ", COLOR_BLUE); + wstr_color("| (____)|| (___) || | | | | | | | | || \\ | || | | || (_____ ", COLOR_BLUE); + wstr_color("| _____)| ___ || | | | | | | | | || (\\ \\) || | | |(_____ ) ", COLOR_BLUE); + wstr_color("| ( | ( ) || | | | | | | | | || | \\ || | | | ) | ", COLOR_BLUE); + wstr_color("| ) | ) ( || (___) | | | | (___) || ) \\ || (___) |/\\____) | ", COLOR_BLUE); + wstr_color("|/ |/ \\|(_______) )_( (_______)|/ )_)(_______)\\_______) ", COLOR_BLUE); + vga_setcolor(COLOR_LIGHT_GREY, COLOR_BLACK); +} + +void login() +{ + logo(); + printk("Log in please.\n"); + printk("Username: "); + gets(user); + printk("Machine: "); + gets(machine); + printk("Loged in!\n"); +} diff --git a/libc/Makefile b/src/libc/Makefile similarity index 95% rename from libc/Makefile rename to src/libc/Makefile index 091cc99..211d503 100644 --- a/libc/Makefile +++ b/src/libc/Makefile @@ -36,7 +36,10 @@ stdio/putchar.o \ stdio/puts.o \ stdlib/abort.o \ stdlib/intlen.o \ +stdlib/atoi.o \ stdlib/itoa.o \ +stdlib/malloc.o \ +stdlib/free.o \ string/memcmp.o \ string/memcpy.o \ string/memmove.o \ @@ -46,6 +49,8 @@ string/strcmp.o \ string/strlen.o \ string/strrev.o \ phapi/list.o \ +phapi/linked_list.o \ +phapi/bitmap.o \ HOSTEDOBJS:=\ $(ARCH_HOSTEDOBJS) \ diff --git a/src/libc/arch/i386/crt0.S b/src/libc/arch/i386/crt0.S new file mode 100644 index 0000000..65e0914 --- /dev/null +++ b/src/libc/arch/i386/crt0.S @@ -0,0 +1,37 @@ +.section .text + +.global _start +.type _start, @function +_start: + # TODO: Locate argc, argv, envp according to System V ABI (i386 supplement) + # Figure 3-31: Initial Process Stack (3-28, Page 54). + + # Set up end of the stack frame linked list. + xorl %ebp, %ebp + pushl %ebp # rip=0 + pushl %ebp # rbp=0 + movl %esp, %ebp + + # Initialize the standard library. + push $0 # TODO: argc + push $0 # TODO: argv + push $0 # TODO: envp + call __init_libc # void(int, char**, char**) + addl $12, %esp + + # Run the global constructors. +#if !defined(__HAS_NO_CRT_INIT) + call _init # void(void) +#endif + + # Run main + push $0 # TODO: argc + push $0 # TODO: argv + push $0 # TODO: envp + call main # int(int, char**, char**) + addl $12, %esp + + # Terminate the process with main's exit code. + push %eax + call exit +.size _start, .-_start diff --git a/src/libc/arch/i386/crti.S b/src/libc/arch/i386/crti.S new file mode 100644 index 0000000..06112f9 --- /dev/null +++ b/src/libc/arch/i386/crti.S @@ -0,0 +1,15 @@ +.section .init +.global _init +.type _init, @function +_init: + push %ebp + movl %esp, %ebp + /* gcc will nicely put the contents of crtbegin.o's .init section here. */ + +.section .fini +.global _fini +.type _fini, @function +_fini: + push %ebp + movl %esp, %ebp + /* gcc will nicely put the contents of crtbegin.o's .fini section here. */ diff --git a/src/libc/arch/i386/crtn.S b/src/libc/arch/i386/crtn.S new file mode 100644 index 0000000..0d58006 --- /dev/null +++ b/src/libc/arch/i386/crtn.S @@ -0,0 +1,9 @@ +.section .init + /* gcc will nicely put the contents of crtend.o's .init section here. */ + popl %ebp + ret + +.section .fini + /* gcc will nicely put the contents of crtend.o's .fini section here. */ + popl %ebp + ret diff --git a/libc/arch/i386/make.config b/src/libc/arch/i386/make.config similarity index 100% rename from libc/arch/i386/make.config rename to src/libc/arch/i386/make.config diff --git a/src/libc/include/bitmap.h b/src/libc/include/bitmap.h new file mode 100644 index 0000000..6bf64c0 --- /dev/null +++ b/src/libc/include/bitmap.h @@ -0,0 +1,28 @@ +#ifndef _bitmap_h +#define _bitmap_h + +#include +#include +#include +#include +#include + +#define BIT_INDEX(x) (x / 0x20) +#define BIT_OFFSET(x) (x % 0x20) + +/** + * Set bit as used. + */ +void use_bit(uint32_t *bitmap, uint32_t bit); + +/** + * Set bit as free. + */ +void free_bit(uint32_t *bitmap, uint32_t bit); + +/** + * Test if bit is free or not. + */ +uint32_t test_bit(uint32_t *bitmap, uint32_t bit); + +#endif diff --git a/src/libc/include/linked_list.h b/src/libc/include/linked_list.h new file mode 100644 index 0000000..cc6dd78 --- /dev/null +++ b/src/libc/include/linked_list.h @@ -0,0 +1,24 @@ +#ifndef _linked_list_h +#define _linked_list_h + +#include +#include +#include +#include +#include + +typedef struct Llist { + struct Llist *prev; + struct Llist *next; + void *data; +} Llist_t; + +Llist_t *Llist_create(); +void Llist_push(Llist_t *head, Llist_t *last); +void List_pop(Llist_t *head); +void Llist_insert_after(Llist_t *location, Llist_t *element); +void Llist_insert_before(Llist_t *location, Llist_t *element); +void Llist_remove(Llist_t *location); +void Llist_destroy(Llist_t *head); + +#endif diff --git a/libc/include/list.h b/src/libc/include/list.h similarity index 91% rename from libc/include/list.h rename to src/libc/include/list.h index a88fdf8..5967926 100644 --- a/libc/include/list.h +++ b/src/libc/include/list.h @@ -1,9 +1,10 @@ #ifndef _list_h #define _list_h -#include -#include -#include +#include +#include +#include +#include #include typedef int8_t (*lessthan_pred_t)(type_t, type_t); diff --git a/libc/include/phapi.h b/src/libc/include/phapi.h similarity index 53% rename from libc/include/phapi.h rename to src/libc/include/phapi.h index 68799d5..93e0288 100644 --- a/libc/include/phapi.h +++ b/src/libc/include/phapi.h @@ -2,7 +2,14 @@ #define _phapi_h // include all Photon API headers +#include +#include +#include +#include +#include #include +#include +#include // types & structs of Photon API diff --git a/libc/include/stdio.h b/src/libc/include/stdio.h similarity index 76% rename from libc/include/stdio.h rename to src/libc/include/stdio.h index 1a872a1..629b576 100644 --- a/libc/include/stdio.h +++ b/src/libc/include/stdio.h @@ -1,18 +1,13 @@ #ifndef _stdio_h #define _stdio_h -#if !defined(__cplusplus) -#include /* C doesn't have booleans by default. */ -#endif -#include -#include +#include +#include +#include +#include #include -#define STDIO_SIZE 4096 -void* stdout; -void* stdin; -volatile int in_size; -int out_crs; +#define STDIO_SIZE 4096 /** * Puts a char in standard out buffer. diff --git a/libc/include/stdlib.h b/src/libc/include/stdlib.h similarity index 59% rename from libc/include/stdlib.h rename to src/libc/include/stdlib.h index 572423b..fe70fa3 100644 --- a/libc/include/stdlib.h +++ b/src/libc/include/stdlib.h @@ -1,13 +1,11 @@ #ifndef _stdlib_h #define _stdlib_h -#if !defined(__cplusplus) -#include /* C doesn't have booleans by default. */ -#endif -#include -#include -#include #include +#include +#include +#include +#include #define ASSERT(b) ((#b) ? (void)0 : panic("Assertion failed!", __LINE__, __FILE__)) @@ -17,7 +15,7 @@ __attribute__((__noreturn__)) void exit(int); /** - * Converts a integer to a string. + * Converts an integer to a string. */ void itoa(char *buf, unsigned long int n, int base); @@ -26,4 +24,19 @@ void itoa(char *buf, unsigned long int n, int base); */ int intlen(int n, int base); +/** + * Converts a string to an integer. + */ +int atoi(char *str); + +/** + * Allocate n bytes of memory. + */ +void *malloc(size_t n); + +/** + * Free allocated memory. + */ +void free(void *p); + #endif diff --git a/libc/include/string.h b/src/libc/include/string.h similarity index 85% rename from libc/include/string.h rename to src/libc/include/string.h index 23cf307..5a98ea9 100644 --- a/libc/include/string.h +++ b/src/libc/include/string.h @@ -1,11 +1,10 @@ #ifndef _string_h #define _string_h -#if !defined(__cplusplus) -#include /* C doesn't have booleans by default. */ -#endif -#include -#include +#include +#include +#include +#include #include /** diff --git a/libc/include/sys/cdefs.h b/src/libc/include/sys/cdefs.h similarity index 100% rename from libc/include/sys/cdefs.h rename to src/libc/include/sys/cdefs.h diff --git a/src/libc/phapi/bitmap.c b/src/libc/phapi/bitmap.c new file mode 100644 index 0000000..51cbdbf --- /dev/null +++ b/src/libc/phapi/bitmap.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include +#include + +void use_bit(uint32_t *bitmap, uint32_t bit) +{ + bitmap[BIT_INDEX(bit)] |= (0x1 << BIT_OFFSET(bit)); +} + +void free_bit(uint32_t *bitmap, uint32_t bit) +{ + bitmap[BIT_INDEX(bit)] &= ~(0x1 << BIT_OFFSET(bit)); +} + +uint32_t test_bit(uint32_t *bitmap, uint32_t bit) +{ + return !(bitmap[BIT_INDEX(bit)] & (0x1 << BIT_OFFSET(bit))); +} diff --git a/src/libc/phapi/linked_list.c b/src/libc/phapi/linked_list.c new file mode 100644 index 0000000..5b5358c --- /dev/null +++ b/src/libc/phapi/linked_list.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include +#include + +Llist_t *Llist_create() +{ + Llist_t *head = malloc(sizeof(Llist_t)); + head->prev = NULL; + head->next = NULL; + + return head; +} + +void Llist_push(Llist_t *head, Llist_t *last) +{ + Llist_t *current = head; + while (current->next != NULL) { + current = current->next; + } + + current->next = last; + current->next->next = NULL; + current->next->prev = current; +} + +void List_pop(Llist_t *head) +{ + Llist_t *current = head; + while (current->next != NULL) { + current = current->next; + } + + current->prev->next = NULL; + free(current); +} + +void Llist_insert_after(Llist_t *location, Llist_t *element) +{ + Llist_t *next_location = location->next; + + location->next = element; + element->next = next_location; + + next_location->prev = element; + element->prev = location; +} + +void Llist_insert_before(Llist_t *location, Llist_t *element) +{ + Llist_t *prev_location = location->prev; + + location->prev = element; + element->prev = prev_location; + + prev_location->next = element; + element->next = location; +} + +void Llist_remove(Llist_t *location) +{ + Llist_t *next = location->next; + Llist_t *prev = location->prev; + + location->prev->next = next; + location->next->prev = prev; + + free(location); +} + +void Llist_destroy(Llist_t *head) +{ + Llist_t *current = head; + + while (current->next != NULL) { + current->prev = NULL; + current = current->next; + free(current->prev); + } + current->prev = NULL; + current->next = NULL; + free(current); +} + diff --git a/src/libc/phapi/list.c b/src/libc/phapi/list.c new file mode 100644 index 0000000..d9c2d48 --- /dev/null +++ b/src/libc/phapi/list.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include + +int8_t std_lessthan_pred(type_t a, type_t b) +{ + return (a < b) ? 1 : 0; +} + +list_t create_list(uint32_t max_size, lessthan_pred_t lessthan) +{ + list_t ret; + ret.array = malloc(max_size * sizeof(type_t)); + memset(ret.array, 0, max_size * sizeof(type_t)); + ret.size = 0; + ret.max_size = max_size; + ret.lessthan = lessthan; + return ret; +} + +list_t place_list(void *addr, uint32_t max_size, lessthan_pred_t lessthan) +{ + list_t ret; + ret.array = (type_t*) addr; + memset(ret.array, 0, max_size * sizeof(type_t)); + ret.size = 0; + ret.max_size = max_size; + ret.lessthan = lessthan; + return ret; +} + +void destroy_list(list_t *array) +{ + kfree(array->array); +} + +void insert_list(type_t item, list_t *array) +{ + ASSERT(array->lessthan); + uint32_t iterator = 0; + while (iterator < array->size && array->lessthan(array->array[iterator], item)) { + iterator++; + } + + if (iterator == array->size) { + array->array[array->size++] = item; + } else { + type_t tmp = array->array[iterator]; + array->array[iterator] = item; + while (iterator < array->size) { + iterator++; + type_t tmp2 = array->array[iterator]; + array->array[iterator] = tmp; + tmp = tmp2; + } + array->size++; + } +} + +type_t lookup_list(uint32_t i, list_t *array) +{ + ASSERT(i < array->size); + return array->array[i]; +} + +void remove_list(uint32_t i, list_t *array) +{ + while (i < array->size) { + array->array[i] = array->array[i + 1]; + i++; + } + array->size--; +} diff --git a/src/libc/stdio/getch.c b/src/libc/stdio/getch.c new file mode 100644 index 0000000..0678025 --- /dev/null +++ b/src/libc/stdio/getch.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include +#include + +extern void *stdin; +extern volatile uint32_t in_size; + +int getch() +{ + while (true) { + if (((uint8_t*)stdin)[in_size] != 0) { + in_size++; + break; + } + } + int c = ((uint8_t*)stdin)[in_size - 1]; + return c; +} diff --git a/src/libc/stdio/getchar.c b/src/libc/stdio/getchar.c new file mode 100644 index 0000000..1e45c1e --- /dev/null +++ b/src/libc/stdio/getchar.c @@ -0,0 +1,13 @@ +#include +#include +#include +#include +#include + +int getchar() +{ + int c = getch(); + putchar(c); + + return c; +} diff --git a/src/libc/stdio/gets.c b/src/libc/stdio/gets.c new file mode 100644 index 0000000..ecdf8a9 --- /dev/null +++ b/src/libc/stdio/gets.c @@ -0,0 +1,24 @@ +#include +#include +#include +#include +#include + +char *gets(char *str) +{ + int c = getch(); + int i = 0; + while (c != '\n') { + if (c != '\b') { + str[i++] = c; + putchar(c); + } else if (c == '\b' && i > 0) { + str[--i] = 0; + putchar(c); + } + c = getch(); + } + str[i] = '\0'; + putchar('\n'); + return str; +} diff --git a/src/libc/stdio/printf.c b/src/libc/stdio/printf.c new file mode 100644 index 0000000..6a04691 --- /dev/null +++ b/src/libc/stdio/printf.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include + +int printf(const char* restrict format, ...) +{ + va_list parameters; + va_start(parameters, format); + + int written = 0; + size_t amount; + bool rejected_bad_specifier = false; + + while ( *format != '\0' ) { + if ( *format != '%' ) { + print_c: + amount = 1; + while ( format[amount] && format[amount] != '%' ) + amount++; + write(format, amount); + format += amount; + written += amount; + continue; + } + + const char* format_begun_at = format; + + if ( *(++format) == '%' ) + goto print_c; + + if ( rejected_bad_specifier ) { + incomprehensible_conversion: + rejected_bad_specifier = true; + format = format_begun_at; + goto print_c; + } + if ( *format == 'c' ) { + format++; + char c = (char) va_arg(parameters, int /* char promotes to int */); + write(&c, sizeof(c)); + } else if ( *format == 's' ) { + format++; + const char* s = va_arg(parameters, const char*); + call(1, (uint32_t) s, strlen(s), 0, 0, 0); + } else if ( *format == 'd' ) { + format++; + int n = va_arg(parameters, int); + if (n) { + char s[intlen(n, 10)]; + itoa(s, n, 10); + call(1, (uint32_t) s, strlen(s), 0, 0, 0); + } else { + printf("0"); + } + } else if ( *format == 'x') { + format++; + int n = va_arg(parameters, int); + if (n) { + char s[intlen(n, 16)]; + itoa(s, n, 16); + call(1, (uint32_t) s, strlen(s), 0, 0, 0); + } else { + printf("0x0"); + } + } else { + goto incomprehensible_conversion; + } + } + + va_end(parameters); + + return written; +} diff --git a/src/libc/stdio/putchar.c b/src/libc/stdio/putchar.c new file mode 100644 index 0000000..c781773 --- /dev/null +++ b/src/libc/stdio/putchar.c @@ -0,0 +1,10 @@ +#include +#include +#include +#include +#include + +void putchar(char c) +{ + write_char(c); +} diff --git a/src/libc/stdio/puts.c b/src/libc/stdio/puts.c new file mode 100644 index 0000000..9ffc66d --- /dev/null +++ b/src/libc/stdio/puts.c @@ -0,0 +1,10 @@ +#include +#include +#include +#include +#include + +int puts(const char* string) +{ + return printf("%s\n", string); +} diff --git a/src/libc/stdlib/abort.c b/src/libc/stdlib/abort.c new file mode 100644 index 0000000..20c03c8 --- /dev/null +++ b/src/libc/stdlib/abort.c @@ -0,0 +1,19 @@ +#include +#include +#include +#include +#include + +__attribute__((__noreturn__)) +void abort(void) +{ +#if __STDC_HOSTED__ + // TODO: Properly implement abort(). + exit(1); +#elif defined(__is_photon_kernel) + panic("Kernel aborted!\n", __LINE__, __FILE__); +#else +#error "You need to implement abort() in this freestanding environment." +#endif + __builtin_unreachable(); +} diff --git a/src/libc/stdlib/atoi.c b/src/libc/stdlib/atoi.c new file mode 100644 index 0000000..6a05b86 --- /dev/null +++ b/src/libc/stdlib/atoi.c @@ -0,0 +1,17 @@ +#include +#include +#include +#include +#include + +int atoi(char *str) +{ + int res = 0; // Initialize result + + // Iterate through all characters of input string and update result + for (int i = 0; str[i] != '\0'; ++i) + res = res*10 + str[i] - '0'; + + // return result. + return res; +} diff --git a/src/libc/stdlib/exit.c b/src/libc/stdlib/exit.c new file mode 100644 index 0000000..adcdf2a --- /dev/null +++ b/src/libc/stdlib/exit.c @@ -0,0 +1,14 @@ +#include +#include +#include +#include +#include + +void exit(int status) +{ + while ( true ) + { + // TODO: Implement the exit system call. + (void) status; + } +} diff --git a/src/libc/stdlib/free.c b/src/libc/stdlib/free.c new file mode 100644 index 0000000..4e2d997 --- /dev/null +++ b/src/libc/stdlib/free.c @@ -0,0 +1,13 @@ +#include +#include +#include +#include +#include + +extern mem_heap_t *user_heap; + +void free(void *p) +{ + Llist_t *chunk = (Llist_t*) ((size_t) p - MEM_HEADER_SIZE); + free_mem_chunk(user_heap, chunk); +} diff --git a/src/libc/stdlib/intlen.c b/src/libc/stdlib/intlen.c new file mode 100644 index 0000000..13462a8 --- /dev/null +++ b/src/libc/stdlib/intlen.c @@ -0,0 +1,12 @@ +#include +#include +#include +#include +#include + +int intlen(int n, int base) +{ + int len; + for(len = 0; n != 0; n /= base, len++) {} + return len; +} diff --git a/src/libc/stdlib/itoa.c b/src/libc/stdlib/itoa.c new file mode 100644 index 0000000..0b39e29 --- /dev/null +++ b/src/libc/stdlib/itoa.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include +#include + +static void add_hex_prefix(char *buf) +{ + int len = strlen(buf); + for (int i = len - 1; i >= 0; i--) { + buf[i + 2] = buf[i]; + } + buf[len + 2] = '\0'; + buf[0] = '0'; + buf[1] = 'x'; +} + +void itoa(char *buf, unsigned long int n, int base) +{ + unsigned long int tmp; + int i; + + tmp = n; + i = 0; + + do { + tmp = n % base; + buf[i++] = (tmp < 10) ? (tmp + '0') : (tmp + 'a' - 10); + } while (n /= base); + buf[i] = '\0'; + + strrev(buf); + if (base == 16) { + add_hex_prefix(buf); + } +} diff --git a/src/libc/stdlib/malloc.c b/src/libc/stdlib/malloc.c new file mode 100644 index 0000000..6db9dc3 --- /dev/null +++ b/src/libc/stdlib/malloc.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include +#include + +mem_heap_t *user_heap; +Llist_t *user_free_mem_head; +mem_chunk_t *user_mem_chunk_head; +char malloc_initialized = 0; + +static void init_malloc() +{ + +} + +void *malloc(size_t n) +{ + if (!malloc_initialized) { + return NULL; + } + + Llist_t *chunk = alloc_mem_chunk(user_heap, n); + printk("Malloc: %x\n", chunk); + if (chunk == NULL) { + return NULL; + } + + void *ret_p = (void*) ((size_t) chunk - MEM_HEADER_SIZE); + return ret_p; +} diff --git a/src/libc/string/memcmp.c b/src/libc/string/memcmp.c new file mode 100644 index 0000000..669c702 --- /dev/null +++ b/src/libc/string/memcmp.c @@ -0,0 +1,17 @@ +#include +#include +#include +#include +#include + +int memcmp(const void* aptr, const void* bptr, size_t size) +{ + const unsigned char* a = (const unsigned char*) aptr; + const unsigned char* b = (const unsigned char*) bptr; + for ( size_t i = 0; i < size; i++ ) + if ( a[i] < b[i] ) + return -1; + else if ( b[i] < a[i] ) + return 1; + return 0; +} diff --git a/libc/string/memcpy.c b/src/libc/string/memcpy.c similarity index 76% rename from libc/string/memcpy.c rename to src/libc/string/memcpy.c index f400f77..e5cc75a 100644 --- a/libc/string/memcpy.c +++ b/src/libc/string/memcpy.c @@ -1,4 +1,8 @@ +#include +#include #include +#include +#include void* memcpy(void* dstptr, const void* srcptr, size_t size) { diff --git a/libc/string/memmove.c b/src/libc/string/memmove.c similarity index 81% rename from libc/string/memmove.c rename to src/libc/string/memmove.c index 99aac5d..60a4b19 100644 --- a/libc/string/memmove.c +++ b/src/libc/string/memmove.c @@ -1,4 +1,8 @@ +#include +#include #include +#include +#include void* memmove(void* dstptr, const void* srcptr, size_t size) { diff --git a/libc/string/memset.c b/src/libc/string/memset.c similarity index 72% rename from libc/string/memset.c rename to src/libc/string/memset.c index db0c002..e98fca7 100644 --- a/libc/string/memset.c +++ b/src/libc/string/memset.c @@ -1,4 +1,8 @@ +#include +#include #include +#include +#include void* memset(void* bufptr, int value, size_t size) { diff --git a/libc/string/memsetw.c b/src/libc/string/memsetw.c similarity index 70% rename from libc/string/memsetw.c rename to src/libc/string/memsetw.c index 0671241..9a33f87 100644 --- a/libc/string/memsetw.c +++ b/src/libc/string/memsetw.c @@ -1,4 +1,8 @@ +#include +#include #include +#include +#include void *memsetw(void *s, int c, size_t n) { diff --git a/libc/string/strcmp.c b/src/libc/string/strcmp.c similarity index 71% rename from libc/string/strcmp.c rename to src/libc/string/strcmp.c index 5264db0..8b33fc7 100644 --- a/libc/string/strcmp.c +++ b/src/libc/string/strcmp.c @@ -1,4 +1,8 @@ +#include +#include #include +#include +#include int strcmp(const char *s1, const char *s2) { diff --git a/libc/string/strlen.c b/src/libc/string/strlen.c similarity index 62% rename from libc/string/strlen.c rename to src/libc/string/strlen.c index 00506a4..f4cabb3 100644 --- a/libc/string/strlen.c +++ b/src/libc/string/strlen.c @@ -1,4 +1,8 @@ +#include +#include #include +#include +#include size_t strlen(const char* string) { diff --git a/libc/string/strrev.c b/src/libc/string/strrev.c similarity index 100% rename from libc/string/strrev.c rename to src/libc/string/strrev.c diff --git a/target-triplet-to-arch.sh b/src/target-triplet-to-arch.sh similarity index 100% rename from target-triplet-to-arch.sh rename to src/target-triplet-to-arch.sh