summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--makefile15
-rw-r--r--src/kernel/main.c93
-rw-r--r--src/kernel/serial.asm29
-rw-r--r--src/kernel/serial.h38
-rw-r--r--src/kernel/stub.asm36
-rw-r--r--src/kernel/vga.c23
-rw-r--r--src/kernel/vga.h6
7 files changed, 161 insertions, 79 deletions
diff --git a/makefile b/makefile
index b330fc3..8ff2c69 100644
--- a/makefile
+++ b/makefile
@@ -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);