summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2024-04-22 23:55:16 +0200
committerAnton Kling <anton@kling.gg>2024-04-22 23:55:16 +0200
commit33663539c2bac856cf2abe79e815ad179dffecdf (patch)
tree62e3fff1b775d2b099a45850cee5ee20787cafea /kernel
parent821eb5ff9ed60d4b1c7a50ebf406f22bc0da9bd4 (diff)
MMU: Extra asserts to avoid future regressions
Diffstat (limited to 'kernel')
-rw-r--r--kernel/arch/i386/mmu.c32
-rw-r--r--kernel/elf.h98
-rw-r--r--kernel/includes/mmu.h2
3 files changed, 20 insertions, 112 deletions
diff --git a/kernel/arch/i386/mmu.c b/kernel/arch/i386/mmu.c
index 6fd00b6..9a00f52 100644
--- a/kernel/arch/i386/mmu.c
+++ b/kernel/arch/i386/mmu.c
@@ -115,7 +115,7 @@ void mmu_free_pages(void *a, u32 n) {
for (; n > 0; n--) {
Page *p = get_page(a, NULL, PAGE_NO_ALLOCATE, 0);
p->present = 0;
- write_to_frame(p->frame * 0x1000, 0);
+ (void)write_to_frame(p->frame * 0x1000, 0);
a += 0x1000;
}
}
@@ -141,9 +141,14 @@ int get_free_frame(u32 *frame) {
return 0;
}
-void write_to_frame(u32 frame_address, u8 on) {
+int write_to_frame(u32 frame_address, u8 on) {
u32 frame = frame_address / 0x1000;
if (on) {
+ int frame_is_used = (0 != (tmp_small_frames[INDEX_FROM_BIT(frame)] &
+ ((u32)0x1 << OFFSET_FROM_BIT(frame))));
+ if (frame_is_used) {
+ return 0;
+ }
num_allocated_frames++;
tmp_small_frames[INDEX_FROM_BIT(frame)] |=
((u32)0x1 << OFFSET_FROM_BIT(frame));
@@ -153,6 +158,7 @@ void write_to_frame(u32 frame_address, u8 on) {
tmp_small_frames[INDEX_FROM_BIT(frame)] &=
~((u32)0x1 << OFFSET_FROM_BIT(frame));
}
+ return 1;
}
PageDirectory *get_active_pagedirectory(void) {
@@ -176,7 +182,7 @@ PageTable *clone_table(u32 src_index, PageDirectory *src_directory,
kmalloc_align_free(new_table, sizeof(PageTable));
return NULL;
}
- write_to_frame(frame_address * 0x1000, 1);
+ assert(write_to_frame(frame_address * 0x1000, 1));
new_table->pages[i].frame = frame_address;
new_table->pages[i].present |= src->pages[i].present;
@@ -369,7 +375,7 @@ void *mmu_map_user_frames(void *const ptr, size_t s) {
p->user = !is_kernel;
p->frame = (uintptr_t)(ptr + i * 0x1000) / 0x1000;
kprintf("mapped user frame: %x\n", p->frame);
- write_to_frame((uintptr_t)ptr + i * 0x1000, 1);
+ (void)write_to_frame((uintptr_t)ptr + i * 0x1000, 1);
}
return r;
}
@@ -386,7 +392,7 @@ void *mmu_map_frames(void *const ptr, size_t s) {
p->rw = rw;
p->user = !is_kernel;
p->frame = (uintptr_t)(ptr + i * 0x1000) / 0x1000;
- write_to_frame((uintptr_t)ptr + i * 0x1000, 1);
+ (void)write_to_frame((uintptr_t)ptr + i * 0x1000, 1);
}
return r;
}
@@ -401,7 +407,7 @@ int allocate_frame(Page *page, int rw, int is_kernel) {
if (!get_free_frame(&frame_address)) {
return 0;
}
- write_to_frame(frame_address * 0x1000, 1);
+ assert(write_to_frame(frame_address * 0x1000, 1));
page->present = 1;
page->rw = rw;
@@ -430,7 +436,7 @@ void mmu_free_pagedirectory(PageDirectory *pd) {
if (!page->frame) {
continue;
}
- write_to_frame(((u32)page->frame) * 0x1000, 0);
+ (void)write_to_frame(((u32)page->frame) * 0x1000, 0);
}
kmalloc_align_free(pd->tables[i], sizeof(PageTable));
pd->tables[i] = NULL;
@@ -451,7 +457,7 @@ void mmu_free_address_range(void *ptr, size_t length, PageDirectory *pd) {
if (!page->frame) {
continue;
}
- write_to_frame(((u32)page->frame) * 0x1000, 0);
+ (void)write_to_frame(((u32)page->frame) * 0x1000, 0);
page->present = 0;
page->rw = 0;
page->user = 0;
@@ -485,7 +491,7 @@ void mmu_map_physical(void *dst, PageDirectory *d, void *physical,
p->rw = 1;
p->user = 1;
p->frame = (uintptr_t)physical / PAGE_SIZE;
- write_to_frame((uintptr_t)physical, 1);
+ (void)write_to_frame((uintptr_t)physical, 1);
}
}
@@ -651,7 +657,7 @@ void paging_init(u64 memsize, multiboot_info_t *mb) {
(multiboot_memory_map_t *)(mb->mmap_addr + 0xc0000000);
for (size_t length = 0; length < mb->mmap_length;) {
if (MULTIBOOT_MEMORY_AVAILABLE == map->type) {
- num_of_frames = max(num_of_frames, map->addr + map->len);
+ num_of_frames = max(num_of_frames, map->addr + map->len + 0x1000);
for (size_t i = 0; i < map->len; i += 0x20000) {
u32 frame = (map->addr + i) / 0x1000;
if (frame < (num_array_frames * 32)) {
@@ -682,14 +688,14 @@ void paging_init(u64 memsize, multiboot_info_t *mb) {
// Loop through the pages in the table
PageTable *table = kernel_directory->tables[i];
- write_to_frame(kernel_directory->physical_tables[i], 1);
+ (void)write_to_frame(kernel_directory->physical_tables[i], 1);
for (size_t j = 0; j < 1024; j++) {
if (!table->pages[j].present) {
continue;
}
// Add the frame to our bitmap to ensure it does not get used by
// another newly created page.
- write_to_frame(table->pages[j].frame * 0x1000, 1);
+ (void)write_to_frame(table->pages[j].frame * 0x1000, 1);
}
}
@@ -725,7 +731,7 @@ void paging_init(u64 memsize, multiboot_info_t *mb) {
for (size_t i = 0; i < map->len - 0x1000; i += 0x20000) {
u32 frame = (map->addr + i) / 0x1000;
if (frame > (num_array_frames * 32)) {
- assert(INDEX_FROM_BIT(frame) <= num_of_frames);
+ assert(INDEX_FROM_BIT(frame) < num_of_frames);
tmp_small_frames[INDEX_FROM_BIT(frame)] = 0;
}
}
diff --git a/kernel/elf.h b/kernel/elf.h
deleted file mode 100644
index 2ad4353..0000000
--- a/kernel/elf.h
+++ /dev/null
@@ -1,98 +0,0 @@
-#ifndef ELF_H
-#define ELF_H
-#include <assert.h>
-#include <fs/vfs.h>
-#include <mmu.h>
-#include <typedefs.h>
-
-#define ET_NONE 0 // No file type
-#define ET_REL 1 // Relocatable file
-#define ET_EXEC 2 // Executable file
-#define ET_DYN 3 // Shared object file
-#define ET_CORE 4 // Core file
-#define ET_LOPROC 0xff00 // Processor-specific
-#define ET_HIPROC 0xffff // Processor-specific
-
-#define EM_NONE 0 // No machine
-#define EM_M32 1 // AT&T WE 32100
-#define EM_SPARC 2 // SPARC
-#define EM_386 3 // Intel 80386
-#define EM_68K 4 // Motorola 68000
-#define EM_88K 5 // Motorola 88000
-#define EM_860 7 // Intel 80860
-#define EM_MIPS 8 // MIPS RS3000
-
-#define EV_NONE 0 // Invalid version
-#define EV_CURRENT 1 // Current version
-
-#define ELF_EXECUTABLE (1 << 0)
-#define ELF_WRITABLE (1 << 1)
-#define ELF_READABLE (1 << 2)
-
-#define Elf32_Addr u32 // Unsigned program address
-#define Elf32_Half u16 // Unsigned medium integer
-#define Elf32_Off u32 // Unsigned file offset
-#define Elf32_Sword u32 // Signed large integer
-#define Elf32_Word u32 // Unsigned large integer
-
-#define ELF_EXEC (1 << 0)
-#define ELF_WRITE (1 << 1)
-#define ELF_READ (1 << 2)
-
-// ELF header
-typedef struct {
- unsigned char e_ident[16];
- Elf32_Half e_type; // Object file type (ET_*)
- Elf32_Half e_machine; // Required architecture (EM_*)
- Elf32_Word e_version; // Object file version (EV_*)
- Elf32_Addr e_entry; // File entry point
- Elf32_Off e_phoff; // Program header table's offset(bytes)
- Elf32_Off e_shoff; // Section header table's offset(bytes)
- Elf32_Word e_flags;
- Elf32_Half e_ehsize; // ELF Header size
- Elf32_Half
- e_phentsize; // Size of program's header tables(all are the same size)
- Elf32_Half e_phnum; // Amount of program headers
- Elf32_Half e_shentsize;
- Elf32_Half e_shnum;
- Elf32_Half e_shstrndx;
-} __attribute__((packed)) ELFHeader;
-
-// Section header
-typedef struct {
- Elf32_Word sh_name;
- Elf32_Word sh_type;
- Elf32_Word sh_flags;
- Elf32_Addr sh_addr;
- Elf32_Off sh_offset;
- Elf32_Word sh_size;
- Elf32_Word sh_link;
- Elf32_Word sh_info;
- Elf32_Word sh_addralign;
- Elf32_Word sh_entsize;
-} Elf32_Shdr;
-
-enum ShT_Types {
- SHT_NULL = 0, // Null section
- SHT_PROGBITS = 1, // Program information
- SHT_SYMTAB = 2, // Symbol table
- SHT_STRTAB = 3, // String table
- SHT_RELA = 4, // Relocation (w/ addend)
- SHT_NOBITS = 8, // Not present in file
- SHT_REL = 9, // Relocation (no addend)
-};
-
-// Program header
-typedef struct {
- Elf32_Word p_type;
- Elf32_Off p_offset;
- Elf32_Addr p_vaddr;
- Elf32_Addr p_paddr;
- Elf32_Word p_filesz;
- Elf32_Word p_memsz;
- Elf32_Word p_flags;
- Elf32_Word p_align;
-} __attribute__((packed)) Elf32_Phdr;
-
-void *load_elf_file(const char *f, u32 *ds);
-#endif
diff --git a/kernel/includes/mmu.h b/kernel/includes/mmu.h
index 83ea6e0..a248b8a 100644
--- a/kernel/includes/mmu.h
+++ b/kernel/includes/mmu.h
@@ -64,7 +64,7 @@ PageDirectory *clone_directory(PageDirectory *original);
void *virtual_to_physical(void *address, PageDirectory *directory);
void *ksbrk(size_t s);
void *ksbrk_physical(size_t s, void **physical);
-void write_to_frame(u32 frame_address, u8 on);
+int write_to_frame(u32 frame_address, u8 on);
Page *get_page(void *ptr, PageDirectory *directory, int create_new_page,
int set_user);