From 009a998876458f1cbab925c56c95b90d48d72157 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 27 Mar 2014 20:03:33 +1300 Subject: Added a bunch of things. This is the epitome of a bad commit message --- Makefile | 18 +++-- kernel.c | 138 +++++++++++++++++++++++++++------- lowlevel.c | 8 +- multiboot.h | 225 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ panic.c | 32 ++++++++ panic.h | 25 +++++++ panic.o | Bin 0 -> 1228 bytes screen/console.c | 9 +++ screen/console.h | 8 +- string/common.c | 33 ++++++-- string/common.h | 1 + toast.h | 7 +- 12 files changed, 452 insertions(+), 52 deletions(-) create mode 100644 multiboot.h create mode 100644 panic.c create mode 100644 panic.h create mode 100644 panic.o diff --git a/Makefile b/Makefile index 1b64ea7..a50cf4b 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,9 @@ CFLAGS = -I. -std=gnu99 -ffreestanding -O2 -Wall -Wextra ASFLAGS = -felf LDFLAGS = -Tlink.ld -TOAST_TARGET = ~/programming/toast/toast_img/ +KERNEL = toastk + +TOAST_TARGET = ~/programming/toast/toast-hdd-img/ SOURCES = boot/boot.o \ screen/console.o \ string/common.o \ @@ -17,18 +19,20 @@ SOURCES = boot/boot.o \ all: $(SOURCES) link clean: - - rm *.o */*.o kernel + - rm *.o */*.o $(KERNEL) link: - - $(LD) $(LDFLAGS) -o kernel $(SOURCES) + - $(LD) $(LDFLAGS) -o $(KERNEL) $(SOURCES) .s.o: - nasm $(ASFLAGS) $< install: -# sudo umount $(TOAST_TARGET) - sudo mount /dev/loop1p1 $(TOAST_TARGET) - sudo cp kernel $(TOAST_TARGET) + # need a better way to automate this first bit + sudo mount /dev/loop0p1 $(TOAST_TARGET) + + sudo cp $(KERNEL) $(TOAST_TARGET) ls $(TOAST_TARGET) sudo umount $(TOAST_TARGET) - bochs -qf bochsrc + #bochs -qf bochsrc + qemu-system-i386 -m 64 -hdd ../toast-hdd.img diff --git a/kernel.c b/kernel.c index 8ca7927..5c9f16d 100644 --- a/kernel.c +++ b/kernel.c @@ -16,48 +16,128 @@ * */ -// Complain if some pleb's not using a cross-compiler +// Complain if some pleb's using a linux toolchain and not cross-compiling #if defined(__linux__) #error "You're not using a cross-compiler. Good luck with that." #endif #include -void kernel_main(multiboot_info_t *mbd, unsigned int magic) +// vv-- Put me somewhere --vv +uint32_t TOTAL_MEMORY = 0; // Total memory. Typically set by k_tally_available_memory(). + // It must be initialised to 0 so that if it's not set otherwise, nothing will think there's memory available +bool KERNEL_OPTION_QUIET = FALSE; +bool KERNEL_OPTION_SILENT = FALSE; +bool KERNEL_OPTION_ESHELL = FALSE; +// ^^-- put me somewhere --^ + +void kernel_main(multiboot_info_t *mbd, uint32_t magic) { + //********************************************************* + // First things first. Parse the command line. Quick guide: + // + // o quiet - Don't print so much stuff to the screen during boot + // o silent - Don't print anything at all during boot (implies quiet) + // o eshell - (RESERVED) Will be used to enter emergency shell + // + if (string_contains( (char*)(mbd->cmdline) , "quiet")) + KERNEL_OPTION_QUIET = TRUE; + + if (string_contains( (char*)(mbd->cmdline) , "silent")) + { + KERNEL_OPTION_QUIET = TRUE; + KERNEL_OPTION_SILENT = TRUE; + } + if (string_contains( (char*)(mbd->cmdline) , "eshell")) + KERNEL_OPTION_ESHELL = TRUE; + //********************************************************* + + //********************************************************* + // Do some important things before we forget + k_tally_available_memory(mbd); + + // Init the text console and colours console_init(); - console_set_colors(COLOR_BRIGHT_GRAY,COLOR_BLACK); + console_set_colors(COLOR_BRIGHT_GRAY, COLOR_BLACK); + console_swap_colors(); + console_set_colors(COLOR_BRIGHT_GRAY, COLOR_BLACK); console_clear(); - 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"); - 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); - - console_print("strlen(\"asdf\") == %d\n",strlen("asdf")); - console_print("strlen(\"\") == %d\n",strlen("")); - // 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) + //********************************************************* + + if (!KERNEL_OPTION_QUIET) + { + // Print some stuff about the environment + console_print("Here is kernel_main()\n"); + console_print("Bootloader: %s\n",mbd->boot_loader_name); + console_print("Kernel: %s\n",mbd->cmdline); + console_print("Flags: %b\n",mbd->flags); + console_print("Boot Device: %x\n",mbd->boot_device); + + // Dump some info about the memory blocks/regions available/reserved + k_dump_memory_blocks(mbd); + } + if (!KERNEL_OPTION_SILENT) + { + console_print("Welcome to Toast v%d.%d (nickname '%s')\nMemory: %dMiB", + KERNEL_VERSION_MAJ, + KERNEL_VERSION_MIN, + KERNEL_NICKNAME, + TOTAL_MEMORY/1048576); + } + //panic(0x4655434B); // (TEST) testing panic +} + +/********************************************************* + * Tally/total the amount of available memory and store + * it for later use. Returns pointer to total mem figure + ********************************************************/ +uint32_t *k_tally_available_memory(multiboot_info_t *mbd) +{ + multiboot_memory_map_t* mmap = (multiboot_memory_map_t*)mbd->mmap_addr; + TOTAL_MEMORY = 0; + + while((uint32_t)mmap < mbd->mmap_addr + mbd->mmap_length) + { + mmap = (multiboot_memory_map_t*)( (uint32_t)mmap + mmap->size + sizeof(uint32_t) ); + + if (mmap->type == 1) // available + TOTAL_MEMORY += (uint32_t)mmap->len; + } + return &TOTAL_MEMORY; +} + +/********************************************************* + * Dump information about the blocks of memory. What + * starts and finishes where and available/reserved + ********************************************************/ +void k_dump_memory_blocks(multiboot_info_t *mbd) +{ + multiboot_memory_map_t* mmap = (multiboot_memory_map_t*)mbd->mmap_addr; + + // While we're pointing to a mem map struct within the supplied range... + while((uint32_t)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 = (multiboot_memory_map_t*)( (uint32_t)mmap + mmap->size + sizeof(uint32_t) ); + console_print("["); + + // Save current console colours + console_swap_colors(); + + if (mmap->type == 1) + { + console_set_colors(COLOR_GREEN, COLOR_BLACK); + console_print(" FREE "); + } else { + console_set_colors(COLOR_RED, COLOR_BLACK); + console_print(" RESERVED "); + } + // Restore old console colours + console_swap_colors(); + + console_print("] 0x%x to 0x%x = %d bytes\n", (uint32_t)mmap->addr, (uint32_t)mmap->addr + (uint32_t)mmap->len-1, (uint32_t)mmap->len ); } - - - //panic(0x4655434B); // (TEST) testing panic } \ No newline at end of file diff --git a/lowlevel.c b/lowlevel.c index 0fc353a..4b78757 100644 --- a/lowlevel.c +++ b/lowlevel.c @@ -21,22 +21,22 @@ #include -void outb(uint16_t p,uint8_t val) +void outb(uint16_t port, uint8_t data) { asm("outb %%al,%%dx;" : - :"d"(p),"a"(val) + :"d"(port),"a"(data) ); } void disable_ints() { - asm("cli"::); + asm("cli"); } void enable_ints() { - asm("sti"::); + asm("sti"); } #endif \ No newline at end of file diff --git a/multiboot.h b/multiboot.h new file mode 100644 index 0000000..0b40dc3 --- /dev/null +++ b/multiboot.h @@ -0,0 +1,225 @@ +/* multiboot.h - Multiboot header file. */ +// Cheers to OSDev.org Wiki for this, it would've taken hours reinventing the wheel on this + +/* Copyright (C) 1999,2003,2007,2008,2009 Free Software Foundation, Inc. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to +* deal in the Software without restriction, including without limitation the +* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +* sell copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY +* DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef MULTIBOOT_HEADER +#define MULTIBOOT_HEADER 1 + +/* How many bytes from the start of the file we search for the header. */ +#define MULTIBOOT_SEARCH 8192 + +/* The magic field should contain this. */ +#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 + +/* This should be in %eax. */ +#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 + +/* The bits in the required part of flags field we don't support. */ +#define MULTIBOOT_UNSUPPORTED 0x0000fffc + +/* Alignment of multiboot modules. */ +#define MULTIBOOT_MOD_ALIGN 0x00001000 + +/* Alignment of the multiboot info structure. */ +#define MULTIBOOT_INFO_ALIGN 0x00000004 + +/* Flags set in the 'flags' member of the multiboot header. */ + +/* Align all boot modules on i386 page (4KB) boundaries. */ +#define MULTIBOOT_PAGE_ALIGN 0x00000001 + +/* Must pass memory information to OS. */ +#define MULTIBOOT_MEMORY_INFO 0x00000002 + +/* Must pass video information to OS. */ +#define MULTIBOOT_VIDEO_MODE 0x00000004 + +/* This flag indicates the use of the address fields in the header. */ +#define MULTIBOOT_AOUT_KLUDGE 0x00010000 + +/* Flags to be set in the 'flags' member of the multiboot info structure. */ + +/* is there basic lower/upper memory information? */ +#define MULTIBOOT_INFO_MEMORY 0x00000001 +/* is there a boot device set? */ +#define MULTIBOOT_INFO_BOOTDEV 0x00000002 +/* is the command-line defined? */ +#define MULTIBOOT_INFO_CMDLINE 0x00000004 +/* are there modules to do something with? */ +#define MULTIBOOT_INFO_MODS 0x00000008 + +/* These next two are mutually exclusive */ + +/* is there a symbol table loaded? */ +#define MULTIBOOT_INFO_AOUT_SYMS 0x00000010 +/* is there an ELF section header table? */ +#define MULTIBOOT_INFO_ELF_SHDR 0X00000020 + +/* is there a full memory map? */ +#define MULTIBOOT_INFO_MEM_MAP 0x00000040 + +/* Is there drive info? */ +#define MULTIBOOT_INFO_DRIVE_INFO 0x00000080 + +/* Is there a config table? */ +#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100 + +/* Is there a boot loader name? */ +#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200 + +/* Is there a APM table? */ +#define MULTIBOOT_INFO_APM_TABLE 0x00000400 + +/* Is there video information? */ +#define MULTIBOOT_INFO_VIDEO_INFO 0x00000800 + +#ifndef ASM_FILE + +typedef unsigned short multiboot_uint16_t; +typedef unsigned int multiboot_uint32_t; +typedef unsigned long long multiboot_uint64_t; + +struct multiboot_header +{ + /* Must be MULTIBOOT_MAGIC - see above. */ + multiboot_uint32_t magic; + + /* Feature flags. */ + multiboot_uint32_t flags; + + /* The above fields plus this one must equal 0 mod 2^32. */ + multiboot_uint32_t checksum; + + /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */ + multiboot_uint32_t header_addr; + multiboot_uint32_t load_addr; + multiboot_uint32_t load_end_addr; + multiboot_uint32_t bss_end_addr; + multiboot_uint32_t entry_addr; + + /* These are only valid if MULTIBOOT_VIDEO_MODE is set. */ + multiboot_uint32_t mode_type; + multiboot_uint32_t width; + multiboot_uint32_t height; + multiboot_uint32_t depth; +}; + +/* The symbol table for a.out. */ +struct multiboot_aout_symbol_table +{ + multiboot_uint32_t tabsize; + multiboot_uint32_t strsize; + multiboot_uint32_t addr; + multiboot_uint32_t reserved; +}; +typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t; + +/* The section header table for ELF. */ +struct multiboot_elf_section_header_table +{ + multiboot_uint32_t num; + multiboot_uint32_t size; + multiboot_uint32_t addr; + multiboot_uint32_t shndx; +}; +typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t; + +struct multiboot_info +{ + /* Multiboot info version number */ + multiboot_uint32_t flags; + + /* Available memory from BIOS */ + multiboot_uint32_t mem_lower; + multiboot_uint32_t mem_upper; + + /* "root" partition */ + multiboot_uint32_t boot_device; + + /* Kernel command line */ + multiboot_uint32_t cmdline; + + /* Boot-Module list */ + multiboot_uint32_t mods_count; + multiboot_uint32_t mods_addr; + + union + { + multiboot_aout_symbol_table_t aout_sym; + multiboot_elf_section_header_table_t elf_sec; + } u; + + /* Memory Mapping buffer */ + multiboot_uint32_t mmap_length; + multiboot_uint32_t mmap_addr; + + /* Drive Info buffer */ + multiboot_uint32_t drives_length; + multiboot_uint32_t drives_addr; + + /* ROM configuration table */ + multiboot_uint32_t config_table; + + /* Boot Loader Name */ + multiboot_uint32_t boot_loader_name; + + /* APM table */ + multiboot_uint32_t apm_table; + + /* Video */ + multiboot_uint32_t vbe_control_info; + multiboot_uint32_t vbe_mode_info; + multiboot_uint16_t vbe_mode; + multiboot_uint16_t vbe_interface_seg; + multiboot_uint16_t vbe_interface_off; + multiboot_uint16_t vbe_interface_len; +}; +typedef struct multiboot_info multiboot_info_t; + +struct multiboot_mmap_entry +{ + multiboot_uint32_t size; + multiboot_uint64_t addr; + multiboot_uint64_t len; + #define MULTIBOOT_MEMORY_AVAILABLE 1 + #define MULTIBOOT_MEMORY_RESERVED 2 + multiboot_uint32_t type; +} __attribute__((packed)); +typedef struct multiboot_mmap_entry multiboot_memory_map_t; + +struct multiboot_mod_list +{ + /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */ + multiboot_uint32_t mod_start; + multiboot_uint32_t mod_end; + + /* Module command line */ + multiboot_uint32_t cmdline; + + /* padding to take it to 16 bytes (must be zero) */ + multiboot_uint32_t pad; +}; +typedef struct multiboot_mod_list multiboot_module_t; + +#endif /* ! ASM_FILE */ + +#endif /* ! MULTIBOOT_HEADER */ \ No newline at end of file diff --git a/panic.c b/panic.c new file mode 100644 index 0000000..d524e6c --- /dev/null +++ b/panic.c @@ -0,0 +1,32 @@ +/* + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +#ifndef PANIC_C +#define PANIC_C + +#include + +void panic() +{ + console_set_colors(COLOR_WHITE,COLOR_GREEN); + console_clear(); + console_print("Kernel panic, sorry!"); + _kernel_exit(); +} + +#endif \ No newline at end of file diff --git a/panic.h b/panic.h new file mode 100644 index 0000000..dc7065e --- /dev/null +++ b/panic.h @@ -0,0 +1,25 @@ +/* + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +#ifndef PANIC_H +#define PANIC_H + +void panic(); // panic.c +void _kernel_exit(); // boot.asm) + +#endif \ No newline at end of file diff --git a/panic.o b/panic.o new file mode 100644 index 0000000..fbc007d Binary files /dev/null and b/panic.o differ diff --git a/screen/console.c b/screen/console.c index cceab6c..71a8456 100644 --- a/screen/console.c +++ b/screen/console.c @@ -74,6 +74,15 @@ void console_set_colors(uint8_t fg, uint8_t bg) console_color = (bg << 4) | fg; } +/********************************************************* + * Swap the current console colours out + ********************************************************/ +void console_swap_colors() +{ + uint32_t t = console_color; + console_color = saved_console_color; + saved_console_color = t; +} /********************************************************* * Set ONLY the console foreground colour diff --git a/screen/console.h b/screen/console.h index f037592..fabbc4a 100644 --- a/screen/console.h +++ b/screen/console.h @@ -43,13 +43,14 @@ #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 +#define COLOR_BRIGHT_GRAY COLOR_BRIGHT_GREY // Alias for grey <--> gray +#define COLOR_GREY COLOR_GRAY // Alias for grey <--> gray +#define COLOR_LIME COLOR_BRIGHT_GREEN // Alias for lime <--> bright green char* console_buffer; uint16_t console_pointer; uint8_t console_color; +uint8_t saved_console_color; void console_init(); void console_set_cursor_xy(uint8_t x,uint8_t y); @@ -57,6 +58,7 @@ 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_swap_colors(); void console_print_char(const char c); void console_print_string(const char *string); void console_print(const char* format,...); diff --git a/string/common.c b/string/common.c index b9adc3e..5e9f8b1 100644 --- a/string/common.c +++ b/string/common.c @@ -60,15 +60,36 @@ uint32_t atoi(const char *string) //strcmp() // UNFINISHED -/*bool string_contains(char *haystack, char *needle) + +// HAYSTACK: +// foo bar hello woo + +// NEEDLE: +// hello +bool string_contains(char *haystack, char *needle) { - return FALSE; uint32_t i; - for (i = strlen(haystack)-(strlen(needle)+1); i >= 0; i--) + uint32_t j; + uint32_t hlen = strlen(haystack); + uint32_t nlen = strlen(needle); + + // If needle is longer than haystack, it can't be in there! + if (strlen(needle) > strlen(haystack)) + return FALSE; + + for (i = 0; i < hlen; i++) { - // if () + for (j = 0; j < nlen; j++) + { + if (haystack[j+i] != needle[j]) + break; + } + // Reached end of haystack without mismatch, we've found the needle! + if (j == nlen) + return TRUE; } -}*/ + return FALSE; +} void memcpy(void *to, const void *from, uint32_t size) { @@ -90,4 +111,4 @@ void memset(void *to, uint8_t value, uint32_t size) t[i] = value; } -#endif +#endif \ No newline at end of file diff --git a/string/common.h b/string/common.h index 82ad4b1..1ca441b 100644 --- a/string/common.h +++ b/string/common.h @@ -22,6 +22,7 @@ uint64_t strlen(const char *string); bool itoa(uint32_t num, char *buffer, uint8_t base); uint32_t atoi(const char *string); +bool string_contains(char *haystack, char *needle); void memcpy(void *to, const void *from, uint32_t size); void memset(void *to, uint8_t value, uint32_t size); diff --git a/toast.h b/toast.h index 7aa1c3d..a2aeefa 100644 --- a/toast.h +++ b/toast.h @@ -25,7 +25,7 @@ #define NULL 0 #define SUCCESS 1 -#include // uint_8 etc +#include // uint8_t etc #include // Get our boolean types defined #define TRUE true @@ -35,10 +35,11 @@ #include // Low level assembly, eg outb(port,val) #include // Common string functions #include // Kernel panic and emergency procedures -#include - +#include // Multiboot structs predefined // KERNEL.C void kernel_main(); +void k_dump_memory_blocks(multiboot_info_t *mbd); +uint32_t *k_tally_available_memory(multiboot_info_t *mbd); #endif -- cgit v1.1