summaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/elf.c14
-rw-r--r--src/kernel/fat.c15
-rw-r--r--src/kernel/idt.c54
-rw-r--r--src/kernel/isrs.asm73
-rw-r--r--src/kernel/main.c2
-rw-r--r--src/kernel/paging.c53
-rw-r--r--src/kernel/paging.h4
-rw-r--r--src/kernel/pmap.c31
-rw-r--r--src/kernel/task.c2
-rw-r--r--src/kernel/task.h5
-rw-r--r--src/kernel/vga.c2
11 files changed, 209 insertions, 46 deletions
diff --git a/src/kernel/elf.c b/src/kernel/elf.c
index 423d51a..07cff91 100644
--- a/src/kernel/elf.c
+++ b/src/kernel/elf.c
@@ -126,6 +126,20 @@ bool try_elf_run(const struct drive *d, const char *path, const char *pass_old_v
tstate.page_directory = pd;
tstate.ret_addr = ehead.entry_vma;
tstate.edx = (uint32_t)pass_vma;
+
+ const char *path_end_start = path;
+ for (const char *i = path; *i; ++i)
+ if (*i == '/')
+ path_end_start = i + 1;
+
+ uint8_t i;
+ for (i = 0; i < TASK_NAME_LEN; ++i) {
+ if (!path_end_start[i])
+ break;
+ tstate.name[i] = path_end_start[i];
+ }
+ tstate.name[i] = '\0';
+
new_task(tstate);
return true;
} \ No newline at end of file
diff --git a/src/kernel/fat.c b/src/kernel/fat.c
index c297cab..c4461de 100644
--- a/src/kernel/fat.c
+++ b/src/kernel/fat.c
@@ -119,10 +119,17 @@ static const uint8_t this_dir[] = {'.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '
static const uint8_t parent_dir[] = {'.', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '};
static inline bool check_fat_names(const uint8_t *a, const uint8_t *b) {
- return (((uint32_t *)a)[0] == ((uint32_t *)b)[0]) &&
- (((uint32_t *)a)[1] == ((uint32_t *)b)[1]) &&
- (((uint16_t *)a)[4] == ((uint16_t *)b)[4]) &&
- (((uint8_t *)a)[10] == ((uint8_t *)b)[10]);
+ for (uint8_t i = 0; i < 11; ++i) {
+ uint8_t ac = a[i];
+ uint8_t bc = b[i];
+ if ((ac >= 0x61) && (ac <= 0x7a))
+ ac &= ~0x20;
+ if ((bc >= 0x61) && (bc <= 0x7a))
+ bc &= ~0x20;
+ if (ac != bc)
+ return false;
+ }
+ return true;
}
//after: cur_dir -> specified entry in root
diff --git a/src/kernel/idt.c b/src/kernel/idt.c
index 4dc8a36..b789d42 100644
--- a/src/kernel/idt.c
+++ b/src/kernel/idt.c
@@ -103,8 +103,8 @@ void const *syscall_table[] = {
&sc_memory_info
};
-//these aren't really void (*)()'s, but gcc complains if we take an address of a void, so we give it a type
-typedef void (*isr_t)();
+//these aren't really void ()'s, but gcc complains if we take an address of a void, so we give it a type
+typedef void isr_t();
extern isr_t syscall_isr;
extern isr_t quit_isr;
@@ -112,6 +112,48 @@ extern isr_t yield_isr;
extern isr_t kbd_isr;
+extern isr_t udf_isr;
+extern isr_t dfa_isr;
+extern isr_t tsf_isr;
+extern isr_t npf_isr;
+extern isr_t ssf_isr;
+extern isr_t gpf_isr;
+extern isr_t pff_isr;
+
+__attribute__ ((noreturn))
+void exception_halt(const char *id, uint32_t code, uint32_t eip, uint32_t cs) {
+ char nbuf[11];
+
+ set_log_mode(LOG_PANIC);
+ logsz("Exception #");
+ logsz(id);
+ logsz(" at 0x");
+ u8_hex(cs, nbuf);
+ logsz(nbuf);
+ logsz(":0x");
+ u32_hex(eip, nbuf);
+ logsz(nbuf);
+
+ logsz("\nerror code = 0x");
+ u32_hex(code, nbuf);
+ logsz(nbuf);
+
+ logsz("\ntask name = ");
+ logsz(active_task->name);
+
+ logsz("\ncr3 = 0x");
+ uint32_t cr3;
+ asm (
+ "mov %%cr3, %0"
+ : "=r" (cr3));
+ u32_hex(cr3, nbuf);
+ logsz(nbuf);
+
+ logsz("\nHalting.");
+ while (1)
+ asm ("hlt");
+}
+
static void register_int(uint8_t n, isr_t *isr, uint8_t dpl) {
idt[n].addr_low = (uint32_t)isr & 0xffff;
idt[n].addr_high = (uint32_t)isr >> 16;
@@ -142,6 +184,14 @@ void init_idt() {
register_int(0x21, &kbd_isr, 0);
+ register_int(0x08, &udf_isr, 0);
+ register_int(0x08, &dfa_isr, 0);
+ register_int(0x0a, &tsf_isr, 0);
+ register_int(0x0b, &npf_isr, 0);
+ register_int(0x0c, &ssf_isr, 0);
+ register_int(0x0d, &gpf_isr, 0);
+ register_int(0x0e, &pff_isr, 0);
+
outb(PIC_MCMD, PIC_RESET);
outb(PIC_SCMD, PIC_RESET);
diff --git a/src/kernel/isrs.asm b/src/kernel/isrs.asm
index 9a9600c..4f2d4e2 100644
--- a/src/kernel/isrs.asm
+++ b/src/kernel/isrs.asm
@@ -6,6 +6,14 @@ global yield_isr
global _start_user_mode
global kbd_isr
+global udf_isr
+global dfa_isr
+global tsf_isr
+global npf_isr
+global ssf_isr
+global gpf_isr
+global pff_isr
+
extern syscall_table
extern active_task
@@ -13,14 +21,26 @@ extern delete_task
extern advance_active_task
extern on_kbd_isr
extern make_sure_tasks
+extern exception_halt
n_syscalls equ 0x9
+;section .bss
+;_debug_is_start_task resb 1
+;extern switch_to_kernel_cr3
+;extern switch_to_task_cr3
+
section .text
syscall_isr:
cmp eax, n_syscalls
jge .bad
+; mov byte [_debug_is_start_task], 0
+; cmp eax, 0x4
+; jne .dont_set_debug
+; mov byte [_debug_is_start_task], 1
+;.dont_set_debug:
+
mov eax, dword [syscall_table + eax * 4]
push edi
@@ -33,6 +53,16 @@ syscall_isr:
add esp, 20
+; cmp byte [_debug_is_start_task], 0
+; je .dont_do_debug
+; push eax
+; call switch_to_kernel_cr3
+; jmp $
+; call switch_to_task_cr3
+; pop eax
+;.dont_do_debug:
+
+._before_return:
iret
.bad:
@@ -86,12 +116,13 @@ yield_isr:
mov edi, dword [eax + 24]
mov ebp, dword [eax + 28]
-_before_start_task:
+._before_return:
iret
_start_user_mode:
mov ax, 0x2b
mov ds, ax
+ mov es, ax
push dword 0x2b
sub esp, 4
@@ -113,4 +144,42 @@ kbd_isr:
pop edx
pop ecx
pop eax
- iret \ No newline at end of file
+ iret
+
+udf_isr:
+ push 0
+ push udid
+ call exception_halt
+
+dfa_isr:
+ push dfid
+ call exception_halt
+
+tsf_isr:
+ push tsid
+ call exception_halt
+
+npf_isr:
+ push npid
+ call exception_halt
+
+ssf_isr:
+ push ssid
+ call exception_halt
+
+gpf_isr:
+ push gpid
+ call exception_halt
+
+pff_isr:
+ push pfid
+ call exception_halt
+
+section .rodata
+udid db "UD", 0
+dfid db "DF", 0
+tsid db "TS", 0
+npid db "NP", 0
+ssid db "SS", 0
+gpid db "GP", 0
+pfid db "PF", 0 \ No newline at end of file
diff --git a/src/kernel/main.c b/src/kernel/main.c
index e2a23e8..06b83d1 100644
--- a/src/kernel/main.c
+++ b/src/kernel/main.c
@@ -136,7 +136,7 @@ void main() {
logsz(nbuf);
logsz("k\n\n");
- if (!try_elf_run(drives, "BIN/INIT.ELF", ""))
+ if (!try_elf_run(drives, "bin/init", ""))
PANIC("Failed to load init program.");
init_kbd();
diff --git a/src/kernel/paging.c b/src/kernel/paging.c
index a0f7c3d..fbc33de 100644
--- a/src/kernel/paging.c
+++ b/src/kernel/paging.c
@@ -20,28 +20,16 @@ enum {
PE_PRESENT = 0x001
};
-//TODO:
-// try_elf_run needs to call these new functions.
-
-void *new_pd() {
- uint32_t *pd = allocate_kernel_pages(1);
- for (uint16_t i = 0; i < 1024; ++i)
- pd[i] = 0;
- return pd;
-}
-
-void free_pd(void *pd) {
- uint32_t *pd_32 = pd;
- for (uint16_t i = 0; i < 1024; ++i)
- if (pd_32[i] & PE_PRESENT)
- free_pages((void *)(pd_32[i] & PE_ADDR_MASK), 1);
- free_pages(pd, 1);
-}
+#define KERNEL_END (0x08000000)
-void pd_map(void *pd, uint32_t physical_addr, uint32_t virtual_addr, bool writable) {
+static void pd_map(void *pd, uint32_t physical_addr, uint32_t virtual_addr, bool writable) {
uint32_t *ptp = (uint32_t *)pd + (virtual_addr >> 22);
- if (!(*ptp & PE_PRESENT))
- *ptp = (uint32_t)allocate_kernel_pages(1) | PE_USER | PE_WRITABLE | PE_PRESENT;
+ if (!(*ptp & PE_PRESENT)) {
+ uint32_t *new_pt = allocate_kernel_pages(1);
+ for (uint16_t i = 0; i < 1024; ++i)
+ new_pt[i] = 0;
+ *ptp = (uint32_t)new_pt | PE_USER | PE_WRITABLE | PE_PRESENT;
+ }
((uint32_t *)(*ptp & PE_ADDR_MASK))[(virtual_addr >> 12) % 1024] = physical_addr | PE_USER | PE_PRESENT | (PE_WRITABLE * writable);
}
@@ -51,26 +39,28 @@ static bool pd_is_mapped(void *pd, uint32_t vma) {
return (pde & PE_PRESENT) && (((uint32_t *)(pde & PE_ADDR_MASK))[(vma >> 12) % 1024] & PE_PRESENT);
}
-#define KERNEL_END (0x08000000)
-
void free_task_pd(void *pd) {
uint32_t *pd_32 = pd;
- for (uint16_t i = 0; i < 1024; ++i)
+ for (uint16_t i = KERNEL_END / 4096 / 1024; i < 1024; ++i)
if (pd_32[i] & PE_PRESENT) {
uint32_t *pt_32 = (uint32_t *)(pd_32[i] & PE_ADDR_MASK);
- if (i >= KERNEL_END >> 22)
- for (uint16_t j = 0; j < 1024; ++j)
- if (pt_32[j] & PE_PRESENT)
- free_pages((void *)(pt_32[j] & PE_ADDR_MASK), 1);
+ for (uint16_t j = 0; j < 1024; ++j)
+ if (pt_32[j] & PE_PRESENT)
+ free_pages((void *)(pt_32[j] & PE_ADDR_MASK), 1);
free_pages(pt_32, 1);
}
free_pages(pd, 1);
}
+__attribute__ ((aligned (4096)))
+static uint32_t kmap[KERNEL_END / 4096];
+
void *new_task_pd() {
- uint32_t *pd = new_pd();
- for (uint32_t addr = 0; addr < KERNEL_END; addr += 4096)
- pd_map(pd, addr, addr, false);
+ uint32_t *pd = allocate_kernel_pages(1);
+ for (uint8_t i = 0; i < KERNEL_END / 4096 / 1024; ++i)
+ pd[i] = (uint32_t)(kmap + i * 1024) | PE_USER | PE_PRESENT;
+ for (uint16_t i = KERNEL_END / 4096 / 1024; i < 1024; ++i)
+ pd[i] = 0;
return pd;
}
@@ -129,6 +119,9 @@ void init_paging() {
for (uint16_t i = 0; i < 1024; ++i)
KPAGE_DIR[i] = (uint32_t)(KPAGE_TABLE_0 + i * 1024) | PE_WRITABLE | PE_PRESENT;
+ for (uint16_t i = 0; i < KERNEL_END / 4096; ++i)
+ kmap[i] = (i * 4096) | PE_USER | PE_PRESENT;
+
asm volatile (
"mov $0x00005000, %%eax\n"
"mov %%eax, %%cr3\n"
diff --git a/src/kernel/paging.h b/src/kernel/paging.h
index 07bf386..6c1a6f5 100644
--- a/src/kernel/paging.h
+++ b/src/kernel/paging.h
@@ -3,10 +3,6 @@
void init_paging();
-void *new_pd();
-void free_pd(void *pd);
-void pd_map(void *pd, uint32_t physical_addr, uint32_t virtual_addr, bool writable);
-
void free_task_pd(void *pd);
void *new_task_pd();
void *pd_user_allocate(void *pd, uint32_t vma, uint32_t pages, bool writable);
diff --git a/src/kernel/pmap.c b/src/kernel/pmap.c
index 8634303..37c7261 100644
--- a/src/kernel/pmap.c
+++ b/src/kernel/pmap.c
@@ -77,8 +77,14 @@ void init_pagemap() {
//a smarter algorithm might pick the smallest one available,
//and go by bytes (or dwords) instead of bits where possible.
void *allocate_kernel_pages(uint32_t n) {
+//logsz("trace: allocate_kernel_pages(");
+//char nbuf[11];
+//u32_dec(n, nbuf);
+//logsz(nbuf);
+//logsz(") = 0x");
+
uint32_t run = 0;
-
+
for (uint32_t page = KBSS_START >> 12; page < USER_START >> 12; ++page) {
if (PAGE_USED(page))
run = 0;
@@ -87,6 +93,9 @@ void *allocate_kernel_pages(uint32_t n) {
for (uint32_t i = start; i <= page; ++i)
SET_PAGE(i);
kernel_pages_left -= n;
+ //u32_hex(start << 12, nbuf);
+ //logsz(nbuf);
+ //logch('\n');
return (void *)(start << 12);
}
}
@@ -98,8 +107,14 @@ void *allocate_kernel_pages(uint32_t n) {
//a smarter algorithm might pick the smallest one available,
//and go by bytes (or dwords) instead of bits where possible.
void *allocate_user_pages(uint32_t n) {
+//logsz("trace: allocate_user_pages(");
+//char nbuf[11];
+//u32_dec(n, nbuf);
+//logsz(nbuf);
+//logsz(") = 0x");
+
uint32_t run = 0;
-
+
for (uint32_t page = USER_START >> 12; page < 1048576; ++page) {
if (PAGE_USED(page))
run = 0;
@@ -108,6 +123,9 @@ void *allocate_user_pages(uint32_t n) {
for (uint32_t i = start; i <= page; ++i)
SET_PAGE(i);
user_pages_left -= n;
+ //u32_hex(start << 12, nbuf);
+ //logsz(nbuf);
+ //logch('\n');
return (void *)(start << 12);
}
}
@@ -117,6 +135,15 @@ void *allocate_user_pages(uint32_t n) {
//in the future, change this to go by bytes or dwords instead of bits.
void free_pages(const void *ptr, uint32_t n) {
+//logsz("trace: free_pages(0x");
+//char nbuf[11];
+//u32_hex(ptr, nbuf);
+//logsz(nbuf);
+//logsz(", ");
+//u32_dec(n, nbuf);
+//logsz(nbuf);
+//logsz(")\n");
+
uint32_t page = (uint32_t)ptr >> 12;
for (uint32_t i = page; i < page + n; ++i)
CLEAR_PAGE(i);
diff --git a/src/kernel/task.c b/src/kernel/task.c
index e2c19ca..6c53510 100644
--- a/src/kernel/task.c
+++ b/src/kernel/task.c
@@ -91,6 +91,8 @@ void make_sure_tasks() {
}
void delete_task(struct task_state *state) {
+ switch_to_kernel_cr3();
free_task_pd(state->page_directory);
+ switch_to_task_cr3();
state->page_directory = 0;
} \ No newline at end of file
diff --git a/src/kernel/task.h b/src/kernel/task.h
index 838f27b..0fa9688 100644
--- a/src/kernel/task.h
+++ b/src/kernel/task.h
@@ -4,10 +4,11 @@
#include <stdbool.h>
#include <stdint.h>
+#define TASK_NAME_LEN 15
+
struct task_state {
uint32_t ret_addr;
void *page_directory;
- //maybe put scheduling or priviledge information here?
uint32_t ebx;
uint32_t ecx;
@@ -16,6 +17,8 @@ struct task_state {
uint32_t edi;
uint32_t ebp;
uint32_t esp;
+
+ char name[TASK_NAME_LEN + 1];
} __attribute__ ((packed));
extern struct task_state *active_task;
diff --git a/src/kernel/vga.c b/src/kernel/vga.c
index c03e5f0..daa92fe 100644
--- a/src/kernel/vga.c
+++ b/src/kernel/vga.c
@@ -31,6 +31,8 @@ void vga_blank() {
void vga_printch(char ch) {
if (ch == '\n')
cursor = ((cursor - VGA_START) / VGA_COLUMNS + 1) * VGA_COLUMNS + VGA_START;
+ else if (ch == '\b')
+ *--cursor = mask | ' ';
else
*cursor++ = mask | (uint8_t)ch;
if (cursor == VGA_END)