diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/memory/paging.c | 46 | ||||
-rw-r--r-- | kernel/user.c | 62 |
2 files changed, 76 insertions, 32 deletions
diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index e21fd34..fc3b256 100644 --- a/kernel/memory/paging.c +++ b/kernel/memory/paging.c @@ -1,4 +1,3 @@ -#include "lib/kio.h" #include <lib.h> #include <comus/memory.h> @@ -6,7 +5,6 @@ #include "physalloc.h" #include "paging.h" #include "memory.h" -#include <stdint.h> // PAGE MAP LEVEL 4 ENTRY struct pml4e { @@ -259,8 +257,10 @@ static volatile struct pml4 *pml4_alloc(void) volatile struct pml4 *pPML4, *vPML4; pPML4 = alloc_phys_page(); - if (pPML4 == NULL) + if (pPML4 == NULL) { + ERROR("Could not allocate PML4"); return NULL; + } vPML4 = PML4_MAP(pPML4); memsetv(vPML4, 0, sizeof(struct pml4)); @@ -288,8 +288,10 @@ static volatile struct pdpt *pdpt_alloc(volatile struct pml4 *pPML4, } pPDPT = alloc_phys_page(); - if (pPML4 == NULL) + if (pPDPT == NULL) { + ERROR("Could not allocate PDPT"); return NULL; + } vPDPT = PDPT_MAP(pPDPT); memsetv(vPDPT, 0, sizeof(struct pdpt)); @@ -321,8 +323,10 @@ static volatile struct pd *pd_alloc(volatile struct pdpt *pPDPT, void *vADDR, } pPD = alloc_phys_page(); - if (pPDPT == NULL) + if (pPD == NULL) { + ERROR("Could not allocate PD"); return NULL; + } vPD = PD_MAP(pPD); memsetv(vPD, 0, sizeof(struct pd)); @@ -354,8 +358,10 @@ static volatile struct pt *pt_alloc(volatile struct pd *pPD, void *vADDR, } pPT = alloc_phys_page(); - if (pPT == NULL) + if (pPT == NULL) { + ERROR("Could not allocate PT"); return NULL; + } vPT = PT_MAP(pPT); memsetv(vPT, 0, sizeof(struct pt)); @@ -911,11 +917,15 @@ void *mem_mapaddr(mem_ctx_t ctx, void *phys, void *virt, size_t len, // get page aligned (or allocate) vitural address if (virt == NULL) virt = virtaddr_alloc(&ctx->virtctx, pages); - if (virt == NULL) + if (virt == NULL) { + ERROR("Could not alloc vitural address for %zu pages", pages); return NULL; + } - if (virtaddr_take(&ctx->virtctx, virt, pages)) + if (virtaddr_take(&ctx->virtctx, virt, pages)) { + ERROR("Could not take vitural address: %p", virt); return NULL; + } assert((uint64_t)virt % PAGE_SIZE == 0, "mem_mapaddr: vitural address not page aligned"); @@ -923,6 +933,7 @@ void *mem_mapaddr(mem_ctx_t ctx, void *phys, void *virt, size_t len, if (map_pages((volatile struct pml4 *)ctx->pml4, virt, aligned_phys, F_PRESENT | flags, pages)) { virtaddr_free(&ctx->virtctx, virt); + ERROR("Could not map pages"); return NULL; } @@ -1028,21 +1039,30 @@ void *mem_alloc_pages_at(mem_ctx_t ctx, size_t count, void *virt, { void *phys = NULL; - if (virtaddr_take(&ctx->virtctx, virt, count)) + if (virtaddr_take(&ctx->virtctx, virt, count)) { + ERROR("Could not take vitural address: %p", virt); return NULL; + } phys = alloc_phys_pages_exact(count); - if (phys == NULL) - return NULL; + if (phys == NULL) { + ERROR("Could not allocate %zu physical pages", count); + goto fail; + } if (map_pages((volatile struct pml4 *)ctx->pml4, virt, phys, flags, count)) { - free_phys_pages(phys, count); - return NULL; + ERROR("Could not map pages"); + goto fail; } return virt; +fail: + free_phys_pages(phys, count); + virtaddr_free(&ctx->virtctx, virt); + return NULL; + // size_t pages_needed = count; // // struct phys_page_slice prev_phys_block = PHYS_PAGE_SLICE_NULL; diff --git a/kernel/user.c b/kernel/user.c index 9612710..97d8f0f 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -1,3 +1,4 @@ +#include "lib/kio.h" #include <comus/fs.h> #include <comus/procs.h> #include <comus/memory.h> @@ -14,7 +15,7 @@ #define USER_STACK_LEN (4 * PAGE_SIZE) #define BLOCK_SIZE (PAGE_SIZE * 1000) -static char *load_buffer = NULL; +static uint8_t *load_buffer = NULL; #define USER_CODE 0x18 #define USER_DATA 0x20 @@ -49,16 +50,22 @@ static int user_load_segment(struct pcb *pcb, struct file *file, int idx) // allocate memory in user process if (mem_alloc_pages_at(pcb->memctx, mem_pages, (void *)hdr.p_vaddr, - F_WRITEABLE | F_UNPRIVILEGED) == NULL) + F_WRITEABLE | F_UNPRIVILEGED) == NULL) { + ERROR("Could not allocate memory for elf segment"); return 1; + } mapADDR = kmapuseraddr(pcb->memctx, (void *)hdr.p_vaddr, mem_bytes); - if (mapADDR == NULL) + if (mapADDR == NULL) { + ERROR("Could load memory for elf segment"); return 1; + } // seek to start of segment - if (file->seek(file, hdr.p_offset, SEEK_SET) < 0) + if (file->seek(file, hdr.p_offset, SEEK_SET) < 0) { + ERROR("Could not load elf segment"); return 1; + } // load data size_t total_read = 0; @@ -66,11 +73,13 @@ static int user_load_segment(struct pcb *pcb, struct file *file, int idx) size_t read = BLOCK_SIZE; if (read > file_bytes - total_read) read = file_bytes - total_read; + TRACE("Reading %zu bytes...", read); if ((read = file->read(file, load_buffer, read)) < 1) { kunmapaddr(mapADDR); + ERROR("Could not load elf segment"); return 1; } - memcpy(mapADDR + total_read, load_buffer, read); + memcpyv(mapADDR + total_read, load_buffer, read); total_read += read; } @@ -89,10 +98,15 @@ static int user_load_segments(struct pcb *pcb, struct file *file) pcb->heap_start = NULL; pcb->heap_len = 0; - if (load_buffer == NULL) - if ((load_buffer = kalloc(BLOCK_SIZE)) == NULL) + if (load_buffer == NULL) { + load_buffer = kalloc(BLOCK_SIZE); + if (load_buffer == NULL) { + ERROR("Could not allocate user load buffer"); return 1; + } + } + TRACE("Loading %u elf segments", pcb->n_elf_segments); for (int i = 0; i < pcb->n_elf_segments; i++) if ((ret = user_load_segment(pcb, file, i))) return ret; @@ -110,12 +124,12 @@ static int validate_elf_hdr(struct pcb *pcb) Elf64_Ehdr *ehdr = &pcb->elf_header; if (strncmp((const char *)ehdr->e_ident, ELFMAG, SELFMAG)) { - WARN("Invalid ELF File."); + ERROR("Invalid ELF File."); return 1; } if (ehdr->e_ident[EI_CLASS] != ELFCLASS64) { - WARN("Unsupported ELF Class."); + ERROR("Unsupported ELF Class."); return 1; } @@ -125,17 +139,17 @@ static int validate_elf_hdr(struct pcb *pcb) } if (ehdr->e_machine != EM_X86_64) { - WARN("Unsupported ELF File target."); + ERROR("Unsupported ELF File target."); return 1; } if (ehdr->e_ident[EI_VERSION] != EV_CURRENT) { - WARN("Unsupported ELF File version."); + ERROR("Unsupported ELF File version."); return 1; } if (ehdr->e_phnum > N_ELF_SEGMENTS) { - WARN("Too many ELF segments."); + ERROR("Too many ELF segments."); return 1; } @@ -151,22 +165,30 @@ static int user_load_elf(struct pcb *pcb, struct file *file) { int ret = 0; - if (file->seek(file, 0, SEEK_SET) < 0) + if (file->seek(file, 0, SEEK_SET) < 0) { + ERROR("Cannot read ELF header."); return 1; - ret = file->read(file, (char *)&pcb->elf_header, sizeof(Elf64_Ehdr)); - if (ret < 0) + } + ret = file->read(file, &pcb->elf_header, sizeof(Elf64_Ehdr)); + if (ret < 0) { + ERROR("Cannot read ELF header."); return 1; + } if (validate_elf_hdr(pcb)) return 1; pcb->n_elf_segments = pcb->elf_header.e_phnum; - if (file->seek(file, pcb->elf_header.e_phoff, SEEK_SET) < 0) + if (file->seek(file, pcb->elf_header.e_phoff, SEEK_SET) < 0) { + ERROR("Cannot read ELF segemts"); return 1; - ret = file->read(file, (char *)&pcb->elf_segments, + } + ret = file->read(file, &pcb->elf_segments, sizeof(Elf64_Phdr) * pcb->elf_header.e_phnum); - if (ret < 0) + if (ret < 0) { + ERROR("Cannot read ELF segemts"); return 1; + } return 0; } @@ -217,8 +239,10 @@ static int user_setup_stack(struct pcb *pcb, const char **args, /* stack */ if (mem_alloc_pages_at(pcb->memctx, USER_STACK_LEN / PAGE_SIZE, (void *)(USER_STACK_TOP - USER_STACK_LEN), - F_WRITEABLE | F_UNPRIVILEGED) == NULL) + F_WRITEABLE | F_UNPRIVILEGED) == NULL) { + ERROR("Could not allocate user stack"); return 1; + } /* regs */ memset(&pcb->regs, 0, sizeof(struct cpu_regs)); |