From 33663539c2bac856cf2abe79e815ad179dffecdf Mon Sep 17 00:00:00 2001 From: Anton Kling Date: Mon, 22 Apr 2024 23:55:16 +0200 Subject: MMU: Extra asserts to avoid future regressions --- include/elf.h | 188 +++++++++++++++++++++++++++++++++++++++++++++++++ kernel/arch/i386/mmu.c | 32 +++++---- kernel/elf.h | 98 -------------------------- kernel/includes/mmu.h | 2 +- 4 files changed, 208 insertions(+), 112 deletions(-) create mode 100644 include/elf.h delete mode 100644 kernel/elf.h diff --git a/include/elf.h b/include/elf.h new file mode 100644 index 0000000..f1c0f5c --- /dev/null +++ b/include/elf.h @@ -0,0 +1,188 @@ +#ifndef ELF_H +#define ELF_H +#include +#ifdef KERNEL +#include +#include +#endif +#include + +#define EI_NIDENT 16 + +#define SHN_UNDEF 0 +#define SHN_LORESERVE 0xff00 +#define SHN_LOPROC 0xff00 +#define SHN_HIPROC 0xff1f +#define SHN_ABS 0xfff1 +#define SHN_COMMON 0xfff2 +#define SHN_HIRESERVE 0xffff + +#define ELF32_R_SYM(i) ((i) >> 8) +#define ELF32_R_TYPE(i) ((unsigned char)(i)) +#define ELF32_R_INFO(s, t) (((s) << 8) + (unsigned char)(t)) + +#define ELF32_ST_BIND(i) ((i)>>4) +#define ELF32_ST_TYPE(i) ((i)&0xf) +#define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf)) + +#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 STT_NOTYPE 0 +#define STT_OBJECT 1 +#define STT_FUNC 2 +#define STT_SECTION 3 +#define STT_FILE 4 +#define STT_LOPROC 13 +#define STT_HIPROC 15 + +#define SHF_WRITE 0x1 +#define SHF_ALLOC 0x2 +#define SHF_EXECINSTR 0x4 +#define SHF_MASKPROC 0xf0000000 + +#define ELFCLASSNONE 0 +#define ELFCLASS32 1 +#define ELFCLASS64 2 + +#define STB_LOCAL 0 +#define STB_GLOBAL 1 +#define STB_WEAK 2 +#define STB_LOPROC 13 +#define STB_HIPROC 15 + +#define ELFDATANONE 0 +#define ELFDATA2LSB 1 +#define ELFDATA2MSB 2 + +#define R_386_NONE 0 +#define R_386_32 1 +#define R_386_PC32 2 +#define R_386_GOT32 3 +#define R_386_PLT32 4 +#define R_386_COPY 5 +#define R_386_GLOB_DAT 6 +#define R_386_JMP_SLOT 7 +#define R_386_RELATIVE 8 +#define R_386_GOTOFF 9 +#define R_386_GOTPC 10 + +#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; + +typedef struct { + Elf32_Addr r_offset; + Elf32_Word r_info; +} Elf32_Rel; + +typedef struct { + Elf32_Word st_name; + Elf32_Addr st_value; + Elf32_Word st_size; + unsigned char st_info; + unsigned char st_other; + Elf32_Half st_shndx; +} Elf32_Sym; + +typedef struct { + unsigned char e_ident[EI_NIDENT]; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; +} Elf32_Ehdr; + +// 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/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 -#include -#include -#include - -#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); -- cgit v1.2.3