diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-07-05 19:38:11 +0300 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-07-05 19:38:11 +0300 |
| commit | e09edb5d54e39bd9509a1dc450df5ab320759f97 (patch) | |
| tree | 78e050b0db87df3a3ddfbb6570d44513ac34e02a /src/vmem.c | |
| parent | 98f21e694a6b0964d6d08196cb6bfbc1c2ae2ff4 (diff) | |
| download | kmi-e09edb5d54e39bd9509a1dc450df5ab320759f97.tar.gz kmi-e09edb5d54e39bd9509a1dc450df5ab320759f97.zip | |
allow booting with Qemu's -kernel flag directly
+ Took some fairly significant changes, for one the kernel is no longer
relocated at the start of a boot, instead it sits wherever the user
decides the kernel should sit. Similarly, the initial kernel stack and
page table are stored within the binary, slightly bloating the size
but making it much safer to boot since there's really no chance of us
overwriting the fdt or initrd in memory.
Diffstat (limited to 'src/vmem.c')
| -rw-r--r-- | src/vmem.c | 35 |
1 files changed, 34 insertions, 1 deletions
@@ -232,6 +232,34 @@ vm_t alloc_fixed_uvmem(struct tcb *t, vm_t start, size_t size, vmflags_t flags) return w; } +static vm_t map_fixed_region(struct vmem *b, vm_t v, pm_t p, size_t size, + vmflags_t flags, stat_t *status) +{ + + vm_t w = v; + stat_t stat = OK; + size_t pages = size / BASE_PAGE_SIZE; + for (size_t i = 0; i < pages; ++i) { + stat = map_vpage(b, p, v, flags, BASE_PAGE); + v += BASE_PAGE_SIZE; + p += BASE_PAGE_SIZE; + } + + if (status) + *status = stat; + + return w; +} + +vm_t map_fixed_mem(struct tcb *t, pm_t start, size_t size, vmflags_t flags) +{ + stat_t status = OK; + const vm_t v = alloc_region(&t->sp_r, size, &size, flags); + const vm_t w = map_fixed_region(t->proc.vmem, v, start, size, flags, + &status); + return w + (start % BASE_PAGE_SIZE); +} + /* free_shared_uvmem shouldn't be needed, likely to work with free_uvmem */ stat_t alloc_shared_uvmem(struct tcb *s, struct tcb *c, size_t size, vmflags_t sflags, vmflags_t cflags, @@ -341,9 +369,14 @@ stat_t copy_allocd_wrapper(struct vmem *b, pm_t *offset, vm_t vaddr, if (!new_page) return INFO_TRGN; - map_vpage(b, new_page, vaddr, flags, order); + /* set write flags temporarily */ + vmflags_t wrflags = flags | VM_W; + map_vpage(b, new_page, vaddr, wrflags, order); memcpy((void *)new_page, (void *)(paddr + *offset), order_size(order)); + /* set actual flags */ + map_vpage(b, new_page, vaddr, flags, order); + if (v_order > order) *offset += order_size(order); else |
