summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMarvin Borner2021-07-10 18:36:50 +0200
committerMarvin Borner2021-07-10 18:36:50 +0200
commit4f1ae4fa4250369919a975f5568425f6791b2489 (patch)
treeaec903e642561edbf6a6cccf513abccff882426f
parentad56eb28f0614db4b7656ade390f1c79b446cbc9 (diff)
Fixed interrupts and added keyboard handler
-rw-r--r--src/loader/dev.c1
-rw-r--r--src/loader/ent.asm4
-rw-r--r--src/loader/gdt.c96
-rw-r--r--src/loader/impl/mb1.c37
-rw-r--r--src/loader/impl/mb2.c17
-rw-r--r--src/loader/inc/dev.h1
-rw-r--r--src/loader/inc/impl.h2
-rw-r--r--src/loader/inc/int.h2
-rw-r--r--src/loader/inc/log.h3
-rw-r--r--src/loader/int.asm4
-rw-r--r--src/loader/int.c12
-rw-r--r--src/loader/log.c7
-rw-r--r--src/loader/main.c1
-rw-r--r--src/loader/sel.c46
14 files changed, 144 insertions, 89 deletions
diff --git a/src/loader/dev.c b/src/loader/dev.c
index 3cdef10..2a57b02 100644
--- a/src/loader/dev.c
+++ b/src/loader/dev.c
@@ -14,6 +14,7 @@ static const char *dev_resolve_type(enum dev_type type)
return "Disk";
case DEV_FB:
return "Framebuffer";
+ case DEV_NONE:
default:
return "Unknown";
}
diff --git a/src/loader/ent.asm b/src/loader/ent.asm
index 47cf49b..c518aad 100644
--- a/src/loader/ent.asm
+++ b/src/loader/ent.asm
@@ -18,7 +18,8 @@ _start:
sub ecx, bss_begin
rep stosb
- lgdt [gdt]
+ lgdt [gdt] ; Load GDT
+
jmp 0x18:.reload_cs
.reload_cs:
@@ -29,5 +30,4 @@ _start:
mov gs, ax
mov ss, ax
- cli
jmp start
diff --git a/src/loader/gdt.c b/src/loader/gdt.c
index 853b793..ea91c33 100644
--- a/src/loader/gdt.c
+++ b/src/loader/gdt.c
@@ -2,48 +2,54 @@
#include <gdt.h>
-static struct gdt_desc gdt_descs[] = { { 0 },
-
- { .limit = 0xffff,
- .base_low = 0x0000,
- .base_mid = 0x00,
- .access = 0x9a,
- .granularity = 0x00,
- .base_hi = 0x00 },
-
- { .limit = 0xffff,
- .base_low = 0x0000,
- .base_mid = 0x00,
- .access = 0x92,
- .granularity = 0x00,
- .base_hi = 0x00 },
-
- { .limit = 0xffff,
- .base_low = 0x0000,
- .base_mid = 0x00,
- .access = 0x9a,
- .granularity = 0xcf,
- .base_hi = 0x00 },
-
- { .limit = 0xffff,
- .base_low = 0x0000,
- .base_mid = 0x00,
- .access = 0x92,
- .granularity = 0xcf,
- .base_hi = 0x00 },
-
- { .limit = 0x0000,
- .base_low = 0x0000,
- .base_mid = 0x00,
- .access = 0x9a,
- .granularity = 0x20,
- .base_hi = 0x00 },
-
- { .limit = 0x0000,
- .base_low = 0x0000,
- .base_mid = 0x00,
- .access = 0x92,
- .granularity = 0x00,
- .base_hi = 0x00 } };
-
-REAL struct gdtr gdt = { sizeof(gdt_descs) - 1, (u32)gdt_descs, 0 };
+static struct gdt_desc gdt_descs[] = {
+ { 0 },
+
+ { .limit = 0xffff,
+ .base_low = 0x0000,
+ .base_mid = 0x00,
+ .access = 0x9a,
+ .granularity = 0x00,
+ .base_hi = 0x00 },
+
+ { .limit = 0xffff,
+ .base_low = 0x0000,
+ .base_mid = 0x00,
+ .access = 0x92,
+ .granularity = 0x00,
+ .base_hi = 0x00 },
+
+ { .limit = 0xffff,
+ .base_low = 0x0000,
+ .base_mid = 0x00,
+ .access = 0x9a,
+ .granularity = 0xcf,
+ .base_hi = 0x00 },
+
+ { .limit = 0xffff,
+ .base_low = 0x0000,
+ .base_mid = 0x00,
+ .access = 0x92,
+ .granularity = 0xcf,
+ .base_hi = 0x00 },
+
+ { .limit = 0x0000,
+ .base_low = 0x0000,
+ .base_mid = 0x00,
+ .access = 0x9a,
+ .granularity = 0x20,
+ .base_hi = 0x00 },
+
+ { .limit = 0x0000,
+ .base_low = 0x0000,
+ .base_mid = 0x00,
+ .access = 0x92,
+ .granularity = 0x00,
+ .base_hi = 0x00 },
+};
+
+REAL struct gdtr gdt = {
+ sizeof(gdt_descs) - 1,
+ (u32)gdt_descs,
+ 0,
+};
diff --git a/src/loader/impl/mb1.c b/src/loader/impl/mb1.c
index e713dd7..c02aa50 100644
--- a/src/loader/impl/mb1.c
+++ b/src/loader/impl/mb1.c
@@ -10,15 +10,20 @@
// The address where data gets stored
#define MB1_LOAD_ADDRESS 0x10000
+#define MB1_FLAG_PAGE_ALIGN (1 << 0) // Align modules with page boundaries (4K)
+#define MB1_FLAG_MEMORY_INFO (1 << 1) // Load/store all mem_* fields and mmap_* structs
+#define MB1_FLAG_VIDEO_MODE (1 << 2) // Load/store video mode table
+#define MB1_FLAG_MANUAL_ADDRESSES (1 << 16) // Use specified load addresses
+
struct mb1_entry {
u32 magic;
u32 flags;
u32 checksum; // Everything after that is optional
- u32 header_addr;
- u32 load_addr;
- u32 load_end_addr;
- u32 bss_end_addr;
- u32 entry_addr;
+ u32 header_addr; // Unsupported
+ u32 load_addr; // Unsupported
+ u32 load_end_addr; // Unsupported
+ u32 bss_end_addr; // Unsupported
+ u32 entry_addr; // Unsupported
u32 mode_type;
u32 width;
u32 height;
@@ -40,8 +45,9 @@ static u32 mb1_store(void *data, u32 size)
return MB1_LOAD_ADDRESS + (offset - size);
}
-static void mb1_store_mmap(struct mb1_info *info)
+static void mb1_store_memory_info(struct mb1_info *info)
{
+ // TODO: Store mem_lower and mem_upper
struct mem_map *mem_map = mem_map_get();
info->flags |= MB1_INFO_MEM_MAP;
info->mmap_length = mem_map->count * sizeof(struct mb1_mmap_entry);
@@ -59,8 +65,6 @@ static void mb1_store_mmap(struct mb1_info *info)
// Load the mb1 structs into memory
static void mb1_load(struct mb1_entry *entry)
{
- (void)entry;
-
struct mb1_info info_struct = { 0 };
struct mb1_info *info = (void *)mb1_store(&info_struct, sizeof(info_struct));
@@ -73,9 +77,9 @@ static void mb1_load(struct mb1_entry *entry)
char loader_name[] = "SegelBoot";
info->boot_loader_name = mb1_store(loader_name, sizeof(loader_name));
- // Set memory map
- /* if (entry->flags & 2) TODO */
- mb1_store_mmap(info);
+ // Store memory info
+ if (entry->flags & MB1_FLAG_MEMORY_INFO)
+ mb1_store_memory_info(info);
}
// Jump to kernel with correct info pointer in eax
@@ -120,18 +124,21 @@ u8 mb1_detect(struct cfg_entry *cfg)
return 0;
cfg->impl.type = IMPL_MB1;
- cfg->impl.start = entry;
+ cfg->impl.offset = (u32)entry - (u32)header;
return 1;
}
-#include <pic.h>
-
// Execute mb1 type kernel
void mb1_exec(struct cfg_entry *cfg)
{
+ struct mb1_entry mb1_entry = { 0 };
+ s32 ret = cfg->dev->p.disk.fs.read(cfg->path, &mb1_entry, cfg->impl.offset,
+ sizeof(mb1_entry), cfg->dev);
+ assert(ret == sizeof(mb1_entry));
+ mb1_load(&mb1_entry);
+
u32 entry = elf_load(cfg->dev, cfg->path);
- mb1_load(cfg->impl.start);
// This is a kind of hacky parameter stack pushing thing, just disable warning :)
#pragma GCC diagnostic ignored "-Wpedantic"
diff --git a/src/loader/impl/mb2.c b/src/loader/impl/mb2.c
index f46310b..09f69ea 100644
--- a/src/loader/impl/mb2.c
+++ b/src/loader/impl/mb2.c
@@ -9,7 +9,7 @@
// The address where data gets stored
#define MB2_LOAD_ADDRESS 0x10000
-struct multiboot_entry {
+struct mb2_entry {
u32 magic;
u32 flags;
u32 header_length;
@@ -18,7 +18,7 @@ struct multiboot_entry {
};
// The (really simple) multiboot checksum algorithm
-/* static u32 mb2_checksum(struct multiboot_entry *entry) */
+/* static u32 mb2_checksum(struct mb2_entry *entry) */
/* { */
/* return -(entry->magic + entry->flags); */
/* } */
@@ -33,7 +33,7 @@ static u32 mb2_store(void *data, u32 size)
}
// Load the mb2 structs into memory
-static void mb2_load(struct multiboot_entry *entry)
+static void mb2_load(struct mb2_entry *entry)
{
(void)mb2_store;
(void)entry;
@@ -64,7 +64,7 @@ u8 mb2_detect(struct cfg_entry *cfg)
return 0;
// Find start of multiboot entry by searching for magic
- struct multiboot_entry *entry = 0;
+ struct mb2_entry *entry = 0;
for (u32 i = 0; i < sizeof(header); i++) {
u32 *p = (u32 *)&header[i];
if (*p == MB2_MAGIC) {
@@ -82,7 +82,7 @@ u8 mb2_detect(struct cfg_entry *cfg)
/* return 0; */
cfg->impl.type = IMPL_MB2;
- cfg->impl.start = entry;
+ cfg->impl.offset = (u32)entry - (u32)header;
return 1;
}
@@ -90,8 +90,13 @@ u8 mb2_detect(struct cfg_entry *cfg)
// Execute mb2 type kernel
void mb2_exec(struct cfg_entry *cfg)
{
+ struct mb2_entry mb2_entry = { 0 };
+ s32 ret = cfg->dev->p.disk.fs.read(cfg->path, &mb2_entry, cfg->impl.offset,
+ sizeof(mb2_entry), cfg->dev);
+ assert(ret == sizeof(mb2_entry));
+ mb2_load(&mb2_entry);
+
u32 entry = elf_load(cfg->dev, cfg->path);
- mb2_load(cfg->impl.start);
// This is a kind of hacky parameter stack pushing thing, just disable warning :)
#pragma GCC diagnostic ignored "-Wpedantic"
diff --git a/src/loader/inc/dev.h b/src/loader/inc/dev.h
index 7120a83..cbefe99 100644
--- a/src/loader/inc/dev.h
+++ b/src/loader/inc/dev.h
@@ -7,6 +7,7 @@
#include <dsk.h>
enum dev_type {
+ DEV_NONE,
DEV_DISK,
DEV_FB,
};
diff --git a/src/loader/inc/impl.h b/src/loader/inc/impl.h
index c7b1261..58ae706 100644
--- a/src/loader/inc/impl.h
+++ b/src/loader/inc/impl.h
@@ -13,7 +13,7 @@ enum impl_type {
struct impl {
enum impl_type type;
- void *start; // Of header/entry
+ u32 offset; // Of header/entry
void (*load)(struct dev *, const char *);
};
diff --git a/src/loader/inc/int.h b/src/loader/inc/int.h
index 8336cd8..ccd9ea8 100644
--- a/src/loader/inc/int.h
+++ b/src/loader/inc/int.h
@@ -43,8 +43,6 @@ struct idt_ptr {
void *base;
} PACKED;
-extern struct idt_ptr idt;
-
void idt_install(void);
void int_event_handler_add(u32 int_no, void (*handler)(void));
diff --git a/src/loader/inc/log.h b/src/loader/inc/log.h
index c40ce50..cb1acd8 100644
--- a/src/loader/inc/log.h
+++ b/src/loader/inc/log.h
@@ -3,9 +3,12 @@
#ifndef LOG_H
#define LOG_H
+#include <def.h>
+
void serial_install(void);
void serial_print(const char *data);
+void vga_put_at(char ch, u8 x, u8 y, u8 color);
void vga_clear(void);
void log(const char *format, ...);
diff --git a/src/loader/int.asm b/src/loader/int.asm
index f6e66ae..4805448 100644
--- a/src/loader/int.asm
+++ b/src/loader/int.asm
@@ -1,7 +1,5 @@
; MIT License, Copyright (c) 2021 Marvin Borner
-bits 32
-
%macro INT_REGISTER 1
dd int%1
%endmacro
@@ -29,7 +27,7 @@ int_common:
push fs
push gs
- mov ax, 0x10
+ mov ax, 0x20
mov ds, ax
mov es, ax
mov fs, ax
diff --git a/src/loader/int.c b/src/loader/int.c
index 8fc0ae3..d4e4841 100644
--- a/src/loader/int.c
+++ b/src/loader/int.c
@@ -11,21 +11,21 @@
extern u32 int_table[];
static struct idt_entry idt_entries[256] = { 0 };
-REAL struct idt_ptr idt = { .size = sizeof(idt_entries) - 1, .base = &idt_entries };
+REAL static struct idt_ptr idt = { .size = sizeof(idt_entries) - 1, .base = idt_entries };
void idt_install(void)
{
for (u8 i = 0; i < 3; i++)
- idt_entries[i] = IDT_ENTRY(int_table[i], 0x08, INT_GATE);
+ idt_entries[i] = IDT_ENTRY(int_table[i], 0x18, INT_GATE);
- idt_entries[3] = IDT_ENTRY(int_table[3], 0x08, INT_TRAP);
- idt_entries[4] = IDT_ENTRY(int_table[4], 0x08, INT_TRAP);
+ idt_entries[3] = IDT_ENTRY(int_table[3], 0x18, INT_TRAP);
+ idt_entries[4] = IDT_ENTRY(int_table[4], 0x18, INT_TRAP);
for (u8 i = 5; i < 48; i++)
- idt_entries[i] = IDT_ENTRY(int_table[i], 0x08, INT_GATE);
+ idt_entries[i] = IDT_ENTRY(int_table[i], 0x18, INT_GATE);
// Load table
- __asm__ volatile("lidt %0" : : "m"(idt));
+ __asm__ volatile("lidt %0" : : "m"(idt) : "memory");
}
/**
diff --git a/src/loader/log.c b/src/loader/log.c
index ff4feff..3a4167f 100644
--- a/src/loader/log.c
+++ b/src/loader/log.c
@@ -120,6 +120,13 @@ void vga_clear(void)
out[i] = 0;
}
+void vga_put_at(char ch, u8 x, u8 y, u8 color)
+{
+ u8 *out = (u8 *)(VGA_ADDRESS + 2 * (x + y * VGA_WIDTH));
+ *out++ = ch;
+ *out++ = color;
+}
+
static void vga_put(char ch)
{
static u8 x = 0;
diff --git a/src/loader/main.c b/src/loader/main.c
index 54f35be..97fc8ef 100644
--- a/src/loader/main.c
+++ b/src/loader/main.c
@@ -40,6 +40,7 @@ int start(u8 disk)
sel_draw();
// Sleep and wait for interrupts
+ __asm__ volatile("sti");
while (1)
__asm__ volatile("hlt");
diff --git a/src/loader/sel.c b/src/loader/sel.c
index acdc783..9052712 100644
--- a/src/loader/sel.c
+++ b/src/loader/sel.c
@@ -2,7 +2,9 @@
// Selection interface
#include <cfg.h>
+#include <cpu.h>
#include <def.h>
+#include <int.h>
#include <log.h>
#include <pnc.h>
#include <sel.h>
@@ -22,29 +24,55 @@ static u8 sel_entry_add(struct cfg_entry *entry)
return 0;
}
-// TODO: Keyboard listener
+static u8 sel_entry_exists(u8 entry)
+{
+ return !!sel_entries[entry].cfg;
+}
+
static void sel_entry_select(u8 entry)
{
- cfg_exec(sel_entries[entry].cfg);
+ if (sel_entry_exists(entry))
+ cfg_exec(sel_entries[entry].cfg);
+ else
+ log("Invalid selection\n");
}
static void sel_entries_draw(void)
{
- for (u8 i = 0; i < COUNT(sel_entries); i++) {
- if (!sel_entries[i].cfg)
- break;
-
+ for (u8 i = 0; sel_entry_exists(i); i++)
vga_log("> '%s' (%s)\n", sel_entries[i].cfg->name, sel_entries[i].cfg->path);
- }
+}
+
+// Using PS2 magic
+static void sel_keyboard_handler(void)
+{
+ static u8 row = 0;
+
+ while (!(inb(0x64) & 1)) // Wait for data (bit 0 gets set)
+ ;
+ u8 data = inb(0x60);
+
+ // Reset previous selection
+ vga_put_at('>', 0, row + 2, 0x07);
+
+ if (data == 0x24 && sel_entry_exists(row + 1)) // j/down key
+ row++;
+ else if (data == 0x25 && row > 0) // k/up key
+ row--;
+ else if (data == (0x1c | 0x80)) // enter key release (| 0x80)
+ sel_entry_select(row);
+
+ // Draw selection
+ vga_put_at('#', 0, row + 2, 0x03);
}
void sel_draw(void)
{
vga_clear();
+ vga_log("SegelBoot by Marvin Borner\n\n");
cfg_foreach(&sel_entry_add);
sel_entries_draw();
- // Just for testing
- sel_entry_select(0);
+ int_event_handler_add(1, &sel_keyboard_handler);
}