Add: paging & test

This commit is contained in:
xamidev
2024-08-18 12:19:16 +02:00
parent 7e551dbfae
commit cd705589de
11 changed files with 256 additions and 2 deletions

View File

@@ -68,7 +68,7 @@ gdb kernel.elf
## Documentation
Two other documents are available to help you understand the project better. One is the User's Manual, labelled [USERS.md](USERS.md), and the other one is the Developer's Manual, labelled [DEVELOPERS.md](DEVELOPERS.md). They are full of useful resources around Blank OS. You'll learn how to use the system and how to contribute to it.
Two other documents are available to help you understand the project better. One is the User's Manual, labelled [USERS.md](docs/USERS.md), and the other one is the Developer's Manual, labelled [DEVELOPERS.md](docs/DEVELOPERS.md). They are full of useful resources around Blank OS. You'll learn how to use the system and how to contribute to it.
### Resources

View File

@@ -27,4 +27,6 @@ SECTIONS {
*(COMMON)
*(.bss)
}
end = .; _end = .; __end = .;
}

42
src/kernel/kheap.c Normal file
View File

@@ -0,0 +1,42 @@
#include "kheap.h"
#include "../libc/stdint.h"
extern uint32_t end;
uint32_t placement_address = (uint32_t)&end;
uint32_t kmalloc_int(uint32_t sz, int align, uint32_t *phys)
{
if (align == 1 && (placement_address & 0x00000FFF))
{
placement_address &= 0xFFFFF000;
placement_address += 0x1000;
}
if (phys)
{
*phys = placement_address;
}
uint32_t tmp = placement_address;
placement_address += sz;
return tmp;
}
uint32_t kmalloc_a(uint32_t sz)
{
return kmalloc_int(sz, 1, 0);
}
uint32_t kmalloc_p(uint32_t sz, uint32_t *phys)
{
return kmalloc_int(sz, 0, phys);
}
uint32_t kmalloc_ap(uint32_t sz, uint32_t *phys)
{
return kmalloc_int(sz, 1, phys);
}
uint32_t kmalloc(uint32_t sz)
{
return kmalloc_int(sz, 0, 0);
}

11
src/kernel/kheap.h Normal file
View File

@@ -0,0 +1,11 @@
#ifndef KHEAP_H
#define KHEAP_H
#include "../libc/stdint.h"
uint32_t kmalloc_a(uint32_t sz);
uint32_t kmalloc_p(uint32_t sz, uint32_t *phys);
uint32_t kmalloc_ap(uint32_t sz, uint32_t *phys);
uint32_t kmalloc(uint32_t sz);
#endif

View File

@@ -3,7 +3,7 @@
#include "gdt.h"
#include "idt.h"
#include "system.h"
//#include <stdarg.h>
#include "paging.h"
char* ascii_title =
"\n"
@@ -36,6 +36,12 @@ void kmain(unsigned int multiboot_info_address)
colorputs(ascii_title, 10);
colorputs(" by @xamidev - star the repo for a cookie!\n\n", 14);
init_paging();
printf("Hello, paging world!\n");
uint32_t *ptr = (uint32_t*)0xA0000000;
uint32_t do_page_fault = *ptr;
timer_install();
serial_printf(2, "%d\tinitialized timer handler", global_ticks);
keyboard_install();

150
src/kernel/paging.c Normal file
View File

