From b707eed2ccab33aa5c008a84d4a74788b4b2e52d Mon Sep 17 00:00:00 2001 From: David Date: Mon, 11 Nov 2013 19:02:19 +1300 Subject: Added %o %b %c in printf(), started memory detection --- Makefile | 4 +- boot/boot.asm | 49 ++++++++++----------- kernel.c | 37 +++++++++++++--- lowlevel.h | 2 + screen/console.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++-------- screen/console.h | 16 ++++--- string/common.c | 60 +++++++++++++++++++------ string/common.h | 8 ++-- toast.h | 17 ++++--- 9 files changed, 247 insertions(+), 78 deletions(-) diff --git a/Makefile b/Makefile index 534b71c..4226d9d 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,8 @@ SOURCES = boot/boot.o \ screen/console.o \ string/common.o \ kernel.o \ - lowlevel.o + lowlevel.o\ + panic.o all: $(SOURCES) link @@ -28,5 +29,6 @@ install: # sudo umount $(TOAST_TARGET) sudo mount /dev/loop0p1 $(TOAST_TARGET) sudo cp kernel $(TOAST_TARGET) + ls $(TOAST_TARGET) sudo umount $(TOAST_TARGET) bochs -qf bochsrc diff --git a/boot/boot.asm b/boot/boot.asm index 645061c..d79c9a1 100644 --- a/boot/boot.asm +++ b/boot/boot.asm @@ -2,54 +2,53 @@ ; get a prototype off the ground quickly without pissing around ; Declare constants used for creating a multiboot header. -MBALIGN equ 1<<0 ; align loaded modules on page boundaries -MEMINFO equ 1<<1 ; provide memory map -FLAGS equ MBALIGN | MEMINFO ; this is the Multiboot 'flag' field -MAGIC equ 0x1BADB002 ; 'magic number' lets bootloader find the header -CHECKSUM equ -(MAGIC + FLAGS) ; checksum of above, to prove we are multiboot - -; Declare a header as in the Multiboot Standard. We put this into a special -; section so we can force the header to be in the start of the final program. -; You don't need to understand all these details as it is just magic values that -; is documented in the multiboot standard. The bootloader will search for this -; magic sequence and recognize us as a multiboot kernel. +MBALIGN equ 1<<0 ; align loaded modules on page boundaries +MEMINFO equ 1<<1 ; Ask for memory map +FLAGS equ MBALIGN | MEMINFO +MAGIC equ 0x1BADB002 +CHECKSUM equ -(MAGIC + FLAGS) + +; Standard mutliboot header so GRUB and other bootloaders can boot the kernel section .multiboot align 4 dd MAGIC dd FLAGS dd CHECKSUM -; Currently the stack pointer register (esp) points at anything and using it may -; cause massive harm. Instead, we'll provide our own stack. We will allocate -; room for a small temporary stack by creating a symbol at the bottom of it, -; then allocating 16384 bytes for it, and finally creating a symbol at the top. +; Init our very own 16K stack section .bootstrap_stack align 4 stack_bottom: times 16384 db 0 stack_top: -; The linker script specifies _start as the entry point to the kernel and the -; bootloader will jump to this position once the kernel has been loaded. It -; doesn't make sense to return from this function as the bootloader is gone. section .text global _start +global _kernel_exit + _start: + ; Functions in external objects extern kernel_main - extern console_print - extern console_set_colors + extern console_print_string + extern console_set_color + ; Set stack up ready for C mov esp, stack_top + push eax + push ebx call kernel_main ; Let the user know that kernel_main() exited - push word 0x0007 - call console_set_colors - push mainexit - call console_print + push 0x0A + call console_set_color ; Reset text colour + push exitmain + call console_print_string + + ; Wake us not from our slumber cli +_kernel_exit: .hang: hlt jmp .hang -mainexit db 10,"asm: kernel_main() exited",0 +exitmain db 10,"boot: kernel_main() exited",0 \ No newline at end of file diff --git a/kernel.c b/kernel.c index 293045e..bb54c18 100644 --- a/kernel.c +++ b/kernel.c @@ -16,7 +16,6 @@ * */ - // Complain if some pleb's not using a cross-compiler #if defined(__linux__) #error "You're not using a cross-compiler. Good luck with that." @@ -24,16 +23,40 @@ #include -void kernel_main() +void kernel_main(multiboot_info_t *mbd, unsigned int magic) { - char b[10]; console_init(); console_set_colors(COLOR_BRIGHT_GRAY,COLOR_BLACK); console_clear(); - console_print("Welcome to Toast "KERNEL_VERSION" (nickname '"KERNEL_NICKNAME"')\n"); + console_print("Welcome to Toast v%d.%d (nickname '%s')\n",KERNEL_VERSION_MAJ,KERNEL_VERSION_MIN,KERNEL_NICKNAME); console_set_color(COLOR_RED); + + // Print some stuff about the bootload console_print("Here is kernel_main()\n"); - char test[] = "1234"; - int a = atoi(test); - itoa(a,b); + console_print("Bootloader: %s\n",mbd->boot_loader_name); + console_print("BIOS Memory: %d Bytes\n",mbd->mem_upper - mbd->mem_lower);// find out 100% what this is + console_print("Kernel: %s\n",mbd->cmdline); + console_print("Flags: %b\n",mbd->flags); + console_print("Boot Device: %x\n",mbd->boot_device); + + console_print("--------------------------------\nShowing console_print() off...\n%dd in binary is %b\n%oo = %xh = %dd\n%d is the ASCII code for %c\n--------------------------------\n",100,100,1234,1234,1234,112,112); + + + // Show all memory stuff + uint32_t mmaps = mbd->mmap_length; + + multiboot_memory_map_t* mmap = mbd->mmap_addr; + while(mmap < mbd->mmap_addr + mbd->mmap_length) + { + mmap = (multiboot_memory_map_t*) ( (unsigned int)mmap + mmap->size + sizeof(unsigned int) ); + console_print("%s: 0x%x to 0x%x = %d bytes\n", + mmap->type == 1? "AVAILABLE" : "RESERVED ", + mmap->addr, + mmap->addr+mmap->len-1, + mmap->len + ); + } + + + //panic(0x4655434B); // (TEST) testing panic } \ No newline at end of file diff --git a/lowlevel.h b/lowlevel.h index d4dcb55..0671599 100644 --- a/lowlevel.h +++ b/lowlevel.h @@ -20,5 +20,7 @@ #define LOWLEVEL_H void outb(uint16_t p,uint8_t val); +void disable_ints(); +void enable_ints(); #endif \ No newline at end of file diff --git a/screen/console.c b/screen/console.c index 57f9d6b..00e9ebb 100644 --- a/screen/console.c +++ b/screen/console.c @@ -30,6 +30,15 @@ void console_init() console_pointer = 0; } + +/********************************************************* + * Update cursor position to x,y co-ord for next char + ********************************************************/ +void console_set_cursor_xy(uint8_t x,uint8_t y) +{ + console_pointer = (160*y) + (2*x); +} + /********************************************************* * Update flashing cursor to match console_position * Note: Does _NOT_ dictate the pos for next printed byte @@ -47,18 +56,18 @@ void console_update_cursor() ********************************************************/ void console_clear() { - int console_pointer; - for (console_pointer = 0; console_pointer < 4000; console_pointer++) + for (console_pointer = 0; console_pointer < 4000; console_pointer+=2) { - console_buffer[console_pointer] = console_color; - console_buffer[console_pointer++] = 0; + console_buffer[console_pointer] = 0; + console_buffer[console_pointer+1] = console_color; } - //console_update_cursor(); + console_pointer = 0; + console_update_cursor(); } /********************************************************* - * Set the console foreground and background colours + * Set the console foreground AND background colours ********************************************************/ void console_set_colors(uint8_t fg, uint8_t bg) { @@ -67,7 +76,7 @@ void console_set_colors(uint8_t fg, uint8_t bg) /********************************************************* - * Set the console foreground colour + * Set ONLY the console foreground colour ********************************************************/ void console_set_color(uint8_t fg) { @@ -75,26 +84,113 @@ void console_set_color(uint8_t fg) console_color |= fg; // Apply foreground color } + +/********************************************************* + * Print a single character + ********************************************************/ +void console_print_char(const char c) +{ + // Scroll the screen up a line if the pointer is out of bounds + if (console_pointer >= 4000) + console_scroll(); + switch (c) + { + case 8: + console_buffer[console_pointer-=2] = 0; + break; + + case 10: + console_pointer += 160-(console_pointer%160); + break; + + default: + console_buffer[console_pointer++] = c; + console_buffer[console_pointer++] = console_color; + } +} + + +/********************************************************* + * Print an integer of a certain base + ********************************************************/ +void console_print_num(const uint32_t num, const uint8_t base) +{ + char buffer[32]; + uint32_t i = 0; + if (num == 0) + { + console_print_char('0'); + } else { + itoa(num,buffer,base); + // Find the first digit which isn't a trailing digit + while(buffer[i++] == '0'); + console_print_string(buffer+i-1); + } +} + /********************************************************* - * Print a null-terminated string to the text screen + * Print a single null-terminated string ********************************************************/ -void console_print(char *string, ...) +void console_print_string(const char *string) { + uint16_t i = 0; + while(string[i] != 0) + console_print_char(string[i++]); + console_update_cursor(); +} + +/********************************************************* + * Print a single null-terminated string + ********************************************************/ +void console_scroll(/*uint8_t lines*/) +{ + //memcpy(console_buffer, console_buffer+160, 3840); + memcpy(console_buffer, console_buffer+160, 3840); + memset(console_buffer+3840, 0, 160); + console_pointer = 3840; +} + + +/********************************************************* + * Print a formatted string + ********************************************************/ +void console_print(const char* format, ...) +{ + va_list strings; + va_start(strings,format); uint16_t i; - for (i = 0; i < strlen(string); i++) + uint64_t length = strlen(format); + + for (i = 0; i < length; i++) { - // If special char, handle appropriately - if (string[i] < 32) + if (format[i] == '%') { - switch (string[i]) - case 10: - console_pointer = 160 + (console_pointer / 160) * 160; + switch (format[++i]) + { + case 's': + console_print_string(va_arg(strings, char*)); + break; + case 'c': + console_print_char(va_arg(strings, uint64_t)); + break; + case 'd': + console_print_num(va_arg(strings, uint64_t),10); + break; + case 'x': + console_print_num(va_arg(strings, uint64_t),16); + break; + case 'o': + console_print_num(va_arg(strings, uint64_t),8); + break; + case 'b': + console_print_num(va_arg(strings, uint64_t),2); + break; + } } else { - console_buffer[console_pointer++] = string[i]; - console_buffer[console_pointer++] = console_color; + console_print_char(format[i]); } } - console_update_cursor(); + va_end(strings); } #endif \ No newline at end of file diff --git a/screen/console.h b/screen/console.h index 66a867a..f037592 100644 --- a/screen/console.h +++ b/screen/console.h @@ -19,6 +19,8 @@ #ifndef __CONSOLE_H #define __CONSOLE_H +#include + #define console_width 80 #define console_height 25 #define console_x_pos (console_pointer%(2*console_width)) @@ -32,28 +34,32 @@ #define COLOR_PURPLE 0x5 #define COLOR_GOLD 0x6 #define COLOR_BRIGHT_GREY 0x7 -#define COLOR_BRIGHT_GRAY 0x7 // Alias for grey vs gray #define COLOR_GRAY 0x8 -#define COLOR_GREY 0x8 // Alias for grey vs gray #define COLOR_BRIGHT_BLUE 0x9 #define COLOR_BRIGHT_GREEN 0xA -#define COLOR_LIME 0xA // Alias for lime vs bright green #define COLOR_AQUA 0xB #define COLOR_RED 0xC #define COLOR_PINK 0xD #define COLOR_YELLOW 0xE #define COLOR_WHITE 0xF +#define COLOR_BRIGHT_GRAY COLOR_BRIGHT_GREY // Alias for grey vs gray +#define COLOR_GREY COLOR_GRAY // Alias for grey vs gray +#define COLOR_LIME COLOR_BRIGHT_GREEN // Alias for lime vs bright green char* console_buffer; uint16_t console_pointer; uint8_t console_color; void console_init(); +void console_set_cursor_xy(uint8_t x,uint8_t y); void console_update_cursor(); void console_clear(); void console_set_colors(uint8_t fg, uint8_t bg); void console_set_color(uint8_t fg); -void console_print(char *string, ...); - +void console_print_char(const char c); +void console_print_string(const char *string); +void console_print(const char* format,...); +void console_print_num(uint32_t num, uint8_t base); +void console_scroll(); #endif \ No newline at end of file diff --git a/string/common.c b/string/common.c index d61bdff..6edce1a 100644 --- a/string/common.c +++ b/string/common.c @@ -21,31 +21,31 @@ #include -uint64_t strlen(char *string) +uint64_t strlen(const char *string) { uint64_t l = 0; - while (string[l] != 0) - l++; + while (string[++l] != 0); return l; } -void itoa(uint32_t num,char *buffer) +bool itoa(uint32_t num, char *buffer, uint8_t base) { + // Lookup table is valid up to heptadecimal (it's an inside joke) + char lookup[] = "0123456789ABCDEFG"; + if (base > 17) + return FALSE; uint8_t i; - uint8_t remainder; - - for(i = 10; i > 0; i--) + /// (Buffer size is 32 bytes) + for(i = 31; i > 0; i--) { - remainder = num % 10; - num = (uint32_t)(num /10); - buffer[i-1] = remainder+48; - console_print(buffer); + buffer[i-1] = lookup[(num % base)]; + num = (uint32_t)(num/base); } - buffer[10] = 0; - + buffer[31] = 0; + return TRUE; } -uint32_t atoi(char *string) +uint32_t atoi(const char *string) { uint32_t i; uint32_t multiplier = 1; @@ -58,4 +58,36 @@ uint32_t atoi(char *string) return total; } +//strcmp() +// UNFINISHED +/*bool string_contains(char *haystack, char *needle) +{ + return FALSE; + uint32_t i; + for (i = strlen(haystack)-(strlen(needle)+1); i >= 0; i--) + { + // if () + } +}*/ + +void memcpy(void *to, const void *from, uint32_t size) +{ + // TO DO: copy more than one byte at a time + char *t = to; + const char *f = from; + uint32_t i; + for (i = 0; i < size; i++) + t[i] = f[i]; +} + + +void memset(void *to, uint8_t value, uint32_t size) +{ + // TO DO: copy more than one byte at a time + char *t = to; + uint32_t i; + for (i = 0; i < size; i++) + t[i] = value; + +} #endif diff --git a/string/common.h b/string/common.h index f332f1c..82ad4b1 100644 --- a/string/common.h +++ b/string/common.h @@ -19,8 +19,10 @@ #ifndef STRING_COMMON_H #define STRING_COMMON_H -uint64_t strlen(char *string); -void itoa(uint32_t num,char *buffer); -uint32_t atoi(char *string); +uint64_t strlen(const char *string); +bool itoa(uint32_t num, char *buffer, uint8_t base); +uint32_t atoi(const char *string); +void memcpy(void *to, const void *from, uint32_t size); +void memset(void *to, uint8_t value, uint32_t size); #endif \ No newline at end of file diff --git a/toast.h b/toast.h index 479bd41..7aa1c3d 100644 --- a/toast.h +++ b/toast.h @@ -19,17 +19,24 @@ #ifndef TOAST_H #define TOAST_H -#define KERNEL_VERSION "0.1" +#define KERNEL_VERSION_MAJ 0 +#define KERNEL_VERSION_MIN 1 #define KERNEL_NICKNAME "Hydrogen" +#define NULL 0 +#define SUCCESS 1 -#include // Get our booleans defined #include // uint_8 etc +#include // Get our boolean types defined -#include // Console output functions -//#include // Console output functions +#define TRUE true +#define FALSE false + +#include // Console output functions #include // Low level assembly, eg outb(port,val) #include // Common string functions -//#include // Common string functions +#include // Kernel panic and emergency procedures +#include + // KERNEL.C void kernel_main(); -- cgit v1.1