aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNic Gaffney <gaffney_nic@protonmail.com>2024-02-28 06:46:04 -0600
committerNic Gaffney <gaffney_nic@protonmail.com>2024-02-28 06:46:04 -0600
commit2d54f6f129cedad272084f4cfe3731309f4c462e (patch)
tree0459fc1d595b251ea8a8eb19b17105ae4c200faf /src
parent67e379966c657eccb3086508fa9bff38b831fbde (diff)
downloadgftos-2d54f6f129cedad272084f4cfe3731309f4c462e.tar.gz
Enabled paging
Diffstat (limited to 'src')
-rw-r--r--src/boot/boot.s15
-rw-r--r--src/include/exceptions.h2
-rw-r--r--src/include/paging.h13
-rw-r--r--src/include/print.h2
-rw-r--r--src/kernel/exceptions.c9
-rw-r--r--src/kernel/kernel.c11
-rw-r--r--src/kernel/paging/mmap.c3
-rw-r--r--src/kernel/paging/page_alloc.c5
-rw-r--r--src/kernel/paging/paging.c67
-rw-r--r--src/kernel/print.c19
-rw-r--r--src/kernel/tables/gdt.c4
-rw-r--r--src/linker.ld13
12 files changed, 141 insertions, 22 deletions
diff --git a/src/boot/boot.s b/src/boot/boot.s
index dbb4052..51bef8f 100644
--- a/src/boot/boot.s
+++ b/src/boot/boot.s
@@ -30,6 +30,10 @@ idtr:
dw 0
dd 0
+global page_ptr
+page_ptr:
+ dd 0
+
global _start:function (_start.end - _start)
_start:
mov esp, stack_top
@@ -37,7 +41,7 @@ _start:
extern get_gdtr
call get_gdtr
cli
- lgdt [gdtr]
+ lgdt [gdtr]
mov eax, cr0
or al, 1
mov cr0, eax
@@ -50,6 +54,15 @@ _start:
sti
xchg bx, bx
+ extern genDirs
+ extern page_dir
+ call genDirs
+ mov eax, page_dir
+ mov cr3, eax
+ mov eax, cr0
+ or eax, 0x80000001
+ mov cr0, eax
+
[bits 32]
extern kernel_main
call kernel_main
diff --git a/src/include/exceptions.h b/src/include/exceptions.h
index 1da8348..fddc66e 100644
--- a/src/include/exceptions.h
+++ b/src/include/exceptions.h
@@ -1,2 +1,2 @@
#pragma once
-__attribute__((noreturn)) void panic(const char *msg);
+__attribute__((noreturn)) void panic(const char *msg, ...);
diff --git a/src/include/paging.h b/src/include/paging.h
new file mode 100644
index 0000000..11578c2
--- /dev/null
+++ b/src/include/paging.h
@@ -0,0 +1,13 @@
+#ifndef __PAGING_H
+#define __PAGING_H
+#include <stdint.h>
+typedef uint32_t Page_Directory;
+typedef uint32_t Page_Table;
+
+Page_Directory make_pagedir(Page_Table *addr, uint8_t flags);
+Page_Directory make_pagetable(uint32_t addr, uint8_t flags);
+void *get_physaddr(void *virtualaddr);
+void map_page(void *physaddr, void *virtualaddr, uint8_t flags);
+void genDirs();
+void *kalloc_init();
+#endif // !__PAGING_H
diff --git a/src/include/print.h b/src/include/print.h
index 7ef7fa3..63f5724 100644
--- a/src/include/print.h
+++ b/src/include/print.h
@@ -1,5 +1,6 @@
#pragma once
+#include <stdarg.h>
#include <stdint.h>
// Define colors for printing
@@ -30,3 +31,4 @@ void print_char(char);
int print_str(char *);
void print_set_color(uint8_t, uint8_t);
int printf(const char *, ...);
+int printf_logic(const char *, va_list args);
diff --git a/src/kernel/exceptions.c b/src/kernel/exceptions.c
index 11e45fb..bd81c08 100644
--- a/src/kernel/exceptions.c
+++ b/src/kernel/exceptions.c
@@ -1,9 +1,14 @@
#include "print.h"
+#include <stdarg.h>
-__attribute__((noreturn)) void panic(const char *msg) {
+__attribute__((noreturn)) void panic(const char *msg, ...) {
+ va_list args;
+ va_start(args, msg);
print_set_color(PRINT_COLOR_BLACK, PRINT_COLOR_RED);
print_clear();
- printf("PANIC!!\n\t%s", msg);
+ printf("PANIC!!\n\t");
+ printf_logic(msg, args);
+ va_end(args);
__asm__ volatile("cli; hlt");
while (1)
;
diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c
index d960c20..c103476 100644
--- a/src/kernel/kernel.c
+++ b/src/kernel/kernel.c
@@ -1,9 +1,8 @@
+#include "exceptions.h"
#include "gdt.h"
#include "isr.h"
+#include "paging.h"
#include "print.h"
-extern GDTR_t idtr;
-extern GDTR_t gdtr;
-
#if defined(__linux__)
#error "Not using cross compiler!"
#endif
@@ -14,6 +13,9 @@ extern GDTR_t gdtr;
#endif
void motd() { printf("Welcome to gftos!\n=================\n"); }
+extern Page_Table pgtable[1024];
+extern Page_Directory page_dir[1024];
+extern GDT_t table;
void kernel_main(void) {
PIC_init(0x20, 0xA0);
@@ -22,6 +24,9 @@ void kernel_main(void) {
print_set_color(PRINT_COLOR_PINK, PRINT_COLOR_DARK_GRAY);
print_clear();
motd();
+ printf("Page Directory: %x\n", (Page_Directory *)page_dir[1023]);
+ printf("Page Table: %x\n", (Page_Table *)pgtable);
+ printf("GDT: %x\n", table);
for (;;) {
update_cursor();
asm("hlt");
diff --git a/src/kernel/paging/mmap.c b/src/kernel/paging/mmap.c
new file mode 100644
index 0000000..662c2cd
--- /dev/null
+++ b/src/kernel/paging/mmap.c
@@ -0,0 +1,3 @@
+#include "paging.h"
+// TODO: write a frame page allocator to allocate page tables into virtual
+// memory
diff --git a/src/kernel/paging/page_alloc.c b/src/kernel/paging/page_alloc.c
new file mode 100644
index 0000000..3c3e28f
--- /dev/null
+++ b/src/kernel/paging/page_alloc.c
@@ -0,0 +1,5 @@
+#include "paging.h"
+#include <stddef.h>
+#include <stdint.h>
+extern uint32_t endkernel;
+// TODO:
diff --git a/src/kernel/paging/paging.c b/src/kernel/paging/paging.c
new file mode 100644
index 0000000..6a482c8
--- /dev/null
+++ b/src/kernel/paging/paging.c
@@ -0,0 +1,67 @@
+#include "paging.h"
+#include "exceptions.h"
+#include <stdint.h>
+extern uint32_t endkernel;
+
+Page_Directory make_pagedir(Page_Table *addr, uint8_t flags) {
+ return ((uint32_t)addr & 0xFFFFF000) | flags;
+}
+
+Page_Table make_pagetable(uint32_t addr, uint8_t flags) {
+ return ((uint32_t)addr & 0xFFFFF000) | flags;
+}
+
+Page_Directory page_dir[1024] __attribute__((aligned(4096)));
+Page_Table pgtable[1024] __attribute__((aligned(4096)));
+
+void idpaging(uint32_t *first_pte, uint32_t from, int size) {
+ for (; size > 0; from += 4096, size -= 4096, first_pte++) {
+ *first_pte = make_pagetable(from, 3); // mark page present.
+ }
+}
+
+void genDirs() {
+ for (int i = 0; i < 1024; i++) {
+ page_dir[i] = make_pagedir(0x0, 2);
+ for (int j = 0; j < 1024; j++)
+ ((uint32_t *)(page_dir[i] & 0xFFFFF000))[j] &= 0xFFFFFFFE;
+ }
+
+ page_dir[1023] = make_pagetable((uint32_t)page_dir, 3);
+
+ idpaging(&pgtable[0], 0x0, 1024 * 0x800);
+ page_dir[0] = make_pagedir(pgtable, 3);
+}
+
+void *get_physaddr(void *virtualaddr) {
+ unsigned long pdindex = (unsigned long)virtualaddr >> 22;
+ unsigned long ptindex = (unsigned long)virtualaddr >> 12 & 0x03FF;
+
+ unsigned long *pd = (unsigned long *)page_dir;
+ if (!(pd[pdindex] & 1))
+ panic("Unimplemented - getphysaddr - pd[%d]", pdindex);
+
+ unsigned long *pt = ((unsigned long *)0xFFC00000) + (0x400 * pdindex);
+ if (!(pt[ptindex] & 1))
+ panic("Unimplemented - getphysaddr - pt[%d]", ptindex);
+
+ return (void *)((pt[ptindex] & ~0xFFF) +
+ ((unsigned long)virtualaddr & 0xFFF));
+}
+
+void map_page(void *physaddr, void *virtualaddr, uint8_t flags) {
+ unsigned long pdindex = (unsigned long)virtualaddr >> 22;
+ unsigned long ptindex = (unsigned long)virtualaddr >> 12 & 0x03FF;
+
+ unsigned long *pd = (unsigned long *)page_dir;
+ if (!(pd[pdindex] & 1)) {
+ pd[pdindex] =
+ make_pagedir((uint32_t *)0xFFC00000 + (0x400 * pdindex), 3);
+ }
+
+ unsigned long *pt = ((unsigned long *)0xFFC00000) + (0x400 * pdindex);
+ if (pt[ptindex] & 1)
+ panic("Unimplemented - map_page - pt[%d]", ptindex);
+
+ pt[ptindex] = ((unsigned long)physaddr) | (flags & 0xFFF) | 0x01; // Present
+}
diff --git a/src/kernel/print.c b/src/kernel/print.c
index f635fe5..937a8aa 100644
--- a/src/kernel/print.c
+++ b/src/kernel/print.c
@@ -129,14 +129,10 @@ void print_set_color(uint8_t foreground, uint8_t background) {
color = foreground + (background << 4);
}
-int printf(const char *str, ...) {
- va_list args;
- va_start(args, str);
- char temp_str[256] = "";
+int printf_logic(const char *str, va_list args) {
int len = 0;
-
- size_t i;
- for (i = 0; str[i] != '\0'; ++i) {
+ char temp_str[256] = "";
+ for (int i = 0; str[i] != '\0'; ++i) {
if (str[i] == '%') {
switch (str[++i]) {
case 'i':
@@ -164,6 +160,13 @@ int printf(const char *str, ...) {
}
print_char(str[i]);
}
+ return len;
+}
+
+int printf(const char *str, ...) {
+ va_list args;
+ va_start(args, str);
+ int len = printf_logic(str, args);
va_end(args);
- return i;
+ return len;
}
diff --git a/src/kernel/tables/gdt.c b/src/kernel/tables/gdt.c
index 9c65152..6cd05a8 100644
--- a/src/kernel/tables/gdt.c
+++ b/src/kernel/tables/gdt.c
@@ -7,8 +7,8 @@ void get_gdtr() {
uint32_t base = (uint32_t)table;
table[0] = make_descriptor(base, 0, 0);
- table[1] = make_descriptor(base, 0x3FFFF, make_code(0, 0, 1));
- table[2] = make_descriptor(base, 0x3FFFF, make_data(0, 0, 1));
+ table[1] = make_descriptor(base, 0xFFFFF, make_code(0, 0, 1));
+ table[2] = make_descriptor(base, 0xFFFFF, make_data(0, 0, 1));
gdtr.size = sizeof(Segment_Descriptor_t) * 3 - 1;
gdtr.offset = base;
diff --git a/src/linker.ld b/src/linker.ld
index 8a9d5f8..770b955 100644
--- a/src/linker.ld
+++ b/src/linker.ld
@@ -10,15 +10,16 @@ ENTRY (_start)
*/
SECTIONS
{
- /* Put sections at 1MiB, the conventional place for kernels to be
+ /* Put sections at 1MiB, the conventional place for kernels to be
* loaded at by the bootloader. */
. = 1M;
- /* First, put the multiboot header. It is required to be put
- * VERY early in the image or the bootloader wont recognize the file
+ /* First, put the multiboot header. It is required to be put
+ * VERY early in the image or the bootloader wont recognize the file
* format. Next, we will put the .text section*/
.text BLOCK(4K) : ALIGN(4K)
{
+ text_start = .;
*(.multiboot)
*(.text)
}
@@ -31,14 +32,16 @@ SECTIONS
.data BLOCK(4K) : ALIGN(4K)
{
*(.data)
+ end_data = .;
}
/* Read write data (uninitialized) and stack */
.bss BLOCK(4K) : ALIGN(4K)
{
+ sbss = .;
*(COMMON)
*(.bss)
+ ebss = .;
+ endkernel = .;
}
- /* The compiler may produce other sections, but they will be put in
- * a section with the same name by default. Add stuff here as needed */
}