summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2024-04-15 23:47:25 +0200
committerAnton Kling <anton@kling.gg>2024-04-16 00:02:23 +0200
commitefe10908766d96974c008a6a8f124916fdca7a14 (patch)
tree69f90dc3c01d32d63a38ab50f61268b1ac06dc97 /kernel
parent62ba2a9ab01e5f2a9b1cd325af8d3112702b7713 (diff)
Kernel: Improve "out of memory" error handling
It can now boot with fairly low memory while not crashing and instead gracefully failing the operation. Userland still does not properly handle errors.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/cpu/idt.c4
-rw-r--r--kernel/kmalloc.c3
-rw-r--r--kernel/lib/list.c26
-rw-r--r--kernel/lib/list.h2
-rw-r--r--kernel/sched/scheduler.c52
5 files changed, 52 insertions, 35 deletions
diff --git a/kernel/cpu/idt.c b/kernel/cpu/idt.c
index b668c6e..ce21d08 100644
--- a/kernel/cpu/idt.c
+++ b/kernel/cpu/idt.c
@@ -53,6 +53,10 @@ void general_protection_fault(reg_t *regs) {
klog("General Protetion Fault", 0x1);
kprintf(" Error Code: %x\n", regs->error_code);
kprintf("Instruction Pointer: %x\n", regs->eip);
+ if (current_task) {
+ kprintf("PID: %x\n", current_task->pid);
+ kprintf("Name: %s\n", current_task->program_name);
+ }
dump_backtrace(12);
halt();
EOI(0xD - 8);
diff --git a/kernel/kmalloc.c b/kernel/kmalloc.c
index 84a16bd..124e5a5 100644
--- a/kernel/kmalloc.c
+++ b/kernel/kmalloc.c
@@ -59,7 +59,7 @@ int init_heap(void) {
}
int add_heap_memory(size_t min_desired) {
- min_desired += sizeof(MallocHeader) + 0x2000;
+ min_desired += sizeof(MallocHeader);
size_t allocation_size = max(min_desired, NEW_ALLOC_SIZE);
allocation_size += delta_page(allocation_size);
void *p;
@@ -157,7 +157,6 @@ void *int_kmalloc(size_t s) {
if (!free_entry) {
if (!add_heap_memory(s)) {
klog("Ran out of memory.", LOG_ERROR);
- assert(0);
return NULL;
}
return kmalloc(s);
diff --git a/kernel/lib/list.c b/kernel/lib/list.c
index c663230..e4d4b23 100644
--- a/kernel/lib/list.c
+++ b/kernel/lib/list.c
@@ -2,15 +2,13 @@
#include <kmalloc.h>
#include <lib/list.h>
-int list_init(struct list *list) {
- // TODO: Make it dynamic
+void list_init(struct list *list) {
list->capacity = 5;
+ list->tail_index = -1;
list->entries = kmalloc(sizeof(void *) * list->capacity);
if (!list->entries) {
- return 0;
+ list->capacity = 0;
}
- list->tail_index = -1;
- return 1;
}
void list_reset(struct list *list) {
@@ -24,15 +22,24 @@ int list_clone(struct list *in, struct list *out) {
if (!list_get(in, i, &output)) {
break;
}
- list_add(out, output, NULL);
+ if (!list_add(out, output, NULL)) {
+ list_free(out);
+ return 0;
+ }
}
return 1;
}
int list_add(struct list *list, void *entry, int *index) {
if (list->tail_index + 1 >= list->capacity) {
- list->capacity += 25;
- list->entries = krealloc(list->entries, sizeof(void *) * list->capacity);
+ int new_capacity = list->capacity + 25;
+ void *new_allocation =
+ krealloc(list->entries, sizeof(void *) * new_capacity);
+ if (!new_allocation) {
+ return 0;
+ }
+ list->entries = new_allocation;
+ list->capacity = new_capacity;
}
list->tail_index++;
list->entries[list->tail_index] = entry;
@@ -60,5 +67,8 @@ int list_get(const struct list *list, int index, void **out) {
}
void list_free(struct list *list) {
+ list->capacity = 0;
+ list->tail_index = -1;
kfree(list->entries);
+ list->entries = NULL;
}
diff --git a/kernel/lib/list.h b/kernel/lib/list.h
index b1f0127..2d1fa0f 100644
--- a/kernel/lib/list.h
+++ b/kernel/lib/list.h
@@ -6,7 +6,7 @@ struct list {
int tail_index;
};
-int list_init(struct list *list);
+void list_init(struct list *list);
void list_reset(struct list *list);
void list_free(struct list *list);
int list_clone(struct list *in, struct list *out);
diff --git a/kernel/sched/scheduler.c b/kernel/sched/scheduler.c
index f56ff56..0eff530 100644
--- a/kernel/sched/scheduler.c
+++ b/kernel/sched/scheduler.c
@@ -100,12 +100,19 @@ void set_signal_handler(int sig, void (*handler)(int)) {
void insert_eip_on_stack(u32 cr3, u32 address, u32 value);
process_t *create_process(process_t *p, u32 esp, u32 eip) {
- process_t *r;
- r = kcalloc(1, sizeof(process_t));
+ process_t *r = kcalloc(1, sizeof(process_t));
+ if (!r) {
+ return NULL;
+ }
+ r->tcb = kcalloc(1, sizeof(struct TCB));
+ if (!r->tcb) {
+ kfree(r);
+ return NULL;
+ }
r->pid = next_pid;
next_pid++;
if (!p) {
- assert(1 == next_pid);
+ assert(0 == r->pid);
strlcpy(r->program_name, "[kernel]", sizeof(current_task->program_name));
} else {
strlcpy(r->program_name, "[Not yet named]",
@@ -113,21 +120,11 @@ process_t *create_process(process_t *p, u32 esp, u32 eip) {
}
if (p) {
- r->cr3 = clone_directory(p->cr3);
- if (!r->cr3) {
+ if (!list_clone(&p->file_descriptors, &r->file_descriptors)) {
+ kfree(r->tcb);
kfree(r);
return NULL;
}
- } else {
- r->cr3 = get_active_pagedirectory();
- }
- r->parent = p;
-
- r->tcb = kcalloc(1, sizeof(struct TCB));
- r->tcb->CR3 = r->cr3->physical_address;
-
- if (p) {
- list_clone(&p->file_descriptors, &r->file_descriptors);
for (int i = 0;; i++) {
vfs_fd_t *out;
if (!list_get(&p->file_descriptors, i, (void **)&out)) {
@@ -140,6 +137,21 @@ process_t *create_process(process_t *p, u32 esp, u32 eip) {
} else {
list_init(&r->file_descriptors);
}
+
+ if (p) {
+ r->cr3 = clone_directory(p->cr3);
+ if (!r->cr3) {
+ kfree(r->tcb);
+ kfree(r);
+ return NULL;
+ }
+ } else {
+ r->cr3 = get_active_pagedirectory();
+ }
+ r->parent = p;
+
+ r->tcb->CR3 = r->cr3->physical_address;
+
list_init(&r->read_list);
list_init(&r->write_list);
list_init(&r->disconnect_list);
@@ -149,18 +161,10 @@ process_t *create_process(process_t *p, u32 esp, u32 eip) {
list_init(&r->event_queue);
- // Temporarily switch to the page directory to be able to place the
- // "entry_instruction_pointer" onto the stack.
-
if (esp) {
esp -= 4;
insert_eip_on_stack(r->cr3->physical_address, esp, eip);
- esp -= 4;
- insert_eip_on_stack(r->cr3->physical_address, esp, 0x1337);
- esp -= 4;
- insert_eip_on_stack(r->cr3->physical_address, esp, 0x1488);
- esp -= 4;
- esp -= 4;
+ esp -= 16;
insert_eip_on_stack(r->cr3->physical_address, esp, 0xF00DBABE);
r->tcb->ESP = esp;
}