paging is not very fun

This commit is contained in:
Tyler Murphy 2023-07-22 11:05:30 -04:00
parent 7a912d1b66
commit da094d011f
24 changed files with 235 additions and 85 deletions

4
.env
View file

@ -5,7 +5,7 @@ LD = $(ARCH)-$(FORMAT)-ld
AS = nasm
AR = ar
CFLAGS = -ffreestanding -m32 -O2 -Wall -Wextra -pedantic # -DKERNEL_LOG
LDFLAGS = -nostdlib
CFLAGS = -ffreestanding -m32 -O2 -Wall -Wextra -pedantic
LDFLAGS = -nostdlib -export-dynamic
QEMU = qemu-system-i386

View file

@ -7,9 +7,9 @@ SECTIONS {
kernel_start = .;
.bootstrap : {
*(.bootstrap.data)
*(.bootstrap.stack)
*(.bootstrap.text)
*(.bootstrap.data)
*(.bootstrap.bss)
}
. += 0xC0000000;
@ -30,7 +30,6 @@ SECTIONS {
{
*(COMMON)
*(.bss)
*(.stack)
}
kernel_end = .;

View file

@ -1,5 +1,7 @@
#pragma once
#include <stddef.h>
extern void arch_init(void *boot_info);
extern void arch_update(void);
extern void arch_halt(void);

View file

@ -102,5 +102,5 @@ struct FixedACPIDescriptionTable {
struct GenericAddressStructure x_gpe1_block;
};
void acpi_init(void *rsdp);
void acpi_poweroff(void);
extern void acpi_init(void);
extern void acpi_poweroff(void);

View file

@ -12,7 +12,7 @@ struct BootTag {
uint32_t type;
uint32_t size;
union {
char cmdline[CMDLINE_MAX];
char cmdline[CMDLINE_MAX + 1];
struct MemoryMap *memory_map;
struct RootSystemDescriptionPointer *rsdp;
} data;
@ -26,9 +26,9 @@ struct BootInfo {
enum BootTagID {
ID_CMDLINE = 0,
iD_MEMORYMAP = 6,
ID_MEMORYMAP = 6,
ID_RSDP = 14
};
void load_boot_info(void* boot_info);
bool get_boot_tag(enum BootTagID id, struct BootTag **tag);
extern void load_boot_info(void* boot_info);
extern bool get_boot_tag(enum BootTagID id, struct BootTag **tag);

View file

@ -0,0 +1,33 @@
#pragma once
#include <stddef.h>
struct page_directory_t { // 32 bits
unsigned int present : 1;
unsigned int rw_flag : 1;
unsigned int access_lvl : 1; //0 is for only ring0. 1 is for anybody.
unsigned int write_through : 1;
unsigned int cache_off : 1;
unsigned int accessed : 1;
unsigned int zero : 1;
unsigned int page_size : 1;
unsigned int unused : 4;
unsigned int tbl_addr : 20;
};
struct page_table_t { // 32 bits
unsigned int present : 1;
unsigned int rw_flag : 1;
unsigned int access_lvl : 1; //0 is for only ring0. 1 is for anybody.
unsigned int write_through : 1;
unsigned int cache_off : 1;
unsigned int accessed : 1;
unsigned int dirty : 1;
unsigned int zero : 1;
unsigned int global : 1;
unsigned int reserved : 3;
unsigned int phys_addr : 20;
};
extern void ident_map_addr(void *addr, size_t len);
extern void ident_unmap_addr(void *addr, size_t len);

View file

@ -27,6 +27,7 @@ enum vga_color {
void vgatext_write_char(char c, enum vga_color color, uint8_t x, uint8_t y);
void vgatext_write_data(uint16_t data, uint16_t index);
void vgatext_write_buf(const uint16_t *buffer);
void vgatext_cur_mov(uint8_t x, uint8_t y);
void vgatext_cur_resize(uint8_t start, uint8_t end);
void vgatext_cur_visible(bool visible);

View file

@ -1,6 +1,13 @@
#pragma once
#include <stddef.h>
extern int memory_lock(void);
extern int memory_unlock(void);
extern void *memory_alloc_page(int);
extern int memory_free_page(void* ,int);
extern void *malloc(size_t size);
extern void free(void *ptr);
extern void *calloc(size_t nobj, size_t size);
extern void *realloc(void *p, size_t size);

View file

@ -36,6 +36,11 @@ extern struct Time get_utctime(void);
*/
extern struct Time get_localtime(void);
/**
* Return the time on the system clock
*/
extern size_t get_systemtime(void);
/**
* Converts the time into a string format
* @param time the current time

View file

@ -1,3 +1,5 @@
#include "arch/i686/mboot.h"
#include "arch/i686/paging.h"
#include <panic.h>
#include <string.h>
#include <stdbool.h>
@ -73,20 +75,25 @@ static void read_s5_addr(void) {
}
}
void acpi_init(void *ptr) {
struct RootSystemDescriptionPointer *rsdp = ptr;
void acpi_init(void) {
struct BootTag *tag;
if (!get_boot_tag(ID_RSDP, &tag)) {
panic("Could not find RSDP");
}
struct RootSystemDescriptionPointer *rsdp = tag->data.rsdp;
if (!checksum((uint8_t*) rsdp, sizeof(struct RootSystemDescriptionPointer))) {
panic("RSDP checksum failed to validate");
}
uintptr_t rsdt_ptr = rsdp->rsdt_address;
rsdt = (void *) rsdt_ptr;
ident_map_addr(rsdt, 1000);
if (!checksum((uint8_t*) &rsdt->header, rsdt->header.length)) {
panic("RSDT checksum failed to validate");
}
return;
fadt = find_fadt();
if (fadt == NULL) {
panic("Could not find FADT");
}
@ -98,6 +105,7 @@ void acpi_init(void *ptr) {
read_s5_addr();
outb(fadt->smi_command_port,fadt->acpi_enable);
panic("C");
}
void acpi_poweroff(void) {

View file

@ -1,4 +1,5 @@
#include <sys.h>
#include "print.h"
#include <arch.h>
#include <arch/i686/asm.h>
#include <arch/i686/acpi.h>
#include <arch/i686/drivers/rtc.h>
@ -14,9 +15,7 @@ void arch_init(void *boot_info) {
pic_remap();
load_boot_info(boot_info);
/* havent refactored to work with paging yet */
// acpi_init();
acpi_init();
// memory_init();
ps2ctrl_init();

View file

@ -1,6 +1,6 @@
#include "time.h"
#include <stdint.h>
#include <sys.h>
#include <arch.h>
#include <arch/i686/drivers/rtc.h>
#include <arch/i686/asm.h>
@ -55,10 +55,9 @@ static void update_localtime(void) {
localtime = time;
// if tz is UTC, we dont need to do anythin
if (last_timezone == UTC) {
cur_localtime = localtime;
return;
}
if (last_timezone == UTC) return;
localtime.hour += last_timezone;
// check if day rolled over
change = localtime.hour < 0 ? -1 : localtime.hour >= 24 ? 1 : 0;
@ -109,8 +108,6 @@ year:
localtime.year -= 1900;
cur_localtime = localtime;
}
void rtc_update(void) {
@ -137,6 +134,7 @@ void rtc_update(void) {
update_localtime();
cur_time = time;
cur_localtime = localtime;
}
struct Time rtc_utctime(void) {
@ -147,6 +145,7 @@ struct Time rtc_localtime(enum Timezone tz) {
if (tz != last_timezone) {
last_timezone = tz;
update_localtime();
cur_localtime = localtime;
}
return cur_localtime;
}

View file

@ -21,7 +21,7 @@ void vgatext_write_buf(const uint16_t *src) {
}
void vgatext_cur_mov(uint8_t x, uint8_t y) {
; const uint16_t pos = y * VGA_TEXT_W + x;
const uint16_t pos = y * VGA_TEXT_W + x;
outb(0x3D4, 0x0F);
outb(0x3D5, (uint8_t) (pos & 0xFF));

View file

@ -2,7 +2,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <sys.h>
#include <arch.h>
#include <print.h>
#include <panic.h>
#include <arch/i686/pic.h>
@ -10,8 +10,7 @@
#include <time.h>
#include <drivers/ps2kb.h>
#include <drivers/ps2mouse.h>
#include "tty/term.h"
#include <arch/i686/asm.h>
struct IdtEntry {
uint16_t isr_low;
@ -41,31 +40,18 @@ enum IDTFlags {
IDT_FLAG_PRESENT = 0x80,
};
#define WIDTH 30
static char buf[WIDTH];
static int timer = -1;
static size_t timer = 0;
void idt_pic_eoi(uint8_t exception) {
pic_eoi(exception - PIC_REMAP_OFFSET);
}
void idt_pic_timer(void) {
timer += 1;
if (timer % 20 != 0) return;
}
uint32_t state = term_save();
term_setfg(VGA_LIGHT_GREEN);
term_setpos(TERM_W - WIDTH - 1, 0);
for (size_t i = 0; i < WIDTH; i++) putchar(' ');
term_setpos(TERM_W - WIDTH - 1, 0);
struct Time t = get_localtime();
timetostr(&t, "%a %b %d %Y %H:%M:%S", buf, WIDTH);
printk("%s", buf);
term_load(state);
size_t get_systemtime(void) {
return timer;
}
void idt_pic_keyboard(void) {

View file

@ -1,3 +1,4 @@
#include "print.h"
#include <panic.h>
#include <string.h>
#include <arch/i686/mboot.h>
@ -11,12 +12,13 @@ static void read_cmdline(struct BootTag *tag, char *data, uint8_t len) {
panic("multiboot2 cmd line to long\nmax is %d but was provided %d\n",
CMDLINE_MAX, len);
memcpy(tag->data.cmdline, data, len);
tag->data.cmdline[len] = '\0';
info.tags[ID_CMDLINE] = *tag;
}
static void read_memorymap(struct BootTag *tag, uint32_t *data) {
tag->data.memory_map = (struct MemoryMap *) data;
info.tags[iD_MEMORYMAP] = *tag;
info.tags[ID_MEMORYMAP] = *tag;
}
static void read_rsdp(struct BootTag *tag, char *data) {
@ -36,7 +38,7 @@ static uint32_t *read_tag(uint32_t *data) {
case ID_CMDLINE:
read_cmdline(&tag, (char *)(data + 2), data_len);
break;
case iD_MEMORYMAP:
case ID_MEMORYMAP:
read_memorymap(&tag, data + 2);
break;
case ID_RSDP:

View file

@ -1,7 +1,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <sys.h>
#include <arch.h>
#include <panic.h>
#include <arch/i686/memory.h>
#include <arch/i686/mboot.h>
@ -126,7 +126,7 @@ void memory_init(void) {
kernel_end_addr = (uintptr_t) &kernel_end;
struct BootTag *tag;
if (!get_boot_tag(iD_MEMORYMAP, &tag)) {
if (!get_boot_tag(ID_MEMORYMAP, &tag)) {
panic("No multiboot memory map found");
}

View file

@ -1,4 +1,5 @@
global page_directory
global page_tables
global paging_init
global paging_finish
global KERNEL_MAPPING
@ -6,12 +7,14 @@ global KERNEL_MAPPING
KERNEL_MAPPING equ 0xC0000000
VGABUF equ 0x000B8000
%define mapped(addr) addr - KERNEL_MAPPING
section .bss
align 4096
page_directory:
resb 4096
page_table1:
resb 4096
resb 1024 * 4
page_tables:
resb 1024 * 1024 * 4
section .bootstrap.text
align 8
@ -20,14 +23,14 @@ paging_init:
extern kernel_end
paging_load:
mov edi, page_table1 - KERNEL_MAPPING
mov edi, mapped(page_tables)
mov esi, 0
mov ecx, 1023
paging_cmp:
cmp esi, kernel_start
jl paging_add
cmp esi, kernel_end - KERNEL_MAPPING
cmp esi, mapped(kernel_end)
jge paging_map
mov edx, esi
@ -40,13 +43,27 @@ paging_add:
loop paging_cmp
paging_map:
mov dword [page_table1 - KERNEL_MAPPING + 1023 * 4], VGABUF | 0x003
mov dword [page_directory - KERNEL_MAPPING + 0], page_table1 - KERNEL_MAPPING + 0x003
mov dword [page_directory - KERNEL_MAPPING + 768 * 4], page_table1 - KERNEL_MAPPING + 0x003
mov ecx, page_directory - KERNEL_MAPPING
lea eax, mapped(page_directory)
push eax
extern setup_pgdir
call mapped(setup_pgdir)
add esp, 0x04
; map VGA buffer
mov dword [mapped(page_tables) + 1023 * 4], VGABUF + 0x003
; map 8MB for the kernel
mov dword [mapped(page_directory) + 0 * 4], mapped(page_tables) + 0x003
mov dword [mapped(page_directory) + 1 * 4], mapped(page_tables) + 0x400000000 + 0x003
mov dword [mapped(page_directory) + 768 * 4], mapped(page_tables) + 0x003
mov dword [mapped(page_directory) + 769 * 4], mapped(page_tables) + 0x400000000 + 0x003
; tell the MMU where the page dir is
mov ecx, mapped(page_directory)
mov cr3, ecx
; finally init paging
mov ecx, cr0
or ecx, 0x80010000
mov cr0, ecx
@ -56,7 +73,9 @@ paging_map:
section .text
align 8
paging_finish:
mov dword [page_directory], 0
; remove the 8MB ident mapping
mov dword [page_directory + 0 * 4], 0
mov dword [page_directory + 1 * 4], 0
mov ecx, cr3
mov cr3, ecx
ret

View file

@ -0,0 +1,71 @@
#include "panic.h"
#include "arch.h"
#include <arch/i686/paging.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <print.h>
extern struct page_directory_t page_directory[1024];
extern struct page_table_t page_tables[1024][1024];
// static uintptr_t KERNEL_MAPPING = 0xC0000000;
void setup_pgdir(struct page_directory_t pgdir[1024]) {
for(int i = 0; i < 1024; i++) {
pgdir[i].present = 0;
pgdir[i].rw_flag = 1;
pgdir[i].access_lvl = 0;
}
}
void paging_ident(struct page_table_t tbl[1024]) {
size_t size = 1024;
for(size_t i = 0; i < size; i++) {
tbl[i].rw_flag = 1;
tbl[i].access_lvl = 0;
tbl[i].phys_addr = i;
tbl[i].present = 1;
}
}
void map_page(struct page_table_t tbl[1024], void *addr) {
uintptr_t ptr = (uintptr_t) addr;
ptr &= 0xfffff000;
ptr >>= 16;
for(size_t i = 0; i < 4096; i++) {
tbl[i].rw_flag = 1;
tbl[i].access_lvl = 0;
tbl[i].phys_addr = ptr / 4096 + i;
tbl[i].present = 1;
}
}
void unmap_page(struct page_table_t tbl[1024]) {
for(size_t i = 0; i < 4096; i++) {
tbl[i].rw_flag = 1;
tbl[i].access_lvl = 0;
tbl[i].phys_addr = 0;
tbl[i].present = 0;
}
}
void ident_map_addr(void *addr, size_t len) {
uintptr_t ptr = (uintptr_t) addr;
int i = ptr / 0x400000;
// int c = len / 0x1000 + (len % 0x1000 ? 1 : 0);
// for (; c > 0; c--, i++) {
// paging_ident(page_tables[i]);
// }
paging_ident(page_tables[i]);
}
void ident_unmap_addr(void *addr, size_t len) {
uintptr_t ptr = (uintptr_t) addr;
int i = ptr / 0x1000;
int c = len / 0x1000 + (len % 0x1000 ? 1 : 0);
for (; c > 0; c--, i++) {
page_tables[i / 1024][i % 1024].present = 0;
page_tables[i / 1024][i % 1024].rw_flag = 1;
page_tables[i / 1024][i % 1024].access_lvl = 0;
}
}

View file

@ -1,4 +1,4 @@
#include <sys.h>
#include <arch.h>
#include <print.h>
#include <arch/i686/pic.h>
#include <arch/i686/asm.h>

View file

@ -1,7 +1,6 @@
global start
bits 32
; create the multiboot header
section .bootstrap.data
align 8
@ -17,7 +16,7 @@ mb_end:
; create the stack for bootstrapping
section .bootstrap.stack
section .bootstrap.bss
align 16
bootstrap_stack_start:
resb 1024 ; 1 KiB
@ -25,7 +24,7 @@ bootstrap_stack_end:
; create the stack for the kernel
section .stack
section .bss
align 16
stack_start:
resb 16384 ; 16 KiB
@ -46,6 +45,7 @@ start:
jmp near load_kernel
; initalize kernel after it has been loaded in higher half
section .text
align 8
@ -65,13 +65,11 @@ load_kernel:
; initalize the FPU
finit
; push multiboot header
; start kernel
sti
extern KERNEL_MAPPING
add ebx, KERNEL_MAPPING
push ebx
; start kernel
sti
call kernel_main
extern kernel_main

View file

@ -3,12 +3,15 @@
#include <drivers/ps2mouse.h>
#include <panic.h>
#include <print.h>
#include <sys.h>
#include <stddef.h>
#include <arch.h>
#include <math.h>
#include <stdint.h>
#include <stdlib.h>
#include <term.h>
#define WIDTH 30
static char buf[WIDTH];
static double x = 0, y = 0;
void kernel_main(void *boot_info) {
@ -23,7 +26,6 @@ void kernel_main(void *boot_info) {
while(1) {
arch_wait_int();
arch_update();
struct Keycode code = ps2kb_get();
if(code.key != KEY_NONE) {
@ -52,6 +54,20 @@ void kernel_main(void *boot_info) {
printk(" x%d y%d\n", (int)x, (int)y);
}
uint32_t state = term_save();
term_setfg(VGA_LIGHT_GREEN);
term_setpos(TERM_W - WIDTH - 1, 0);
for (size_t i = 0; i < WIDTH; i++) putchar(' ');
term_setpos(TERM_W - WIDTH - 1, 0);
struct Time t = get_localtime();
timetostr(&t, "%a %b %d %Y %H:%M:%S", buf, WIDTH);
printk("%s", buf);
term_load(state);
arch_update();
term_flush();
}
}

View file

@ -1,10 +1,15 @@
#include <sys.h>
#include <arch.h>
#include <stdarg.h>
#include <stdlib.h>
#include <panic.h>
#include <print.h>
#include <term.h>
struct stackframe {
struct stackframe* ebp;
uint32_t eip;
};
__attribute__((noreturn))
void _panic_impl(char* msg, int line, char* file, ...) {
arch_disable_int();

View file

@ -2,7 +2,7 @@
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <sys.h>
#include <arch.h>
#include <print.h>
#include "drivers/vga.h"