Skip to content

Commit

Permalink
~ | VMM's debug continues
Browse files Browse the repository at this point in the history
  • Loading branch information
BolvicBolvicovic committed Sep 9, 2024
1 parent 7488906 commit ba72840
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 62 deletions.
6 changes: 3 additions & 3 deletions memory/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ MEM = memory.a
PMM_SRC = pmm/pmm.c
PMM_OBJ = pmm/pmm.o

VMM_SRC = vmm/vmm.c vmm/paging.s
VMM_OBJ = vmm/vmm.o vmm/paging.o
VMM_SRC = vmm/vmm.c vmm/paging.s vmm/pdt.c
VMM_OBJ = vmm/vmm.o vmm/paging.o vmm/pdt.o

AR = ../gcc_kfs/bin/i386-elf-ar rcs
CC = ../gcc_kfs/bin/i386-elf-gcc
FLAGS = -ffreestanding \
-g \
-O2 \
-O0 \
-nostdlib

all: $(MEM)
Expand Down
6 changes: 3 additions & 3 deletions memory/pmm/pmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ uint32_t _memory_used_blocks = 0;
uint32_t _memory_max_blocks = 0;
uint32_t* _memory_map = NULL;

inline void mmap_set(int bit) {
void mmap_set(int bit) {
_memory_map[bit / 32] |= (1 << (bit % 32));
}

inline void mmap_unset(int bit) {
void mmap_unset(int bit) {
_memory_map[bit / 32] &= ~(1 << (bit % 32));
}

inline int mmap_test(int bit) {
int mmap_test(int bit) {
return _memory_map[bit / 32] & (1 << (bit % 32));
}

Expand Down
3 changes: 2 additions & 1 deletion memory/vmm/paging.s
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ enable_paging:
ret

switch_dir:
mov %eax, %cr3
movl 4(%esp), %eax
movl %eax, %cr3
ret

flush_tlb_entry:
Expand Down
57 changes: 57 additions & 0 deletions memory/vmm/pdt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#include "pdt.h"

inline void pt_entry_add_attrib (pt_entry* e, uint32_t attrib) {
*e |= attrib;
}

inline void pt_entry_del_attrib (pt_entry* e, uint32_t attrib) {
*e &= ~attrib;
}

inline void pt_entry_set_frame (pt_entry* e, uint32_t addr) {
*e = (*e & ~I86_PTE_FRAME) | addr;
}

inline int pt_entry_is_present (pt_entry e) {
return e & I86_PTE_PRESENT;
}

inline int pt_entry_is_writable (pt_entry e) {
return e & I86_PTE_WRITABLE;
}

inline uint32_t pt_entry_pfn (pt_entry e) {
return e & I86_PTE_FRAME;
}

inline void pd_entry_add_attrib (pd_entry* e, uint32_t attrib) {
*e |= attrib;
}

inline void pd_entry_del_attrib (pd_entry* e, uint32_t attrib) {
*e &= ~attrib;
}

inline void pd_entry_set_frame (pd_entry* e, uint32_t addr) {
*e = (*e & ~I86_PDE_FRAME) | addr;
}

inline int pd_entry_is_present (pd_entry e) {
return e & I86_PDE_PRESENT;
}

inline int pd_entry_is_writable (pd_entry e) {
return e & I86_PDE_WRITABLE;
}

inline uint32_t pd_entry_pfn (pd_entry e) {
return e & I86_PDE_FRAME;
}

inline int pd_entry_is_user (pd_entry e) {
return e & I86_PDE_USER;
}

inline int pd_entry_is_4mb (pd_entry e) {
return e & I86_PDE_4MB;
}
59 changes: 43 additions & 16 deletions memory/vmm/pdt.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,6 @@ enum PAGE_PTE_FLAGS {

typedef uint32_t pt_entry;

#define PT_ENTRY_ADD_ATTRIB(ENTRY, ATTRIB) ((ENTRY) = (uint32_t)(ENTRY) | (1 << ATTRIB))
#define PT_ENTRY_DEL_ATTRIB(ENTRY, ATTRIB) ((ENTRY) = (uint32_t)(ENTRY) & ~(1 << ATTRIB))
#define PT_ENTRY_SET_FRAME(ENTRY, PHYS_ADDR) ((ENTRY) = (void *)(((uint32_t)ENTRY & ~I86_PTE_FRAME) | ((uint32_t)PHYS_ADDR & I86_PTE_FRAME)))
#define PT_ENTRY_IS_PRESENT(ENTRY) ((uint32_t)(ENTRY) & I86_PTE_PRESENT)
#define PT_ENTRY_IS_WRITABLE(ENTRY) ((uint32_t)(ENTRY) & I86_PTE_WRITABLE)
#define PT_ENTRY_PFN(ENTRY) ((uint32_t)(ENTRY) & I86_PTE_FRAME)

// PAGE DIRECTORY ENTRY

enum PAGE_PDE_FLAGS {
Expand All @@ -46,15 +39,49 @@ enum PAGE_PDE_FLAGS {
};

typedef uint32_t pd_entry;
//! sets a flag in the page table entry
extern void pd_entry_add_attrib (pd_entry* e, uint32_t attrib);

//! clears a flag in the page table entry
extern void pd_entry_del_attrib (pd_entry* e, uint32_t attrib);

//! sets a frame to page table entry
extern void pd_entry_set_frame (pd_entry*, uint32_t);

//! test if page is present
extern int pd_entry_is_present (pd_entry e);

//! test if directory is user mode
extern int pd_entry_is_user (pd_entry);

//! test if directory contains 4mb pages
extern int pd_entry_is_4mb (pd_entry);

//! test if page is writable
extern int pd_entry_is_writable (pd_entry e);

//! get page table entry frame address
extern uint32_t pd_entry_pfn (pd_entry e);

//! enable global pages
extern void pd_entry_enable_global (pd_entry e);

//! sets a flag in the page table entry
extern void pt_entry_add_attrib (pt_entry* e, uint32_t attrib);

//! clears a flag in the page table entry
extern void pt_entry_del_attrib (pt_entry* e, uint32_t attrib);

//! sets a frame to page table entry
extern void pt_entry_set_frame (pt_entry*, uint32_t);

//! test if page is present
extern int pt_entry_is_present (pt_entry e);

//! test if page is writable
extern int pt_entry_is_writable (pt_entry e);

#define PD_ENTRY_ADD_ATTRIB(ENTRY, ATTRIB) ((ENTRY) = (uint32_t)(ENTRY) | (1 << ATTRIB))
#define PD_ENTRY_DEL_ATTRIB(ENTRY, ATTRIB) ((ENTRY) = (uint32_t)(ENTRY) & ~(1 << ATTRIB))
#define PD_ENTRY_SET_FRAME(ENTRY, PHYS_ADDR) ((ENTRY) = (void*)(((uint32_t)ENTRY & ~I86_PDE_FRAME) | ((uint32_t)PHYS_ADDR & I86_PDE_FRAME)))
#define PD_ENTRY_IS_PRESENT(ENTRY) ((uint32_t)(ENTRY) & I86_PDE_PRESENT)
#define PD_ENTRY_IS_USER(ENTRY) ((uint32_t)(ENTRY) & I86_PDE_USER)
#define PD_ENTRY_IS_4MB(ENTRY) ((uint32_t)(ENTRY) & I86_PDE_4MB)
#define PD_ENTRY_IS_WRITABLE(ENTRY) ((uint32_t)(ENTRY) & I86_PDE_WRITABLE)
#define PD_ENTRY_PFN(ENTRY) ((uint32_t)(ENTRY) & I86_PDE_FRAME)
#define PD_ENTRY_ENABLE_GLOBAL(ENTRY) ((ENTRY) = (uint32_t)(ENTRY) | I86_PDE_CPU_GLOBAL)
//! get page table entry frame address
extern uint32_t pt_entry_pfn (pt_entry e);

#endif
66 changes: 30 additions & 36 deletions memory/vmm/vmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,31 @@ extern void flush_tlb_entry(uint32_t addr);
int vmm_alloc_page(pt_entry* entry) {
void* p = pmm_alloc_block();
if (!p) return 0;
PT_ENTRY_SET_FRAME(entry, p);
PT_ENTRY_ADD_ATTRIB(entry, I86_PTE_PRESENT);
pt_entry_set_frame(entry, (uint32_t)p);
pt_entry_add_attrib(entry, I86_PTE_PRESENT);
return 1;
}

void vmm_free_page(pt_entry* entry) {
void* p = (void*)PT_ENTRY_PFN(entry);
void* p = (void*)pt_entry_pfn(entry);
if (p) pmm_free_block(p);
PT_ENTRY_ADD_ATTRIB(entry, I86_PTE_PRESENT);
pt_entry_add_attrib(entry, I86_PTE_PRESENT);
}

inline pt_entry* vmm_ptable_lookup_entry(p_table* p, uint32_t addr) {
pt_entry* vmm_ptable_lookup_entry(p_table* p, uint32_t addr) {
if (p) return &p->m_entries[PAGE_TAB_INDEX(addr)];
return 0;
}

inline pd_entry* vmm_pdir_lookup_entry(p_dir* p, uint32_t addr) {
pd_entry* vmm_pdir_lookup_entry(p_dir* p, uint32_t addr) {
if (p) return &p->m_entries[PAGE_TAB_INDEX(addr)];
return 0;
}

inline int vmm_switch_pdir(p_dir* dir) {
int vmm_switch_pdir(p_dir* dir) {
if (!dir) return 0;
_current_dir = dir;
asm volatile (
"mov %0, %%cr3\n"
:
: "r" (_cur_pdbr)
: "memory"
);
//switch_dir(_cur_pdbr);
return 1;
switch_dir(_cur_pdbr);
}

p_dir* vmm_get_dir() { return _current_dir; }
Expand All @@ -53,42 +46,43 @@ void vmm_map_page(void* phys, void* virt) {
if (!table) return;
memset(table, 0, sizeof(p_table));
pd_entry* entry = &page_dir->m_entries[PAGE_DIR_INDEX((uint32_t)virt)];
PD_ENTRY_ADD_ATTRIB(entry, I86_PDE_PRESENT);
PD_ENTRY_ADD_ATTRIB(entry, I86_PDE_WRITABLE);
PD_ENTRY_SET_FRAME(entry, (uint32_t)table);
pd_entry_add_attrib(entry, I86_PDE_PRESENT);
pd_entry_add_attrib(entry, I86_PDE_WRITABLE);
pd_entry_set_frame(entry, (uint32_t)table);
}
p_table* table = (p_table*)PAGE_PHYS_ADDR(e);
pt_entry* page = &table->m_entries[PAGE_TAB_INDEX((uint32_t)virt)];
PT_ENTRY_SET_FRAME(page, (uint32_t)phys);
PT_ENTRY_ADD_ATTRIB(page, I86_PTE_PRESENT);
pt_entry_set_frame(page, (uint32_t)phys);
pt_entry_add_attrib(page, I86_PTE_PRESENT);
}

void vmm_init() {
p_table* table = (p_table*)pmm_alloc_block();
if (!table) return;
p_table* table2 = (p_table*)pmm_alloc_block();
if (!table2) return;
memset(table, 0, sizeof(p_table));
memset(table, 0, sizeof(p_table));
memset(table2, 0, sizeof(p_table));
//! 1st 4mb are idenitity mapped
for (int i=0, frame=0x0, virt=0x00000000; i<1024; i++, frame+=4096, virt+=4096) {
for (int i=0, frame=0x0, virt=0x00000000; i<PAGES_PER_TABLE; i++, frame+=PAGE_SIZE, virt+=PAGE_SIZE) {

//! create a new page
pt_entry page=0;
pt_entry* page_addr = &page;
PT_ENTRY_ADD_ATTRIB(page_addr, I86_PTE_PRESENT);
PT_ENTRY_SET_FRAME (page_addr, frame);
pt_entry* page_addr = &page;
pt_entry_add_attrib(page_addr, I86_PTE_PRESENT);
pt_entry_set_frame (page_addr, frame);

//! ...and add it to the page table
table2->m_entries [PAGE_TAB_INDEX(virt) ] = page;
}
//! map 1mb to 3gb (where we are at)
for (int i=0, frame=0x100000, virt=0xc0000000; i<1024; i++, frame+=4096, virt+=4096) {
for (int i=0, frame=0x100000, virt=0xc0000000; i<PAGES_PER_TABLE; i++, frame+=PAGE_SIZE, virt+=PAGE_SIZE) {

//! create a new page
pt_entry page=0;
pt_entry* page_addr = &page;
PT_ENTRY_ADD_ATTRIB(page_addr, I86_PTE_PRESENT);
PT_ENTRY_SET_FRAME (page_addr, frame);
pt_entry* page_addr = &page;
pt_entry_add_attrib(page_addr, I86_PTE_PRESENT);
pt_entry_set_frame (page_addr, frame);

//! ...and add it to the page table
table->m_entries [PAGE_TAB_INDEX (virt) ] = page;
Expand All @@ -100,18 +94,18 @@ void vmm_init() {
//! clear directory table and set it as current
memset (dir, 0, sizeof (p_dir));
pd_entry* entry = &dir->m_entries [PAGE_DIR_INDEX (0xc0000000) ];
PD_ENTRY_ADD_ATTRIB (entry, I86_PDE_PRESENT);
PD_ENTRY_ADD_ATTRIB (entry, I86_PDE_WRITABLE);
PD_ENTRY_SET_FRAME (entry, table);
pd_entry_add_attrib (entry, I86_PDE_PRESENT);
pd_entry_add_attrib (entry, I86_PDE_WRITABLE);
pd_entry_set_frame (entry, (uint32_t)table);

pd_entry* entry2 = &dir->m_entries [PAGE_DIR_INDEX (0x00000000) ];
PD_ENTRY_ADD_ATTRIB (entry2, I86_PDE_PRESENT);
PD_ENTRY_ADD_ATTRIB (entry2, I86_PDE_WRITABLE);
PD_ENTRY_SET_FRAME (entry2, table2);
pd_entry_add_attrib (entry2, I86_PDE_PRESENT);
pd_entry_add_attrib (entry2, I86_PDE_WRITABLE);
pd_entry_set_frame (entry2, (uint32_t)table2);
//! store current PDBR
_cur_pdbr = (uint32_t) &dir->m_entries;

//! switch to our page directory
vmm_switch_pdir(dir);
enable_paging();
//enable_paging();
}
6 changes: 3 additions & 3 deletions memory/vmm/vmm.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
#define PAGES_PER_TABLE 1024
#define PAGES_PER_DIR 1024

#define PAGE_DIR_INDEX(ADDR) ((ADDR) >> 22) & 0x3FF
#define PAGE_TAB_INDEX(ADDR) ((ADDR) >> 12) & 0x3FF
#define PAGE_DIR_INDEX(ADDR) (((ADDR) >> 22) & 0x3FF)
#define PAGE_TAB_INDEX(ADDR) (((ADDR) >> 12) & 0x3FF)
#define PAGE_PHYS_ADDR(ADDR) ((*ADDR) & ~0xFFF)

#define PTABLE_ADDR_SPACE_SIZE 0x400000 // 4MB
#define DTABLE_ADDR_SPACE_SIZE 0x100000000 // 4GB

#define PAGE_SIZE 0x1000
#define PAGE_SIZE 0x1000 // 4KB

typedef struct {
pt_entry m_entries[PAGES_PER_TABLE];
Expand Down

0 comments on commit ba72840

Please sign in to comment.