FORKgit add .git add .!

This commit is contained in:
2026-07-08 19:11:39 -05:00
parent e42ee8eb85
commit ec3cbb4794
10 changed files with 146 additions and 105 deletions

View File

@@ -9,20 +9,6 @@ extern uint8_t __kernel_end;
extern uint32_t page_directory[1024];
#define PAGE_SIZE 4096
#define MAX_RAM 0xFFFFFFFF // 4GB
#define BITMAP_SIZE ((MAX_RAM / PAGE_SIZE) / 8)
#define PAGE_TABLES 0xFFC00000
#define PAGE_DIRECTORY 0xFFFFF000
#define TEMP_MAPPING_VADDR 0xDFFF0000
#define TEMP_COPY_SRC 0xDFFE0000 // Safely 1 page down
#define TEMP_COPY_DST 0xDFFD0000
#define USR_PAGE 0x07
#define SUP_PAGE 0x03
static uint32_t max_address = 0;
static uint32_t total_available_memory = 0;
static uint8_t memory_bitmap[BITMAP_SIZE];
@@ -120,8 +106,8 @@ void p_free_frame(void* addr) {
void map_page(uint32_t vaddr, uint32_t paddr, uint32_t flags) {
uint32_t pde_entry = vaddr >> 22;
uint32_t pte_entry = (vaddr >> 12) & 0x3FF;
uint32_t* pd = (uint32_t*)PAGE_DIRECTORY;
uint32_t* tablev = (uint32_t*)(PAGE_TABLES + (pde_entry * PAGE_SIZE));
uint32_t* pd = (uint32_t*)CUR_PAGE_DIRECTORY;
uint32_t* tablev = (uint32_t*)(CUR_PAGE_TABLES + (pde_entry * PAGE_SIZE));
if ((pd[pde_entry] & PAGE_PRESENT) == 0) {
uint32_t new_table = (uint32_t)p_alloc_frame();
@@ -136,6 +122,35 @@ void map_page(uint32_t vaddr, uint32_t paddr, uint32_t flags) {
flush_tlb();
}
void unmap_page(uint32_t vaddr) {
uint32_t pde_entry = vaddr >> 22;
uint32_t pte_entry = (vaddr >> 12) & 0x3FF;
uint32_t* tablev = (uint32_t*)(CUR_PAGE_TABLES + (pde_entry * PAGE_SIZE));
tablev[pte_entry] = 0;
flush_tlb();
}
int is_cow(uint32_t vaddr) {
uint32_t pde_entry = vaddr >> 22;
uint32_t pte_entry = (vaddr >> 12) & 0x3FF;
uint32_t* pd = (uint32_t*)CUR_PAGE_DIRECTORY;
uint32_t* tablev = (uint32_t*)(CUR_PAGE_TABLES + (pde_entry * PAGE_SIZE));
if (!(pd[pde_entry] & PAGE_PRESENT)) {
return 0;
}
if (tablev[pte_entry] & PAGE_WRITABLE) {
return 0;
}
if (!(tablev[pte_entry] & PAGE_COW)) {
return 0;
}
return 1;
}
void init_pmm(void* mmap_base, uint32_t mmap_limit) {
for (int i = 0; i < BITMAP_SIZE; i++) {
memory_bitmap[i] = 0xFF;
@@ -166,103 +181,90 @@ uint32_t total_free_memory() {
return total_available_memory;
}
void* create_task_pd() {
uint32_t pd_address = (uint32_t)p_alloc_frame();
if (pd_address == 0) {
return 0;
void* create_new_pd() {
uint32_t task_pd_addr = (uint32_t)p_alloc_frame();
if (task_pd_addr == 0) {
return NULL; // outta mem
}
map_page(TEMP_MAPPING_VADDR, pd_address, PAGE_PRESENT | PAGE_WRITABLE);
map_page(TEMP_TASKPD_VADDR, task_pd_addr, PAGE_PRESENT | PAGE_WRITABLE);
uint32_t* task_pd = (uint32_t*)TEMP_MAPPING_VADDR;
uint32_t* kernel_pd = (uint32_t*)PAGE_DIRECTORY;
uint32_t* task_pd = (uint32_t*)TEMP_TASKPD_VADDR;
uint32_t* parent_pd = (uint32_t*)CUR_PAGE_DIRECTORY;
for(int i = 768; i < 1023; i++) {
task_pd[i] = parent_pd[i];
}
task_pd[1023] = task_pd_addr | PAGE_PRESENT | PAGE_WRITABLE;
for(int i = 0; i < 768; i++) {
task_pd[i] = 0;
}
for(int i = 768; i < 1023; i++) {
task_pd[i] = kernel_pd[i];
}
task_pd[1023] = (uint32_t)pd_address | PAGE_PRESENT | PAGE_WRITABLE;
unmap_page(TEMP_TASKPD_VADDR);
uint32_t pde = TEMP_MAPPING_VADDR >> 22;
uint32_t pte = (TEMP_MAPPING_VADDR >> 12) & 0x3FF;
uint32_t* kernel_pt = (uint32_t*)(PAGE_TABLES + (pde * PAGE_SIZE));
kernel_pt[pte] = 0;
return (void*)pd_address;
return (void*)task_pd_addr;
}
void* clone_task_pd() {
uint32_t child_pd_phys = (uint32_t)p_alloc_frame();
if (child_pd_phys == 0) return NULL;
map_page(TEMP_MAPPING_VADDR, child_pd_phys, PAGE_PRESENT | PAGE_WRITABLE);
uint32_t* child_pd = (uint32_t*)TEMP_MAPPING_VADDR;
uint32_t* parent_pd = (uint32_t*)PAGE_DIRECTORY;
for (int i = 768; i < 1023; i++) {
child_pd[i] = parent_pd[i];
void* clone_current_pd() {
uint32_t task_pd_addr = (uint32_t)p_alloc_frame();
if (task_pd_addr == 0) {
return NULL; // outta mem
}
child_pd[1023] = child_pd_phys | PAGE_PRESENT | PAGE_WRITABLE;
map_page(TEMP_TASKPD_VADDR, task_pd_addr, PAGE_PRESENT | PAGE_WRITABLE);
for (int i = 0; i < 768; i++) {
child_pd[i] = 0;
uint32_t* task_pd = (uint32_t*)TEMP_TASKPD_VADDR;
uint32_t* parent_pd = (uint32_t*)CUR_PAGE_DIRECTORY;
for(int i = 768; i < 1023; i++) {
task_pd[i] = parent_pd[i];
}
task_pd[1023] = task_pd_addr | PAGE_PRESENT | PAGE_WRITABLE;
for(int i = 0; i < 768; i++) {
task_pd[i] = 0;
}
for (int i = 0; i < 768; i++) {
uint32_t pde = parent_pd[i];
if (!(pde & PAGE_PRESENT)) continue;
uint32_t child_pt_phys = (uint32_t)p_alloc_frame();
uint32_t task_pt = (uint32_t)p_alloc_frame();
task_pd[i] = task_pt | (pde & 0xFFF);
uint32_t parent_pt = pde & 0xFFFFF000;
child_pd[i] = child_pt_phys | (pde & 0xFFF);
map_page(TEMP_PT_DST, task_pt, PAGE_PRESENT | PAGE_WRITABLE);
map_page(TEMP_PT_SRC, parent_pt, PAGE_PRESENT | PAGE_WRITABLE);
map_page(TEMP_COPY_SRC, pde & ~(PAGE_SIZE - 1), PAGE_PRESENT | PAGE_WRITABLE);
map_page(TEMP_COPY_DST, child_pt_phys, PAGE_PRESENT | PAGE_WRITABLE);
flush_tlb();
uint32_t* pt_dst = (uint32_t*)TEMP_PT_DST;
uint32_t* pt_src = (uint32_t*)TEMP_PT_SRC;
uint32_t* src_pt = (uint32_t*)TEMP_COPY_SRC;
uint32_t* dst_pt = (uint32_t*)TEMP_COPY_DST;
for(int j = 0; j < 1024; j++) {
uint32_t pte_src = pt_src[j];
if (!(pte_src & PAGE_PRESENT)) continue;
for (int j = 0; j < 1024; j++) {
uint32_t pte = src_pt[j];
if (!(pte & PAGE_PRESENT)) {
dst_pt[j] = 0;
if (!(pte_src & PAGE_WRITABLE)) {
pt_dst[j] = pt_src[j];
continue;
}
uint32_t child_frame_phys = (uint32_t)p_alloc_frame();
dst_pt[j] = child_frame_phys | (pte & 0xFFF);
// the src page is writable, mark the pte src as read only and COW, then copy to dst pte
pt_src[j] &= ~(PAGE_WRITABLE);
pt_src[j] |= PAGE_COW;
flush_tlb(); // huge performance hit here, and probably everywhere else too where we aren't switching cr3s
uint32_t parent_data_phys = pte & ~(PAGE_SIZE - 1);
map_page(TEMP_COPY_SRC, parent_data_phys, PAGE_PRESENT | PAGE_WRITABLE);
map_page(TEMP_COPY_DST, child_frame_phys, PAGE_PRESENT | PAGE_WRITABLE);
flush_tlb();
memcpy((void*)TEMP_COPY_DST, (void*)TEMP_COPY_SRC, PAGE_SIZE);
map_page(TEMP_COPY_SRC, pde & ~(PAGE_SIZE - 1), PAGE_PRESENT | PAGE_WRITABLE);
map_page(TEMP_COPY_DST, child_pt_phys, PAGE_PRESENT | PAGE_WRITABLE);
flush_tlb();
pt_dst[j] = pt_src[j];
}
unmap_page(TEMP_PT_DST);
unmap_page(TEMP_PT_SRC);
}
uint32_t pde_main = TEMP_MAPPING_VADDR >> 22;
uint32_t* pt_main = (uint32_t*)(PAGE_TABLES + (pde_main * PAGE_SIZE));
pt_main[(TEMP_MAPPING_VADDR >> 12) & 0x3FF] = 0;
unmap_page(TEMP_TASKPD_VADDR);
uint32_t pde_src = TEMP_COPY_SRC >> 22;
uint32_t* pt_src = (uint32_t*)(PAGE_TABLES + (pde_src * PAGE_SIZE));
pt_src[(TEMP_COPY_SRC >> 12) & 0x3FF] = 0;
uint32_t pde_dst = TEMP_COPY_DST >> 22;
uint32_t* pt_dst = (uint32_t*)(PAGE_TABLES + (pde_dst * PAGE_SIZE));
pt_dst[(TEMP_COPY_DST >> 12) & 0x3FF] = 0;
flush_tlb();
return (void*)child_pd_phys;
return (void*)task_pd_addr;
}

View File

@@ -3,12 +3,24 @@
#include <stdint.h>
#define PAGE_PRESENT 0x1
#define PAGE_WRITABLE 0x2
#define PAGE_USER 0x4
#define PAGE_PRESENT (1 << 0)
#define PAGE_WRITABLE (1 << 1)
#define PAGE_USER (1 << 2)
#define PAGE_COW (1 << 9)
#define TEMP_KERNPD_VADDR 0xDFF90000
#define TEMP_TASKPD_VADDR 0xDFFA0000
#define TEMP_PT_SRC 0xDFFB0000
#define TEMP_PT_DST 0xDFFC0000
#define PAGE_SIZE 4096
#define MAX_RAM 0xFFFFFFFF // 4GB
#define BITMAP_SIZE ((MAX_RAM / PAGE_SIZE) / 8)
#define CUR_PAGE_DIRECTORY 0xFFFFF000
#define CUR_PAGE_TABLES 0xFFC00000
typedef struct __attribute__((packed)) {
uint32_t addr;
} mem_page_t;
@@ -20,10 +32,13 @@ void* p_alloc_frame();
uint32_t total_free_memory();
void* create_task_pd();
void* clone_task_pd();
void* create_new_pd();
void* clone_current_pd();
int is_cow(uint32_t vaddr);
void map_page(uint32_t vaddr, uint32_t paddr, uint32_t flags);
void unmap_page(uint32_t vaddr);
void load_pd(void* paddr);