Implement brk syscall simple case
This commit is contained in:
parent
c59eb339e9
commit
6471ee9a2d
10
core/elf.c
10
core/elf.c
@ -3,6 +3,8 @@
|
|||||||
#include "klibc.h"
|
#include "klibc.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "paging.h"
|
#include "paging.h"
|
||||||
|
#include "thread.h"
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make sure the program is in a valid ELF format, map it into memory,
|
* Make sure the program is in a valid ELF format, map it into memory,
|
||||||
@ -11,9 +13,10 @@
|
|||||||
* @return 0 when the program is not a valid ELF
|
* @return 0 when the program is not a valid ELF
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uaddr_t loadElfProg(const char *prog)
|
uaddr_t loadElfProg(const char *prog, struct process * proc)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
uaddr_t lastUserAddr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Typedefs, constants and structure definitions as given by the ELF
|
* Typedefs, constants and structure definitions as given by the ELF
|
||||||
@ -176,7 +179,12 @@ uaddr_t loadElfProg(const char *prog)
|
|||||||
/* Copy segment into memory */
|
/* Copy segment into memory */
|
||||||
memcpy((void *)elf_phdrs[i].p_vaddr, (void *)(prog + elf_phdrs[i].p_offset),
|
memcpy((void *)elf_phdrs[i].p_vaddr, (void *)(prog + elf_phdrs[i].p_offset),
|
||||||
elf_phdrs[i].p_filesz);
|
elf_phdrs[i].p_filesz);
|
||||||
|
if (lastUserAddr < uaddr) {
|
||||||
|
lastUserAddr = uaddr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
processInitHeap(proc, lastUserAddr);
|
||||||
|
|
||||||
return elf_hdr->e_entry;
|
return elf_hdr->e_entry;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "process.h"
|
||||||
|
#include "thread.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
uaddr_t loadElfProg(const char *prog);
|
uaddr_t loadElfProg(const char *prog, struct process *proc);
|
||||||
|
@ -86,7 +86,7 @@ void loadUserSpace()
|
|||||||
struct process *proc = processCreate("UserSpace");
|
struct process *proc = processCreate("UserSpace");
|
||||||
|
|
||||||
threadChangeCurrentContext(processGetMMUContext(proc));
|
threadChangeCurrentContext(processGetMMUContext(proc));
|
||||||
uaddr_t prog = loadElfProg(buf + FILE_HEADER_SIZE);
|
uaddr_t prog = loadElfProg(buf + FILE_HEADER_SIZE, proc);
|
||||||
if (prog == (uaddr_t)NULL) {
|
if (prog == (uaddr_t)NULL) {
|
||||||
free(buf);
|
free(buf);
|
||||||
return;
|
return;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "klibc.h"
|
#include "klibc.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "mmuContext.h"
|
#include "mmuContext.h"
|
||||||
|
#include "types.h"
|
||||||
#include "uaddrspace.h"
|
#include "uaddrspace.h"
|
||||||
|
|
||||||
struct process {
|
struct process {
|
||||||
@ -167,3 +168,11 @@ struct mmu_context *processGetMMUContext(struct process *proc)
|
|||||||
{
|
{
|
||||||
return uAddrSpaceGetMMUContext(proc->addrSpace);
|
return uAddrSpaceGetMMUContext(proc->addrSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct uAddrSpace *processGetAddrSpace(struct process *proc){
|
||||||
|
return proc->addrSpace;
|
||||||
|
}
|
||||||
|
|
||||||
|
int processInitHeap(struct process *proc, uaddr_t lastUserAddr){
|
||||||
|
return uAddrSpaceSetHeap(proc->addrSpace, lastUserAddr, 0);
|
||||||
|
}
|
||||||
|
@ -15,3 +15,5 @@ int processSetName(struct process *proc, char *name);
|
|||||||
int processAddThread(struct process *proc, struct thread *th);
|
int processAddThread(struct process *proc, struct thread *th);
|
||||||
int processRemoveThread(struct thread *th);
|
int processRemoveThread(struct thread *th);
|
||||||
struct mmu_context *processGetMMUContext(struct process *th);
|
struct mmu_context *processGetMMUContext(struct process *th);
|
||||||
|
struct uAddrSpace *processGetAddrSpace(struct process *proc);
|
||||||
|
int processInitHeap(struct process *proc, uaddr_t lastUserAddr);
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
#include "syscall.h"
|
#include "syscall.h"
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
#include "klibc.h"
|
#include "klibc.h"
|
||||||
|
#include "process.h"
|
||||||
#include "stdarg.h"
|
#include "stdarg.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "uaddrspace.h"
|
||||||
|
|
||||||
int syscallExecute(int syscallId, const struct cpu_state *userCtx)
|
int syscallExecute(int syscallId, const struct cpu_state *userCtx)
|
||||||
{
|
{
|
||||||
@ -37,6 +40,21 @@ int syscallExecute(int syscallId, const struct cpu_state *userCtx)
|
|||||||
printf("Got 5args from userspace %d %d %d %d %d\n", arg1, arg2, arg3, arg4, arg5);
|
printf("Got 5args from userspace %d %d %d %d %d\n", arg1, arg2, arg3, arg4, arg5);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SYSCALL_ID_BRK:{
|
||||||
|
|
||||||
|
struct uAddrSpace *as;
|
||||||
|
uaddr_t newHeapTop;
|
||||||
|
|
||||||
|
as = processGetAddrSpace(getCurrentThread()->process);
|
||||||
|
ret = syscallGet1arg(userCtx, (unsigned int *)&newHeapTop);
|
||||||
|
if (ret != 0)
|
||||||
|
break;
|
||||||
|
threadChangeCurrentContext(uAddrSpaceGetMMUContext(as));
|
||||||
|
//TODO : what if *newHeapTop raise page fault?
|
||||||
|
ret = sysBrk(as, newHeapTop);
|
||||||
|
threadChangeCurrentContext(NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
printf("Unknon syscall id %d\n", syscallId);
|
printf("Unknon syscall id %d\n", syscallId);
|
||||||
ret = -ENOENT;
|
ret = -ENOENT;
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#define SYSCALL_ID_PUTC 3
|
#define SYSCALL_ID_PUTC 3
|
||||||
#define SYSCALL_ID_READ 4
|
#define SYSCALL_ID_READ 4
|
||||||
#define SYSCALL_ID_TEST 5
|
#define SYSCALL_ID_TEST 5
|
||||||
|
#define SYSCALL_ID_BRK 6
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
int syscallExecute(int syscallId, const struct cpu_state *user_ctx);
|
int syscallExecute(int syscallId, const struct cpu_state *user_ctx);
|
||||||
|
119
core/uaddrspace.c
Normal file
119
core/uaddrspace.c
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
#include "uaddrspace.h"
|
||||||
|
#include "alloc.h"
|
||||||
|
#include "kernel.h"
|
||||||
|
#include "mem.h"
|
||||||
|
#include "mmuContext.h"
|
||||||
|
#include "process.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
#include "thread.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct uAddrVirtualReg {
|
||||||
|
uaddr_t addr;
|
||||||
|
size_t size;
|
||||||
|
int right; // PAGING_MEM_*
|
||||||
|
uint32_t offset; // in the mappedRessource
|
||||||
|
uint flags;
|
||||||
|
|
||||||
|
struct mappedRessource *res;
|
||||||
|
struct uAddrVirtualReg *nextInAddrSpace, *prevInAddrSpace;
|
||||||
|
struct uAddrVirtualReg *nextInMappedRes, *prevInMappedRes;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct uAddrSpace {
|
||||||
|
struct process *process; // The process that is represented by this AS
|
||||||
|
struct mmu_context *ctx; // The corresponding MMU configuration
|
||||||
|
|
||||||
|
struct uAddrVirtualReg *listVirtualReg; // List of Virtual Region used by this process
|
||||||
|
|
||||||
|
uaddr_t heapStart; // Start of the Head
|
||||||
|
size_t heapSize; // Hep size -> modified by brk()
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mappedRessourceOps {
|
||||||
|
int (*open)(struct uAddrVirtualReg *vreg);
|
||||||
|
int (*close)(struct uAddrVirtualReg *vreg);
|
||||||
|
int (*unmap)(struct uAddrVirtualReg *vregi, uaddr_t addr, size_t size);
|
||||||
|
int (*nopage)(struct uAddrVirtualReg *vregi, uaddr_t addr,
|
||||||
|
int right); // Called by the pageflt handler when the page is missing
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mappedRessource {
|
||||||
|
int right; // PAGING_MEM_*
|
||||||
|
struct mappedRessourceOps *ops;
|
||||||
|
struct uAddrVirtualReg *listVirtualReg;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct uAddrSpace *uAddrSpaceCreate(struct process *proc)
|
||||||
|
{
|
||||||
|
struct uAddrSpace *addr = (struct uAddrSpace *)malloc(sizeof(struct uAddrSpace));
|
||||||
|
|
||||||
|
if (addr == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
addr->ctx = mmuContextCreate();
|
||||||
|
|
||||||
|
if (addr->ctx == NULL) {
|
||||||
|
free(addr);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr->process = proc;
|
||||||
|
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uAddrSpaceDelete(struct uAddrSpace *addr)
|
||||||
|
{
|
||||||
|
// TODO Work on Virtual Region
|
||||||
|
return mmuContextUnref(addr->ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mmu_context *uAddrSpaceGetMMUContext(struct uAddrSpace *addr)
|
||||||
|
{
|
||||||
|
return addr->ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uAddrSpaceSetHeap(struct uAddrSpace *as, uaddr_t addr, size_t size)
|
||||||
|
{
|
||||||
|
as->heapStart = addr;
|
||||||
|
as->heapSize = size;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uaddr_t sysBrk(struct uAddrSpace *as, uaddr_t newHeapTop)
|
||||||
|
{
|
||||||
|
int incSize;
|
||||||
|
assert(as->heapStart);
|
||||||
|
if (!newHeapTop || newHeapTop < as->heapStart)
|
||||||
|
return as->heapStart + as->heapSize;
|
||||||
|
|
||||||
|
newHeapTop = ALIGN(newHeapTop, PAGE_SIZE);
|
||||||
|
|
||||||
|
if (newHeapTop == as->heapStart + as->heapSize)
|
||||||
|
return newHeapTop;
|
||||||
|
|
||||||
|
incSize = ALIGN(newHeapTop - (as->heapStart + as->heapSize), PAGE_SIZE);
|
||||||
|
|
||||||
|
if (incSize < 0){
|
||||||
|
//FIXME
|
||||||
|
return as->heapStart + as->heapSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
//WIP do it manually
|
||||||
|
for (uaddr_t begin = ALIGN(as->heapStart + as->heapSize, PAGE_SIZE); begin < newHeapTop; begin += PAGE_SIZE) {
|
||||||
|
paddr_t ppage = allocPhyPage(1);
|
||||||
|
if (0 != pageMap(begin, ppage,
|
||||||
|
PAGING_MEM_USER | PAGING_MEM_WRITE | PAGING_MEM_READ))
|
||||||
|
return (uaddr_t)NULL;
|
||||||
|
|
||||||
|
unrefPhyPage(ppage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
14
core/uaddrspace.h
Normal file
14
core/uaddrspace.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "mmuContext.h"
|
||||||
|
#include "process.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
struct uAddrSpace;
|
||||||
|
struct uAddrVirtualReg;
|
||||||
|
|
||||||
|
struct uAddrSpace * uAddrSpaceCreate(struct process *proc);
|
||||||
|
int uAddrSpaceDelete(struct uAddrSpace *addr);
|
||||||
|
struct mmu_context * uAddrSpaceGetMMUContext(struct uAddrSpace *addr);
|
||||||
|
int uAddrSpaceSetHeap(struct uAddrSpace *as, uaddr_t addr, size_t size);
|
||||||
|
uaddr_t sysBrk(struct uAddrSpace *as, uaddr_t newHeapTop);
|
@ -8,6 +8,7 @@
|
|||||||
#define SYSCALL_ID_PUTC 3
|
#define SYSCALL_ID_PUTC 3
|
||||||
#define SYSCALL_ID_READ 4
|
#define SYSCALL_ID_READ 4
|
||||||
#define SYSCALL_ID_TEST 5
|
#define SYSCALL_ID_TEST 5
|
||||||
|
#define SYSCALL_ID_BRK 6
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
int syscallExecute(int syscallId, const struct cpu_state *user_ctx);
|
int syscallExecute(int syscallId, const struct cpu_state *user_ctx);
|
||||||
|
@ -566,3 +566,7 @@ int readline(char *buf, int size)
|
|||||||
return i == (size-1);
|
return i == (size-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *brk(void *addr)
|
||||||
|
{
|
||||||
|
return (void *)syscall1(SYSCALL_ID_BRK, (unsigned int)addr);
|
||||||
|
}
|
||||||
|
@ -45,3 +45,4 @@ int testSycall5(uint arg1, uint arg2, uint arg3, uint arg4, uint arg5);
|
|||||||
char readc();
|
char readc();
|
||||||
char readcBlock();
|
char readcBlock();
|
||||||
int readline(char *buf, int size);
|
int readline(char *buf, int size);
|
||||||
|
void *brk(void *addr);
|
||||||
|
@ -13,6 +13,7 @@ int func_help()
|
|||||||
printf(" suicide\n");
|
printf(" suicide\n");
|
||||||
printf(" help\n");
|
printf(" help\n");
|
||||||
printf(" syscall5\n");
|
printf(" syscall5\n");
|
||||||
|
printf(" alloc\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,6 +25,23 @@ int func_suicide()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void * initialHeap = 0;
|
||||||
|
int func_alloc(){
|
||||||
|
|
||||||
|
if(initialHeap == 0){
|
||||||
|
initialHeap = brk(0);
|
||||||
|
}
|
||||||
|
void * currentHeap = brk(0);
|
||||||
|
if (currentHeap - initialHeap < 4096){
|
||||||
|
brk(initialHeap + 4096);
|
||||||
|
}
|
||||||
|
int * allocatedData = (int *)initialHeap;
|
||||||
|
for(unsigned int i = 0 ; i < 4096/sizeof(int); i++){
|
||||||
|
allocatedData[i] =i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
(void)argc;
|
(void)argc;
|
||||||
@ -50,6 +68,10 @@ int main(int argc, char *argv[])
|
|||||||
testSycall5(1, 2, 3, 4, 5);
|
testSycall5(1, 2, 3, 4, 5);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (strcmp(buf, "alloc") == 0) {
|
||||||
|
func_alloc();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user