From b4edf54aa6709e0f77148f9df4f54f52e64309ac Mon Sep 17 00:00:00 2001 From: hasslesstech Date: Thu, 6 Mar 2025 21:50:29 +0200 Subject: [PATCH] [dirty:segfault] stage 1 --- Makefile | 23 +++++++++++++++++++++ config.h | 1 + inc/kernel.h | 34 +++++++++++++++++++++++++++++++ inc/mmu.h | 2 ++ inc/page_table.h | 0 inc/process.h | 29 +++++++++++++++++++++++++++ inc/random.h | 6 ++++++ src/kernel.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ src/main.c | 44 ++++++++++++++++++++++++++++++++++++++++ src/mmu.c | 18 +++++++++++++++++ src/process.c | 43 +++++++++++++++++++++++++++++++++++++++ src/random.c | 14 +++++++++++++ 12 files changed, 266 insertions(+) create mode 100644 Makefile create mode 100644 config.h create mode 100644 inc/kernel.h create mode 100644 inc/mmu.h create mode 100644 inc/page_table.h create mode 100644 inc/process.h create mode 100644 inc/random.h create mode 100644 src/kernel.c create mode 100644 src/main.c create mode 100644 src/mmu.c create mode 100644 src/process.c create mode 100644 src/random.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2eaa940 --- /dev/null +++ b/Makefile @@ -0,0 +1,23 @@ +CCFLAGS = -g -O0 -Iinc/ -I. + + +main: main.o kernel.o mmu.o process.o random.o + gcc $(CCFLAGS) -o main main.o kernel.o mmu.o process.o random.o + +main.o: src/main.c + gcc $(CCFLAGS) -c -o main.o src/main.c + +kernel.o: src/kernel.c + gcc $(CCFLAGS) -c -o kernel.o src/kernel.c + +mmu.o: src/mmu.c + gcc $(CCFLAGS) -c -o mmu.o src/mmu.c + +process.o: src/process.c + gcc $(CCFLAGS) -c -o process.o src/process.c + +random.o: src/random.c + gcc $(CCFLAGS) -c -o random.o src/random.c + +clean: + rm *.o main diff --git a/config.h b/config.h new file mode 100644 index 0000000..3bd10e0 --- /dev/null +++ b/config.h @@ -0,0 +1 @@ +#define PHYSICAL_PAGE_AMOUNT 128 diff --git a/inc/kernel.h b/inc/kernel.h new file mode 100644 index 0000000..86c8868 --- /dev/null +++ b/inc/kernel.h @@ -0,0 +1,34 @@ +#ifndef KERNEL_HEADER +#define KERNEL_HEADER + +#include "process.h" + +struct RunQ { + struct Process *current_proc; + size_t max_procs; + size_t proc_amount; + size_t next_proc_id; +}; + +struct RunQ *RunQ(size_t max_procs); +void RUNQ_add_process(size_t max_page_accesses, size_t total_pages_owned); + +static struct RunQ *runq; + + +struct PhysPage { + size_t ppn; + size_t busy_flag; + struct PhysPage *prev; + struct PhysPage *next; + struct PageTable *pt; + size_t pt_index; +}; + +static struct PhysPage *first_free_page; +static struct PhysPage *first_busy_page; + + +void KERNEL_page_fault(struct PageTableEntry *pt, size_t page_no); + +#endif diff --git a/inc/mmu.h b/inc/mmu.h new file mode 100644 index 0000000..88747c5 --- /dev/null +++ b/inc/mmu.h @@ -0,0 +1,2 @@ +void MMU_read(struct PageTableEntry *pt, size_t page_no); +void MMU_write(struct PageTableEntry *pt, size_t page_no); diff --git a/inc/page_table.h b/inc/page_table.h new file mode 100644 index 0000000..e69de29 diff --git a/inc/process.h b/inc/process.h new file mode 100644 index 0000000..da9b84d --- /dev/null +++ b/inc/process.h @@ -0,0 +1,29 @@ +#ifndef PROCESS_HEADER +#define PROCESS_HEADER + +#include + +struct PageTableEntry { + size_t p:1; + size_t r:1; + size_t m:1; + size_t ppn; +}; + +struct Process { + struct Process *prev; + struct Process *next; + size_t id; + size_t pages_accessed; + size_t max_accesses; + size_t total_pages_owned; + struct PageTableEntry *pt; +}; + +struct Process *Process(size_t proc_id, + size_t max_accesses, + size_t total_pages_owned); + +size_t PROCESS_run_for(struct Process *p, size_t time_bits); + +#endif diff --git a/inc/random.h b/inc/random.h new file mode 100644 index 0000000..5e8346a --- /dev/null +++ b/inc/random.h @@ -0,0 +1,6 @@ +#ifndef RANDOM_HEADER +#define RANDOM_HEADER + +size_t randint(size_t max); + +#endif diff --git a/src/kernel.c b/src/kernel.c new file mode 100644 index 0000000..972bd9c --- /dev/null +++ b/src/kernel.c @@ -0,0 +1,52 @@ +#include +#include + +#include "kernel.h" +#include "process.h" + +struct RunQ * +RunQ(size_t max_procs) +{ + struct RunQ *runq = malloc(sizeof(struct RunQ)); + runq->current_proc = NULL; + runq->max_procs = max_procs; + runq->proc_amount = 0; + runq->next_proc_id = 1; + + return runq; +} + +void +RUNQ_add_process(size_t max_page_accesses, + size_t total_pages_owned) +{ + if (runq->proc_amount >= runq->max_procs) + return; + + struct Process *new_p = Process(runq->next_proc_id, max_page_accesses, total_pages_owned); + + if (!runq->current_proc) { + runq->current_proc = new_p; + new_p->next = new_p; + new_p->prev = new_p; + } else { + new_p->next = runq->current_proc; + new_p->prev = runq->current_proc->prev; + new_p->next->prev = new_p; + new_p->prev->next = new_p; + runq->current_proc = new_p; + } + + runq->proc_amount++; + runq->next_proc_id++; +} + + +void +KERNEL_page_fault(struct PageTableEntry *pt, size_t page_no) +{ + if (first_free_page) { + pt[page_no].ppn = first_free_page->ppn; + pt[page_no].p = 1; + } +} diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..7d912e6 --- /dev/null +++ b/src/main.c @@ -0,0 +1,44 @@ +#include +#include +#include + +#include "kernel.h" + +#include "config.h" + +int +main(void) +{ + first_busy_page = NULL; + + struct PhysPage *first_free_page = malloc(sizeof(struct PhysPage)); + first_free_page->ppn = 0; + first_free_page->busy_flag = 0; + first_free_page->prev = first_free_page; + first_free_page->next = first_free_page; + + for (int i = 1; i <= PHYSICAL_PAGE_AMOUNT; i++) { + struct PhysPage *pp = malloc(sizeof(struct PhysPage)); + pp->ppn = i; + pp->busy_flag = 0; + + /* + * insert into here + * | + * v + * [ ] [ ] [ ] + * ^ + * | + * *first_free_page + */ + pp->prev = first_free_page->prev; + pp->next = first_free_page; + pp->next->prev = pp; + pp->prev->next = pp; + } + + runq = RunQ(10); + RUNQ_add_process(10000, 50); + RUNQ_add_process(10000, 50); + RUNQ_add_process(10000, 50); +} diff --git a/src/mmu.c b/src/mmu.c new file mode 100644 index 0000000..93de176 --- /dev/null +++ b/src/mmu.c @@ -0,0 +1,18 @@ +#include "kernel.h" + +void MMU_read(struct PageTableEntry *pt, size_t page_no) +{ + if (!pt[page_no].p) + KERNEL_page_fault(pt, page_no); + + pt[page_no].r = 1; +} + +void MMU_write(struct PageTableEntry *pt, size_t page_no) +{ + if (!pt[page_no].p) + KERNEL_page_fault(pt, page_no); + + pt[page_no].r = 1; + pt[page_no].m = 1; +} diff --git a/src/process.c b/src/process.c new file mode 100644 index 0000000..21ce891 --- /dev/null +++ b/src/process.c @@ -0,0 +1,43 @@ +#include +#include + +#include "process.h" +#include "mmu.h" +#include "random.h" + +struct Process * +Process(size_t proc_id, size_t max_accesses, size_t total_pages_owned) +{ + struct Process *p = malloc(sizeof(struct Process)); + p->id = proc_id; + p->max_accesses = max_accesses; + p->pages_accessed = 0; + p->total_pages_owned = total_pages_owned; + p->pt = malloc(sizeof(struct PageTableEntry) * total_pages_owned); + + for (size_t i = 0; i < p->total_pages_owned; i++) + p->pt[i].p = 0; + + return p; +} + +size_t PROCESS_run_for(struct Process *p, size_t time_bits) +{ + for (size_t i = 0; + (i < time_bits) && (p->pages_accessed < p->max_accesses); + i++, p->pages_accessed++) + { + // no working set yet + int accessed_page_no = randint(p->total_pages_owned); + + if (randint(10) > 7) { + printf("[process] Writing to page #%d\n", accessed_page_no); + MMU_write(p->pt, accessed_page_no); + } else { + printf("[process] Reading from page #%d\n", accessed_page_no); + MMU_read(p->pt, accessed_page_no); + } + } + + return p->pages_accessed >= p->max_accesses; +} diff --git a/src/random.c b/src/random.c new file mode 100644 index 0000000..9f103df --- /dev/null +++ b/src/random.c @@ -0,0 +1,14 @@ +#include +#include +#include + +size_t randint(size_t max) +{ + size_t random_value; + + int f = open("/dev/urandom", O_RDONLY); + read(f, &random_value, 8); + close(f); + + return random_value % max; +}