@@ -0,0 +1,150 @@
#include "../libc/stdint.h"
#include "paging.h"
#include "../libc/stdio.h"
#include "system.h"
#include "kheap.h"
uint32_t *frames;
uint32_t nframes;
extern uint32_t placement_address;
#define INDEX_FROM_BIT(a) (a/(8*4))
#define OFFSET_FROM_BIT(a) (a%(8*4))
static void set_frame(uint32_t frame_addr)
{
uint32_t frame = frame_addr/0x1000;
uint32_t idx = INDEX_FROM_BIT(frame);
uint32_t off = OFFSET_FROM_BIT(frame);
frames[idx] |= (0x1 << off);
}
static void clear_frame(uint32_t frame_addr)
{
uint32_t frame = frame_addr/0x1000;
uint32_t idx = INDEX_FROM_BIT(frame);
uint32_t off = OFFSET_FROM_BIT(frame);
frames[idx] &= ~(0x1 << off);
}
/*
static uint32_t test_frame(uint32_t frame_addr)
{
uint32_t frame = frame_addr/0x1000;
uint32_t idx = INDEX_FROM_BIT(frame);
uint32_t off = OFFSET_FROM_BIT(frame);
return (frames[idx] & (0x1 << off));
}
*/
static uint32_t first_frame()
{
uint32_t i, j;
for (i=0; i<INDEX_FROM_BIT(nframes); i++)
{
if (frames[i] != 0xFFFFFFFF)
{
for (j=0; j<32; j++)
{
uint32_t toTest = 0x1 << j;
if (!(frames[i]&toTest))
{
return i*4*8+j;
}
}
}
}
return 0;
}
void alloc_frame(page_t *page, int is_kernel, int is_writeable)
{
if (page->frame != 0)
{
return;
} else {
uint32_t idx = first_frame();
if (idx == (uint32_t)-1)
{
panic();
}
set_frame(idx*0x1000);
page->present = 1;
page->rw = (is_writeable)?1:0;
page->user = (is_kernel)?0:1;
page->frame = idx;
}
}
void free_frame(page_t *page)
{
uint32_t frame;
if (!(frame=page->frame))
{
return;
} else {
clear_frame(frame);
page->frame = 0x0;
}
}
void init_paging()
{
uint32_t mem_end_page = 0x10000000;
nframes = mem_end_page / 0x1000;
frames = (uint32_t*)kmalloc(INDEX_FROM_BIT(nframes));
memset(frames, 0, INDEX_FROM_BIT(nframes));
page_directory_t* kernel_directory = (page_directory_t*)kmalloc_a(sizeof(page_directory_t));
memset(kernel_directory, 0, sizeof(page_directory_t));
//page_directory_t* current_directory = kernel_directory;
unsigned int i = 0;
while (i < placement_address)
{
alloc_frame(get_page(i, 1, kernel_directory), 0, 0);
i += 0x1000;
}
irq_install_handler(14, page_fault);
switch_page_directory(kernel_directory);
}
void switch_page_directory(page_directory_t *dir)
{
//page_directory_t* current_directory = dir;
asm volatile("mov %0, %%cr3":: "r"(&dir->tablesPhysical));
uint32_t cr0;
asm volatile("mov %%cr0, %0": "=r"(cr0));
cr0 |= 0x80000000;
asm volatile("mov %0, %%cr0":: "r"(cr0));
}
page_t *get_page(uint32_t address, int make, page_directory_t *dir)
{
address /= 0x1000;
uint32_t table_idx = address / 1024;
if (dir->tables[table_idx])
{
return &dir->tables[table_idx]->pages[address%1024];
} else if (make)
{
uint32_t tmp;
dir->tables[table_idx] = (page_table_t*)kmalloc_ap(sizeof(page_table_t), &tmp);
memset(dir->tables[table_idx], 0, 0x1000);
dir->tablesPhysical[table_idx] = tmp | 0x7;
return &dir->tables[table_idx]->pages[address%1024];
} else {
return 0;
}
return 0;
}
void page_fault()
{
puts("Page fault");
panic();
}

34
src/kernel/paging.h Normal file
View File

@@ -0,0 +1,34 @@
#ifndef PAGING_H
#define PAGING_H
#include "system.h"
#include "../libc/stdint.h"
typedef struct
{
uint32_t present : 1;
uint32_t rw : 1;
uint32_t user : 1;
uint32_t accessed : 1;
uint32_t dirty : 1;
uint32_t unused : 7;
uint32_t frame : 20;
} page_t;
typedef struct
{
page_t pages[1024];
} page_table_t;
typedef struct
{
page_table_t *tables[1024];
uint32_t tablesPhysical[1024];
uint32_t physicalAsddr;
} page_directory_t;
void init_paging();
void switch_page_directory(page_directory_t *new);
page_t *get_page(uint32_t address, int make, page_directory_t *dir);
void page_fault();
#endif

View File

@@ -1,4 +1,5 @@
#include "system.h"
#include "../libc/stdint.h"
void *memset(void *dest, char val, size_t count)
{
@@ -6,3 +7,8 @@ void *memset(void *dest, char val, size_t count)
for(; count != 0; count--) *temp++ = val;
return dest;
}
void panic()
{
for (;;);
}

View File

@@ -1,6 +1,8 @@
#ifndef SYSTEM_H
#define SYSTEM_H
#include "../libc/stdint.h"
typedef int size_t;
void *memset(void *dest, char val, size_t count);
@@ -13,6 +15,7 @@ struct regs
unsigned int eip, cs, eflags, useresp, ss;
};
void panic();
void isr_install();
void irq_install();
void irq_install_handler(int irq, void (*handler)(struct regs *r));