summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorthe lemons <citrons@mondecitronne.com>2021-04-10 01:59:09 -0500
committerthe lemons <citrons@mondecitronne.com>2021-04-10 01:59:09 -0500
commitbaa4b6cf54364d0333ece9539d9cd8cd66b23a39 (patch)
tree4b108a372ac6fd52c5292886088ddc4891933d9b
parent6626a1ecee2759d6fb71e72cc95b22bd6af22875 (diff)
refactor interrupt handling (and do other things)
-rwxr-xr-xkernel.binbin89932 -> 95156 bytes
-rw-r--r--linker.ld4
-rw-r--r--os.isobin19892224 -> 19898368 bytes
-rw-r--r--src/interrupt.c68
-rw-r--r--src/interrupt.h16
-rw-r--r--src/interrupt_stub.s48
-rw-r--r--src/irq_handlers.c26
-rw-r--r--src/main.c20
-rw-r--r--src/memory.c60
-rw-r--r--src/memory.h44
-rw-r--r--src/misc.h6
11 files changed, 217 insertions, 75 deletions
diff --git a/kernel.bin b/kernel.bin
index 8c58cab..cd32d5b 100755
--- a/kernel.bin
+++ b/kernel.bin
Binary files differ
diff --git a/linker.ld b/linker.ld
index cd22338..22a3ab1 100644
--- a/linker.ld
+++ b/linker.ld
@@ -6,6 +6,8 @@ SECTIONS
/* Begin at 1 MiB */
. = 1M;
+ __kernel_start = .;
+
/* Multiboot header */
.text BLOCK(4K) : ALIGN(4K)
{
@@ -23,4 +25,6 @@ SECTIONS
*(COMMON)
*(.bss)
}
+
+ __kernel_end = .;
}
diff --git a/os.iso b/os.iso
index 190667f..74e73b0 100644
--- a/os.iso
+++ b/os.iso
Binary files differ
diff --git a/src/interrupt.c b/src/interrupt.c
index c417117..98ac2fb 100644
--- a/src/interrupt.c
+++ b/src/interrupt.c
@@ -1,43 +1,33 @@
#include "interrupt.h"
#include "string.h"
-#include "vga.h"
-#include "bees.h"
-#include "printf.h"
-#include "keyboard.h"
struct port pic_master_command = {0x20, port8bit_slow};
struct port pic_master_data = {0x21, port8bit_slow};
struct port pic_slave_command = {0xA0, port8bit_slow};
struct port pic_slave_data = {0xA1, port8bit_slow};
-struct port ps2_port = {0x60, port8bit};
-
struct gate_desc idt[256] = {0};
-#define PIC_EOI 0x20
-
void irq_end(uint8_t int_number) {
if (int_number >= 0x28)
port_write(pic_slave_command, PIC_EOI);
port_write(pic_master_command, PIC_EOI);
}
-uint8_t ps2_read() {
- return port_read(ps2_port);
-}
-uint32_t handle_int(uint8_t int_number, uint32_t idk, uint32_t esp) {
- switch (int_number) {
- case 0x0D:
- // bye
- bees("general protection fault");
- break;
- case 0x21:
- keyboard_event(&ps2_read);
- irq_end(int_number);
- break;
- }
+uint32_t handle_int(irqh_t *int_handler, uint8_t int_number, uint32_t esp) {
+
+ port_write(pic_master_data, 0xFF); // mask all IRQs
+ start_interrupts(); // reenable interrupts
+
+ if (int_handler != NULL) (*int_handler)();
+ irq_end(int_number);
+
+ // call event loop here
+
+ clear_interrupts();
+ port_write(pic_master_data, INT_MASK); // restore normal interrupt mask
return esp;
}
@@ -61,16 +51,30 @@ void interrupt_init() {
for (uint16_t i = 0; i < 256; i++)
set_int_desc_entry(i, code_seg, &int_ignore, 0, IDT_INTERRUPT_GATE);
- // Put the interrupt handlers in the IDT
- set_int_desc_entry(0x20, code_seg, &handle_irq0x00, 0, IDT_INTERRUPT_GATE);
- set_int_desc_entry(0x21, code_seg, &handle_irq0x01, 0, IDT_INTERRUPT_GATE);
- set_int_desc_entry(0x0D, code_seg, &handle_irq0x0D, 0, IDT_INTERRUPT_GATE);
+#define IRQH(IRQ) \
+ set_int_desc_entry( \
+ IRQ + 0x20, code_seg, &handle_irq ## IRQ, 0, IDT_INTERRUPT_GATE)
+
+#define EXCH(IRQ) \
+ set_int_desc_entry( \
+ IRQ, code_seg, &handle_exception ## IRQ, 0, IDT_INTERRUPT_GATE)
+
+ IRQH(0x00);
+ IRQH(0x01);
+
+ EXCH(0x00);
+ EXCH(0x01);
+ EXCH(0x02);
+ EXCH(0x03);
+ EXCH(0x06);
+ EXCH(0x07);
+ EXCH(0x08);
+ EXCH(0x0D);
port_write(pic_master_command, 0x11);
port_write(pic_slave_command, 0x11);
- // (I actually don't understand how this works)
- // Remap the PIC
+ // remap the PIC
port_write(pic_master_data, 0x20); // Interrupt vector offsets
port_write(pic_slave_data, 0x28);
@@ -80,7 +84,7 @@ void interrupt_init() {
port_write(pic_master_data, 0x01);
port_write(pic_slave_data, 0x01);
- port_write(pic_master_data, 0xFD);
+ port_write(pic_master_data, INT_MASK);
port_write(pic_slave_data, 0xFF);
// Load the IDT
@@ -92,5 +96,9 @@ void interrupt_init() {
}
void start_interrupts() {
- asm("sti");
+ asm volatile("sti");
+}
+
+void clear_interrupts() {
+ asm volatile("cli");
}
diff --git a/src/interrupt.h b/src/interrupt.h
index 5e0112b..b308a0c 100644
--- a/src/interrupt.h
+++ b/src/interrupt.h
@@ -31,10 +31,18 @@ void set_int_desc_entry(uint8_t int_number, uint16_t gdt_code_seg,
void interrupt_init();
void start_interrupts();
+void clear_interrupts();
void handle_irq0x00();
void handle_irq0x01();
-void handle_irq0x0D();
+void handle_exception0x00();
+void handle_exception0x01();
+void handle_exception0x02();
+void handle_exception0x03();
+void handle_exception0x06();
+void handle_exception0x07();
+void handle_exception0x08();
+void handle_exception0x0D();
void int_ignore();
@@ -43,4 +51,10 @@ struct port pic_master_data;
struct port pic_slave_command;
struct port pic_slave_data;
+typedef void irqh_t();
+
+#define INT_MASK 0x00
+
+#define PIC_EOI 0x20
+
#endif
diff --git a/src/interrupt_stub.s b/src/interrupt_stub.s
index 3d2ba53..3838048 100644
--- a/src/interrupt_stub.s
+++ b/src/interrupt_stub.s
@@ -8,9 +8,10 @@
.macro handle_exception num
-.global handle_irq\num
-handle_irq\num:
+.global handle_exception\num
+handle_exception\num:
movb $\num, (int_number)
+ movl $exch_\num, (int_handler)
jmp int_bottom
.endm
@@ -18,40 +19,45 @@ handle_irq\num:
.global handle_irq\num
handle_irq\num:
movb $\num + IRQ_BASE, (int_number)
+ movl $irqh_\num, (int_handler)
jmp int_bottom
.endm
handle_irq 0x00
handle_irq 0x01
+handle_exception 0x00
+handle_exception 0x01
+handle_exception 0x02
+handle_exception 0x03
+handle_exception 0x06
+handle_exception 0x07
+handle_exception 0x08
handle_exception 0x0D
+int_ignore:
+
+ movb $0xFF, (int_number)
+ movl $0x00, (int_handler)
+
int_bottom:
- pop %eax
- push int_bottom
- pusha
- pushl %ds
- pushl %es
- pushl %fs
- pushl %gs
-
+
+ cli
+
pushl %esp
- pushl %eax
push (int_number)
+ pushl (int_handler)
call handle_int
movl %eax, %esp // Set the stack pointer to the return value of handle_int
- popl %gs
- popl %fs
- popl %es
- popl %ds
- popa
-
- iret
-
-int_ignore:
pop %eax
+ pop %eax
+ pop %eax
+ pop %eax
+
+ sti
- iret
+ hlt
.data
int_number: .byte 0
+ int_handler: .int 0
diff --git a/src/irq_handlers.c b/src/irq_handlers.c
new file mode 100644
index 0000000..19db144
--- /dev/null
+++ b/src/irq_handlers.c
@@ -0,0 +1,26 @@
+
+#include "interrupt.h"
+#include "port.h"
+#include "bees.h"
+#include "keyboard.h"
+#include <stdint.h>
+
+uint8_t ps2_read() {
+ const struct port ps2_port = {0x60, port8bit};
+ return port_read(ps2_port);
+}
+
+#define IRQH(I) void irqh_ ## I ()
+#define EXCH(I) void exch_ ## I ()
+
+IRQH(0x00) {return;}
+IRQH(0x01) {keyboard_event(&ps2_read);}
+
+EXCH(0x00) {bees("division by zero (this is weird!)");}
+EXCH(0x01) {bees("values of beta may give rise to dom!");}
+EXCH(0x02) {bees("lp0 on fire");}
+EXCH(0x03) {bees("values of beta may give rise to dom!");}
+EXCH(0x06) {bees("invalid opcode (bad!)");}
+EXCH(0x07) {bees("values of beta may give rise to dom!");}
+EXCH(0x08) {bees("double fault");}
+EXCH(0x0D) {bees("general protection fault");}
diff --git a/src/main.c b/src/main.c
index 382abe7..9bc98ae 100644
--- a/src/main.c
+++ b/src/main.c
@@ -19,7 +19,9 @@ const char *pope =
"loosing\", naming him as the \"rock\" upon which the church would be built. \n"
"Since 1929, the pope has official residence in the Apostolic Palace in the \n"
"Vatican City, a city-state enclaved within Rome, Italy.[6] The current pope is \n"
-"Francis, who was elected on 13 March 2013, succeeding Benedict XVI.[7] \n"
+"Francis, who was elected on 13 March 2013, succeeding Benedict XVI.[7] \n";
+
+/*
"While his office is called the papacy, the jurisdiction of the episcopal see is\n"
"called the Holy See.[8] It is the Holy See that is the sovereign entity by \n"
"international law headquartered in the distinctively independent Vatican City \n"
@@ -28,15 +30,12 @@ const char *pope =
"recognized by its adherence at various levels to international organization and\n"
"by means of its diplomatic relations and political accords with many \n"
"independent states.\n";
+*/
void kernel_main(multiboot_info_t *mb) {
vsetcolor(vga_color(vga_black, vga_white));
vclear();
interrupt_init();
- start_interrupts();
- init_memory(mb);
-
- printf("%u MB memory available\n", memory_available / 1000000);
vprint(" _ _ \n");
vprint(" ___(_) |_ _ __ ___ _ __ ___ ___ ___ \n");
@@ -46,5 +45,16 @@ void kernel_main(multiboot_info_t *mb) {
vprint(pope);
+// init_memory(mb);
+
+// printf("%u MB memory available\n", memory_available / 1000000);
+
+// printf("I will now exhaust a lot of memory\n");
+// for (int i=0;i<250000000;i++) alloc_cell(0);
+//
+// printf("%u MB memory available\n", memory_available / 1000000);
+
+ start_interrupts();
+
while (1) asm volatile("hlt");
}
diff --git a/src/memory.c b/src/memory.c
index bc65311..e5e215c 100644
--- a/src/memory.c
+++ b/src/memory.c
@@ -4,19 +4,29 @@
#include <stddef.h>
#include "memory.h"
#include "multiboot.h"
+#include "bees.h"
+#include "misc.h"
#include "printf.h"
struct memory_area {
uint32_t len;
struct memory_area *next;
+ struct memory_area *prev;
};
-struct memory_area *first = NULL;
-
uint32_t memory_available = 0;
+uint32_t total_memory = 0;
+struct memory_area *first_area = NULL;
+
+struct cell *first_free = NULL;
+
+extern mem_t __kernel_start;
+extern mem_t __kernel_end;
void init_memory(multiboot_info_t *mb) {
struct memory_area *prev = NULL;
+ struct cell *prev_cell = NULL;
+
for (
multiboot_memory_map_t *e = (multiboot_memory_map_t *) mb->mmap_addr;
(unsigned int) e < mb->mmap_addr + mb->mmap_length;
@@ -24,7 +34,7 @@ void init_memory(multiboot_info_t *mb) {
) {
if (e->type != MULTIBOOT_MEMORY_AVAILABLE) continue;
// memory below 1MB is not safe to use.
- if (e->addr < 1000000) continue;
+ if (e->addr < __kernel_start) continue;
// memory above UINT_MAX is unusable.
if (e->addr > UINT_MAX) continue;
@@ -34,14 +44,54 @@ void init_memory(multiboot_info_t *mb) {
length = UINT_MAX - e->addr;
else length = e->len;
- memory_available += length;
+ // free memory comes after the kernel
+ uint32_t addr = e->addr;
+ if (addr < (uint32_t) __kernel_end) {
+ addr = (uint32_t) __kernel_end;
+ length -= addr - e->addr;
+ }
+
+ memory_available += length - sizeof(struct memory_area);
- struct memory_area *cur = (struct memory_area *) e->addr;
+ // join memory area to linked list
+ struct memory_area *cur = (struct memory_area *) addr;
cur->len = length;
+ cur->next = NULL;
+ cur->prev = prev;
if (prev != NULL)
prev->next = (struct memory_area *) e->addr;
prev = cur;
+
+ if (first_area == NULL) first_area = cur;
+
+ unsigned char *after = (unsigned char*) (cur + 1);
+
+ // link memory into free list
+ for (
+ // cells start after memory area struct; they must be aligned.
+ struct cell *c = (struct cell *)
+ (after + ((uint32_t) after % sizeof(struct cell)));
+ // no part of the cell can be outside of the memory area
+ (uint32_t) (c + 1) < (uint32_t) cur + cur->len;
+ c++
+ ) {
+ if (first_free == NULL) first_free = c;
+ c->type = FREE_CELL;
+ set_cdr(c, 0);
+ if (prev_cell != NULL) set_cdr(prev_cell, (uint32_t) c);
+ prev_cell = c;
+ }
}
+ total_memory = memory_available;
+}
+
+struct cell *alloc_cell(enum cell_type t) {
+ if (first_free == NULL) return NULL; // GC should be invoked here somehow
+ if (first_free->type != FREE_CELL) bees("heap corruption has occurred");
+ first_free = cdr_cell(first_free);
+ first_free->type = t;
+ memory_available -= sizeof(struct cell);
+ return first_free;
}
diff --git a/src/memory.h b/src/memory.h
index c5b6367..f780034 100644
--- a/src/memory.h
+++ b/src/memory.h
@@ -2,36 +2,54 @@
#define __MEMORY_H
#include <stdint.h>
-#include "redacted.h"
#include "multiboot.h"
enum cell_type {
FREE_CELL,
CONS_CELL,
INT_CELL,
+ BIGINT_CELL,
CHAR_CELL,
FLOAT_CELL,
+ VIRTUAL_CELL,
+ SYMBOL_CELL,
ARRAY_CELL,
ARRAY_MEMBER,
+ SYS_ARRAY,
APIOFORM
};
struct cell {
- uint8_t type;
- union {
- struct cell *free;
- struct cell *cons;
- struct {int type : 8; int size : 24;} array_cell;
- uint32_t int_;
- uint32_t char_;
- float float_;
- REDACTED_t apioform;
- } car;
- struct cell *cdr;
-};
+ int car : 29;
+ int cdr : 29;
+ int type : 4;
+ int gc_mark : 1;
+} __attribute((packed));
uint32_t memory_available;
void init_memory(multiboot_info_t *mb);
+struct cell *alloc_cell(enum cell_type t);
+enum cell_type get_cell_type(const struct cell *c);
+void set_cell_type(struct cell *c, enum cell_type t);
+
+static inline uint32_t car(struct cell *c) {
+ return c->car << 3;
+}
+static inline uint32_t cdr(struct cell *c) {
+ return c->cdr << 3;
+}
+static inline struct cell *car_cell(struct cell *c) {
+ return (struct cell *) car(c);
+}
+static inline struct cell *cdr_cell(struct cell *c) {
+ return (struct cell *) cdr(c);
+}
+static inline void set_car(struct cell *c, uint32_t val) {
+ c->car = val >> 3;
+}
+static inline void set_cdr(struct cell *c, uint32_t val) {
+ c->cdr = val >> 3;
+}
#endif
diff --git a/src/misc.h b/src/misc.h
new file mode 100644
index 0000000..93b3117
--- /dev/null
+++ b/src/misc.h
@@ -0,0 +1,6 @@
+#ifndef __MISC_H
+#define __MISC_H
+
+typedef unsigned char mem_t[];
+
+#endif