diff options
-rw-r--r-- | makefile | 15 | ||||
-rw-r--r-- | src/kernel/main.c | 93 | ||||
-rw-r--r-- | src/kernel/serial.asm | 29 | ||||
-rw-r--r-- | src/kernel/serial.h | 38 | ||||
-rw-r--r-- | src/kernel/stub.asm | 36 | ||||
-rw-r--r-- | src/kernel/vga.c | 23 | ||||
-rw-r--r-- | src/kernel/vga.h | 6 |
7 files changed, 161 insertions, 79 deletions
@@ -5,13 +5,14 @@ cd: kernel fs grub2-mkrescue out/fs -o out/cd.iso --product-name=portland --product-version=0.0.9 kernel: obj out - nasm src/kernel/stub.asm -o obj/kstub.o -f elf32 - gcc -c src/kernel/files.c -o obj/kfiles.o -ffreestanding -nostdlib -m32 - gcc -c src/kernel/main.c -o obj/kmain.o -ffreestanding -nostdlib -m32 - gcc -c src/kernel/mem.c -o obj/kmem.o -ffreestanding -nostdlib -m32 - gcc -c src/kernel/proc.c -o obj/kproc.o -ffreestanding -nostdlib -m32 - gcc -c src/kernel/vga.c -o obj/kvga.o -ffreestanding -nostdlib -m32 - ld obj/kstub.o obj/kfiles.o obj/kmain.o obj/kmem.o obj/kproc.o obj/kvga.o \ + nasm src/kernel/serial.asm -o obj/kserial.o -f elf32 + nasm src/kernel/stub.asm -o obj/kstub.o -f elf32 + gcc -c src/kernel/files.c -o obj/kfiles.o -ffreestanding -nostdlib -m32 + gcc -c src/kernel/main.c -o obj/kmain.o -ffreestanding -nostdlib -m32 + gcc -c src/kernel/mem.c -o obj/kmem.o -ffreestanding -nostdlib -m32 + gcc -c src/kernel/proc.c -o obj/kproc.o -ffreestanding -nostdlib -m32 + gcc -c src/kernel/vga.c -o obj/kvga.o -ffreestanding -nostdlib -m32 + ld obj/kstub.o obj/kfiles.o obj/kmain.o obj/kmem.o obj/kproc.o obj/kserial.o obj/kvga.o \ -o out/kernel.elf -T src/kernel/link.ld -s --orphan-handling=discard -melf_i386 diff --git a/src/kernel/main.c b/src/kernel/main.c index 75edeec..ab8eb91 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -23,8 +23,6 @@ OF THIS SOFTWARE. #include "proc.h" #include <stdbool.h> -extern uint32_t info_pointer; - enum tag_type { BOOT_COMMAND = 1, LOADER_NAME = 2, @@ -52,7 +50,6 @@ enum tag_type { struct tag_start { uint32_t type; uint32_t size; - uint8_t rest; } __attribute__ ((__packed__)); struct boot_device_tag { @@ -79,52 +76,68 @@ bool have_boot_device = false; bool have_mmap = false; enum error_codes { - NO_BOOT_DEVICE = 000000000000, - NO_MMAP = 000000000001, - INSUFF_MEMORY = 000000000002 + NO_BOOT_DEVICE = 0x00000000, + NO_MMAP = 0x00000001, + INSUFF_MEMORY = 0x00000002 }; -uint32_t main(void) { - for (uint32_t *i = (uint32_t *)VGA_BUFFER; i < (uint32_t *)0x000b8fa0; ++i) - *i = 0x70207020; - - put_sz("Starting...\n"); - - uint32_t info_size = *(uint32_t *)info_pointer; - struct tag_start *tag_pointer = (struct tag_start *)(info_pointer + 2); +struct tag_start *tag_pointer; +uint32_t main(void) { + clear(); + + /* + uint32_t *debug_ptr = (uint32_t *)tag_pointer - 2; + uint32_t debug_size = *debug_ptr / 4; + for (uint32_t i = 0; i < debug_size; ++i) { + put_32_hex(debug_ptr[i]); + put_char(' '); + } + */ + + put_sz("Multiboot info:\n"); while (tag_pointer->type) { + put_sz(" Tag type 0x"); + put_32_hex(tag_pointer->type); + put_sz(" with size 0x"); + put_32_hex(tag_pointer->size); switch (tag_pointer->type) { case BOOT_DEVICE: - boot_device = *(struct boot_device_tag *)&tag_pointer->rest; + boot_device = *(struct boot_device_tag *)(tag_pointer + 1); have_boot_device = true; - put_sz("Boot device: 0x"); + put_sz(": boot device\n BIOS code: "); put_32_hex(boot_device.bios_device); if (boot_device.partition != 0xffffffff) { - put_sz(", 0x"); + put_sz("\n Partition number: "); put_32_hex(boot_device.partition); if (boot_device.subpartition != 0xffffffff) { - put_sz(", 0x"); + put_sz("\n Subpartition number: "); put_32_hex(boot_device.subpartition); + put_char('\n'); } + else + put_sz("\n No subpartition\n"); } - put_char('\n'); + else + put_sz("\n No partition\n"); break; case MEMORY_MAP: { - struct mmap_tag_entry *tag = (struct mmap_tag_entry *)((uint32_t)&tag_pointer->rest + 8); - uint32_t size = *(uint32_t *)&tag_pointer->rest; + uint32_t size = *(uint32_t *)(tag_pointer + 1); + struct mmap_tag_entry *tag = (struct mmap_tag_entry *)(tag_pointer + 2); + struct mmap_tag_entry *end = (struct mmap_tag_entry *)((uint32_t)tag_pointer + tag_pointer->size); struct mmap_entry *entry = (struct mmap_entry *)tag; struct mmap_entry **last_next = &mmap_start; uint32_t usable = 0; - while (tag) { + put_sz(": memory map\n Regions:\n"); + while (tag != end) { if (!(tag->base & 0xffffffff00000000)) { entry->base = (uint32_t)tag->base; entry->length = (tag->base + tag->length - 1) & 0xffffffff00000000 ? 1 + ~(uint32_t)tag->base : (uint32_t)tag->length; - put_sz("Memory: 0x"); + put_sz(" 0x"); put_32_hex(entry->base); put_sz(" - 0x"); put_32_hex(entry->base + entry->length - 1); @@ -147,7 +160,9 @@ uint32_t main(void) { entry->whose = HARDWARE; break; default: - put_sz(": unrecognized type, assuming hardware use\n"); + put_sz(": hardware use (0x"); + put_32_hex(tag->type); + put_sz(")\n"); entry->whose = HARDWARE; break; } @@ -158,13 +173,13 @@ uint32_t main(void) { tag = (struct mmap_tag_entry *)((uint32_t)tag + size); } - put_sz("Total usable memory: 0x"); + put_sz(" Total usable memory: "); put_32_hex(usable); put_char('\n'); - bool clean; + bool dirty; do { - clean = true; + dirty = false; for (struct mmap_entry *current = mmap_start; current; current = current->next) for (struct mmap_entry *against = mmap_start; against; against = against->next) if ((current->base + current->length == against->base) && @@ -177,27 +192,29 @@ uint32_t main(void) { ; current->next = against->next; } - clean = false; + dirty = true; } - } while (clean); + } while (dirty); have_mmap = true; break; } default: - put_sz("Ignoring multiboot tag 0x"); - put_32_hex(tag_pointer->type); - put_char('\n'); + put_sz(": ignoring\n"); } - tag_pointer = (struct tag_start *)((uint32_t)tag_pointer + tag_pointer->size); - }; + tag_pointer = (struct tag_start *)(((uint32_t)tag_pointer + tag_pointer->size - 1 & 0xfffffff8) + 8); + } if (!have_boot_device) return NO_BOOT_DEVICE; if (!have_mmap) return NO_MMAP; + put_sz("Halting."); + while (1) + ; + if (!((proc_table = allocate_block(sizeof(struct proc_info) * 65536, KERNEL)) && (file_table = allocate_block(sizeof(struct file_info) * 65536, KERNEL)))) return INSUFF_MEMORY; @@ -206,3 +223,11 @@ uint32_t main(void) { while (1) put_sz("|\b/\b-\b\\\b"); } + +void wrapped_main(void) { + uint32_t error = main(); + set_color(0x47); + clear(); + put_sz("Error: 0x"); + put_32_hex(error); +} diff --git a/src/kernel/serial.asm b/src/kernel/serial.asm new file mode 100644 index 0000000..9ebf84c --- /dev/null +++ b/src/kernel/serial.asm @@ -0,0 +1,29 @@ +;Copyright 2019 Benji Dial + +;Permission to use, copy, modify, and/or distribute this +;software for any purpose with or without fee is hereby +;granted, provided that the above copyright notice and this +;permission notice appear in all copies. + +;THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS +;ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL +;IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO +;EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +;INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +;RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +;ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +;ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +;OF THIS SOFTWARE. + +global send_byte +global read_byte + +section .text +;COM1: COM2: COM3: COM4: +;0x03f8, 0x02f8, 0x03e8, 0x02e8 + +send_byte:;void send_byte(uint8_t value, uint8_t port) + ;TODO + +read_byte:;uint8_t read_byte(uint8_t port) + ;TODO
\ No newline at end of file diff --git a/src/kernel/serial.h b/src/kernel/serial.h new file mode 100644 index 0000000..d5e4038 --- /dev/null +++ b/src/kernel/serial.h @@ -0,0 +1,38 @@ +/* +Copyright 2019 Benji Dial + +Permission to use, copy, modify, and/or distribute this +software for any purpose with or without fee is hereby +granted, provided that the above copyright notice and this +permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS +ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO +EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +OF THIS SOFTWARE. +*/ + +#include <stdint.h> + +#ifndef SERIAL_H +#define SERIAL_H + +enum serials { + COM1 = 0, + COM2 = 1, + COM3 = 2, + COM4 = 3 +}; + +/* +Commenting out so I don't accidentally call garbage while these are unimplemented. +void send_byte(uint8_t value, uint8_t port); +uint8_t read_byte(uint8_t port); +*/ + +#endif
\ No newline at end of file diff --git a/src/kernel/stub.asm b/src/kernel/stub.asm index 84e4523..bad26aa 100644 --- a/src/kernel/stub.asm +++ b/src/kernel/stub.asm @@ -15,7 +15,9 @@ ;ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE ;OF THIS SOFTWARE. -extern main +global _start +extern wrapped_main +extern tag_pointer section .mb_header dd 0xe852_50d6;magic @@ -34,37 +36,12 @@ mb_end: section .text bits 32 -global _start _start: - mov dword [info_pointer], ebx + add ebx, 8 + mov dword [tag_pointer], ebx mov esp, stack - call main - mov edx, eax - - mov eax, 0x4720_4720 - mov ebx, 0x000b_8000 - mov ecx, 0x000b_8fa0 -clear_screen_loop: - mov dword [ebx], eax - add ebx, 4 - test ebx, ecx - jne clear_screen_loop - - mov dword [0x000b_8000], 0x4772_4745 - mov dword [0x000b_8004], 0x476f_4772 - mov dword [0x000b_8008], 0x4720_4772 - mov ebx, 0x000b_8020 - mov ecx, 0x000b_800a -error_number_loop: - mov al, dl - and al, 0x07 - or al, 0x30 - mov byte [ebx], al - sub ebx, 2 - shr edx, 3 - test ebx, ecx - jne error_number_loop + call wrapped_main cli halt: @@ -72,7 +49,6 @@ halt: jmp halt section .bss -global info_pointer info_pointer resd 1 resb 0x1000 - $ + $$ stack:
\ No newline at end of file diff --git a/src/kernel/vga.c b/src/kernel/vga.c index 96a691f..3d8de43 100644 --- a/src/kernel/vga.c +++ b/src/kernel/vga.c @@ -18,6 +18,7 @@ OF THIS SOFTWARE. */ #include "vga.h" +#include "serial.h" #include <stdbool.h> uint16_t cursor_pos = 0; @@ -25,18 +26,24 @@ uint8_t color = 0x70; #define cols 80 #define rows 25 +void clear(void) { + uint32_t fill = 0x00200020 | (color << 24) | (color << 8); + for (uint32_t *i = (uint32_t *)VGA_BUFFER; i < (uint32_t *)(VGA_BUFFER + rows * cols * 2); ++i) + *i = fill; + cursor_pos = 0; +} + void scroll(void) { cursor_pos -= cols * 2; - uint32_t *limit = (uint32_t *)(VGA_BUFFER + cols * (rows - 1)); - for (uint32_t *i = (uint32_t *)VGA_BUFFER; i < limit; ++i) + for (uint32_t *i = (uint32_t *)VGA_BUFFER; i < (uint32_t *)(VGA_BUFFER + (rows - 1) * cols * 2); ++i) *i = *(i + cols / 2); - limit += cols / 2; - uint32_t fill = (color * 0x0100 + (uint8_t)' ') * 0x00010001; - for (uint32_t *i = limit - cols / 2; i < limit; ++i) + uint32_t fill = (color << 8) | (color << 24) | 0x00200020; + for (uint32_t *i = (uint32_t *)(VGA_BUFFER + (rows - 1) * cols * 2); i < (uint32_t *)(VGA_BUFFER + rows * cols * 2); ++i) *i = fill; } void put_char(uint8_t ch) { + //send_byte(ch, COM2); switch (ch) { case '\b': if (cursor_pos) @@ -89,12 +96,12 @@ void put_16(uint16_t n) { void put_32_hex(uint32_t n) { for (uint8_t i = 0; i < 4; ++i) { - put_char(n / 0xf0000000 + (n < 0xa0000000 ? (uint8_t)'0' : (uint8_t)'a' - 1)); + put_char("0123456789abcdef"[n >> 28]); n <<= 4; } - put_char('_'); + put_char('.'); for (uint8_t i = 0; i < 4; ++i) { - put_char(n / 0xf0000000 + (n < 0xa0000000 ? (uint8_t)'0' : (uint8_t)'a' - 1)); + put_char("0123456789abcdef"[n >> 28]); n <<= 4; } } diff --git a/src/kernel/vga.h b/src/kernel/vga.h index 2214f27..5658437 100644 --- a/src/kernel/vga.h +++ b/src/kernel/vga.h @@ -22,7 +22,13 @@ OF THIS SOFTWARE. #ifndef VGA_H #define VGA_H +#define put_debug(name, value) \ + put_sz(name ": 0x"); \ + put_32_hex(value); \ + put_char('\n'); + #define VGA_BUFFER ((uint8_t *)0x000b8000) +void clear(void); void put_char(uint8_t ch); void put_sz(uint8_t *s); void put_16(uint16_t n); |