summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--kernel/memory/paging.c46
-rw-r--r--kernel/user.c62
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));