Compare commits
2 Commits
e50f8940a9
...
28aef30f77
| Author | SHA1 | Date | |
|---|---|---|---|
| 28aef30f77 | |||
| 9f107a1a5e |
@@ -3,8 +3,12 @@
|
|||||||
|
|
||||||
#define SYS_PROC_QUIT 1
|
#define SYS_PROC_QUIT 1
|
||||||
#define SYS_PROC_TEST 2
|
#define SYS_PROC_TEST 2
|
||||||
|
#define SYS_PROC_MAP 3
|
||||||
|
#define SYS_PROC_UNMAP 4
|
||||||
|
|
||||||
#define SR_OK 0
|
#define SR_OK 0
|
||||||
#define SR_SYSCALL_NOT_FOUND 1
|
#define SR_SYSCALL_NOT_FOUND 1
|
||||||
|
#define SR_UNALIGNED 2
|
||||||
|
#define SR_OOM_ERROR 3
|
||||||
|
|
||||||
#endif // _M_SYSCALL_DEFS_H
|
#endif // _M_SYSCALL_DEFS_H
|
||||||
|
|||||||
11
init/init.c
11
init/init.c
@@ -1,9 +1,12 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <m/mem.h>
|
||||||
#include <m/proc.h>
|
#include <m/proc.h>
|
||||||
|
#include <string/string.h>
|
||||||
|
|
||||||
void app_main (void) {
|
void app_main (void) {
|
||||||
m_proc_test ();
|
m_proc_map (M_PROC_MAP_BASE, 1, PM_PRESENT | PM_RW | PM_USER);
|
||||||
m_proc_test ();
|
|
||||||
m_proc_test ();
|
memset ((void*)M_PROC_MAP_BASE, 0, M_PAGE_SIZE);
|
||||||
m_proc_test ();
|
|
||||||
|
m_proc_unmap (M_PROC_MAP_BASE, 1);
|
||||||
}
|
}
|
||||||
|
|||||||
1
kernel/.gitignore
vendored
1
kernel/.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
*.json
|
*.json
|
||||||
|
.cache
|
||||||
|
|||||||
@@ -70,6 +70,8 @@ void proc_cleanup (struct proc* proc) {
|
|||||||
struct proc_mapping* mapping =
|
struct proc_mapping* mapping =
|
||||||
list_entry (mapping_link, struct proc_mapping, proc_mappings_link);
|
list_entry (mapping_link, struct proc_mapping, proc_mappings_link);
|
||||||
|
|
||||||
|
DEBUG ("mapping vaddr=%p, paddr=%p, size=%zu\n", mapping->vaddr, mapping->paddr, mapping->size);
|
||||||
|
|
||||||
pmm_free (mapping->paddr, mapping->size / PAGE_SIZE);
|
pmm_free (mapping->paddr, mapping->size / PAGE_SIZE);
|
||||||
list_remove (proc->mappings, mapping_link);
|
list_remove (proc->mappings, mapping_link);
|
||||||
free (mapping);
|
free (mapping);
|
||||||
|
|||||||
@@ -38,14 +38,21 @@ static bool proc_check_elf (uint8_t* elf) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void proc_map (struct proc* proc, uintptr_t start_paddr, uintptr_t start_vaddr, size_t pages,
|
bool proc_map (struct proc* proc, uintptr_t start_paddr, uintptr_t start_vaddr, size_t pages,
|
||||||
uint32_t flags) {
|
uint32_t flags) {
|
||||||
|
DEBUG ("start_vaddr=%p, start_paddr=%p, pages=%zu, flags=%x\n", start_vaddr, start_paddr, pages,
|
||||||
|
flags);
|
||||||
|
|
||||||
struct proc_mapping* mapping = malloc (sizeof (*mapping));
|
struct proc_mapping* mapping = malloc (sizeof (*mapping));
|
||||||
|
|
||||||
|
if (mapping == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
mapping->paddr = start_paddr;
|
mapping->paddr = start_paddr;
|
||||||
mapping->vaddr = start_vaddr;
|
mapping->vaddr = start_vaddr;
|
||||||
mapping->size = pages * PAGE_SIZE;
|
mapping->size = pages * PAGE_SIZE;
|
||||||
|
|
||||||
flags &= ~MM_PD_LOCK; /* clear LOCK flag if present, because we lock manualy */
|
flags &= ~(MM_PD_LOCK | MM_PD_RELOAD); /* clear LOCK flag if present, because we lock manualy */
|
||||||
|
|
||||||
spin_lock (&proc->pd.lock);
|
spin_lock (&proc->pd.lock);
|
||||||
|
|
||||||
@@ -57,6 +64,70 @@ void proc_map (struct proc* proc, uintptr_t start_paddr, uintptr_t start_vaddr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock (&proc->pd.lock);
|
spin_unlock (&proc->pd.lock);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool proc_unmap (struct proc* proc, uintptr_t start_vaddr, size_t pages) {
|
||||||
|
size_t unmap_size = pages * PAGE_SIZE;
|
||||||
|
uintptr_t end_vaddr = start_vaddr + unmap_size;
|
||||||
|
struct list_node_link *mapping_link, *mapping_link_tmp;
|
||||||
|
bool used_tail_mapping = false;
|
||||||
|
|
||||||
|
DEBUG ("start_vaddr=%p, pages=%zu\n", start_vaddr, pages);
|
||||||
|
|
||||||
|
struct proc_mapping* tail_mapping = malloc (sizeof (*tail_mapping));
|
||||||
|
if (tail_mapping == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
spin_lock (&proc->pd.lock);
|
||||||
|
|
||||||
|
list_foreach (proc->mappings, mapping_link, mapping_link_tmp) {
|
||||||
|
struct proc_mapping* mapping =
|
||||||
|
list_entry (mapping_link, struct proc_mapping, proc_mappings_link);
|
||||||
|
|
||||||
|
uintptr_t m_end = mapping->vaddr + mapping->size;
|
||||||
|
|
||||||
|
/* check overlap */
|
||||||
|
if ((start_vaddr < m_end) && (end_vaddr > mapping->vaddr)) {
|
||||||
|
/* split in the middle */
|
||||||
|
if ((start_vaddr > mapping->vaddr) && (end_vaddr < m_end)) {
|
||||||
|
tail_mapping->vaddr = end_vaddr;
|
||||||
|
tail_mapping->paddr = mapping->paddr + (end_vaddr - mapping->vaddr);
|
||||||
|
tail_mapping->size = m_end - end_vaddr;
|
||||||
|
|
||||||
|
mapping->size = start_vaddr - mapping->vaddr;
|
||||||
|
|
||||||
|
list_insert_after (proc->mappings, &mapping->proc_mappings_link,
|
||||||
|
&tail_mapping->proc_mappings_link);
|
||||||
|
|
||||||
|
used_tail_mapping = true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
} else if ((start_vaddr <= mapping->vaddr) && (end_vaddr < m_end)) { /* shrink left */
|
||||||
|
size_t diff = end_vaddr - mapping->vaddr;
|
||||||
|
mapping->vaddr += diff;
|
||||||
|
mapping->paddr += diff;
|
||||||
|
mapping->size -= diff;
|
||||||
|
} else if ((start_vaddr > mapping->vaddr) && (end_vaddr >= m_end)) { /* shrink right */
|
||||||
|
mapping->size = start_vaddr - mapping->vaddr;
|
||||||
|
} else { /* full overlap */
|
||||||
|
list_remove (proc->mappings, &mapping->proc_mappings_link);
|
||||||
|
free (mapping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!used_tail_mapping)
|
||||||
|
free (tail_mapping);
|
||||||
|
|
||||||
|
for (uintptr_t vpage = start_vaddr; vpage < end_vaddr; vpage += PAGE_SIZE) {
|
||||||
|
mm_unmap_page (&proc->pd, vpage, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock (&proc->pd.lock);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct elf_aux proc_load_segments (struct proc* proc, uint8_t* elf) {
|
struct elf_aux proc_load_segments (struct proc* proc, uint8_t* elf) {
|
||||||
|
|||||||
@@ -44,8 +44,9 @@ struct proc {
|
|||||||
|
|
||||||
void proc_sched (void);
|
void proc_sched (void);
|
||||||
void proc_kill (struct proc* proc);
|
void proc_kill (struct proc* proc);
|
||||||
void proc_map (struct proc* proc, uintptr_t start_paddr, uintptr_t start_vaddr, size_t pages,
|
bool proc_map (struct proc* proc, uintptr_t start_paddr, uintptr_t start_vaddr, size_t pages,
|
||||||
uint32_t flags);
|
uint32_t flags);
|
||||||
|
bool proc_unmap (struct proc* proc, uintptr_t start_vaddr, size_t pages);
|
||||||
struct elf_aux proc_load_segments (struct proc* proc, uint8_t* elf);
|
struct elf_aux proc_load_segments (struct proc* proc, uint8_t* elf);
|
||||||
void proc_init (void);
|
void proc_init (void);
|
||||||
|
|
||||||
|
|||||||
@@ -1,28 +1,63 @@
|
|||||||
#include <aux/compiler.h>
|
#include <aux/compiler.h>
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
#include <m/syscall_defs.h>
|
#include <m/syscall_defs.h>
|
||||||
|
#include <mm/pmm.h>
|
||||||
#include <proc/proc.h>
|
#include <proc/proc.h>
|
||||||
#include <sys/debug.h>
|
#include <sys/debug.h>
|
||||||
|
#include <sys/mm.h>
|
||||||
#include <syscall/syscall.h>
|
#include <syscall/syscall.h>
|
||||||
|
|
||||||
#define DEFINE_SYSCALL(name) \
|
#define DEFINE_SYSCALL(name) \
|
||||||
int name (struct proc* proc, uintptr_t UNUSED a1, uintptr_t UNUSED a2, uintptr_t UNUSED a3, \
|
int name (struct proc* proc, uintptr_t UNUSED a1, uintptr_t UNUSED a2, uintptr_t UNUSED a3, \
|
||||||
uintptr_t UNUSED a4, uintptr_t UNUSED a5, uintptr_t UNUSED a6)
|
uintptr_t UNUSED a4, uintptr_t UNUSED a5, uintptr_t UNUSED a6)
|
||||||
|
|
||||||
|
/* int proc_quit (void) */
|
||||||
DEFINE_SYSCALL (sys_proc_quit) {
|
DEFINE_SYSCALL (sys_proc_quit) {
|
||||||
proc_kill (proc);
|
proc_kill (proc);
|
||||||
proc_sched ();
|
proc_sched ();
|
||||||
return SR_OK;
|
return SR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* int proc_test (void) */
|
||||||
DEFINE_SYSCALL (sys_proc_test) {
|
DEFINE_SYSCALL (sys_proc_test) {
|
||||||
DEBUG ("test syscall message!\n");
|
DEBUG ("test syscall message!\n");
|
||||||
return SR_OK;
|
return SR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* int proc_map (uintptr_t vaddr, size_t pages, uint32_t flags) */
|
||||||
|
DEFINE_SYSCALL (sys_proc_map) {
|
||||||
|
uintptr_t vaddr = a1;
|
||||||
|
size_t pages = (size_t)a2;
|
||||||
|
uint32_t flags = (uint32_t)a3;
|
||||||
|
|
||||||
|
if (vaddr % PAGE_SIZE != 0)
|
||||||
|
return -SR_UNALIGNED;
|
||||||
|
|
||||||
|
uintptr_t paddr = pmm_alloc (pages);
|
||||||
|
if (paddr == PMM_ALLOC_ERR)
|
||||||
|
return -SR_OOM_ERROR;
|
||||||
|
|
||||||
|
bool ok = proc_map (proc, paddr, vaddr, pages, flags);
|
||||||
|
return ok ? SR_OK : -SR_OOM_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* int proc_unmap (uintptr_t vaddr, size_t pages) */
|
||||||
|
DEFINE_SYSCALL (sys_proc_unmap) {
|
||||||
|
uintptr_t vaddr = a1;
|
||||||
|
size_t pages = (size_t)a2;
|
||||||
|
|
||||||
|
if (vaddr % PAGE_SIZE != 0)
|
||||||
|
return -SR_UNALIGNED;
|
||||||
|
|
||||||
|
bool ok = proc_unmap (proc, vaddr, pages);
|
||||||
|
return ok ? SR_OK : -SR_OOM_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
static syscall_handler_func_t handler_table[] = {
|
static syscall_handler_func_t handler_table[] = {
|
||||||
[SYS_PROC_QUIT] = &sys_proc_quit,
|
[SYS_PROC_QUIT] = &sys_proc_quit,
|
||||||
[SYS_PROC_TEST] = &sys_proc_test,
|
[SYS_PROC_TEST] = &sys_proc_test,
|
||||||
|
[SYS_PROC_MAP] = &sys_proc_map,
|
||||||
|
[SYS_PROC_UNMAP] = &sys_proc_unmap,
|
||||||
};
|
};
|
||||||
|
|
||||||
syscall_handler_func_t syscall_find_handler (int syscall_num) {
|
syscall_handler_func_t syscall_find_handler (int syscall_num) {
|
||||||
|
|||||||
@@ -5,18 +5,13 @@
|
|||||||
int msl_amd64_syscall (int syscall_num, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4,
|
int msl_amd64_syscall (int syscall_num, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4,
|
||||||
uintptr_t a5, uintptr_t a6) {
|
uintptr_t a5, uintptr_t a6) {
|
||||||
uint64_t result;
|
uint64_t result;
|
||||||
__asm__ volatile ("movq %1, %%rax\n"
|
__asm__ volatile ("movq %[a4], %%r10\n"
|
||||||
"movq %2, %%rdi\n"
|
"movq %[a5], %%r8\n"
|
||||||
"movq %3, %%rsi\n"
|
"movq %[a6], %%r9\n"
|
||||||
"movq %4, %%rdx\n"
|
|
||||||
"movq %5, %%r10\n"
|
|
||||||
"movq %6, %%r8\n"
|
|
||||||
"movq %7, %%r9\n"
|
|
||||||
"syscall\n"
|
"syscall\n"
|
||||||
"movq %%rax, %0\n"
|
: "=a"(result)
|
||||||
: "=r"(result)
|
: "a"(syscall_num), "D"(a1), "S"(a2),
|
||||||
: "r"((uint64_t)syscall_num), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5),
|
"d"(a3), [a4] "r"(a4), [a5] "r"(a5), [a6] "r"(a6)
|
||||||
"r"(a6)
|
: "r10", "r8", "r9", "r11", "rcx", "cc", "memory");
|
||||||
: "memory", "cc", "rcx", "r11");
|
|
||||||
return (int)result;
|
return (int)result;
|
||||||
}
|
}
|
||||||
|
|||||||
13
libmsl/m/mem.h
Normal file
13
libmsl/m/mem.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#ifndef _LIBMSL_M_MEM_H
|
||||||
|
#define _LIBMSL_M_MEM_H
|
||||||
|
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
#define M_PROC_MAP_BASE 0x0000700000000000
|
||||||
|
#define M_PAGE_SIZE 4096
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PM_PRESENT (1 << 0)
|
||||||
|
#define PM_RW (1 << 1)
|
||||||
|
#define PM_USER (1 << 2)
|
||||||
|
|
||||||
|
#endif // _LIBMSL_M_MEM_H
|
||||||
@@ -1,6 +1,16 @@
|
|||||||
#include <m/syscall.h>
|
#include <m/syscall.h>
|
||||||
#include <m/syscall_defs.h>
|
#include <m/syscall_defs.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
int m_proc_quit (void) { return m_syscall (SYS_PROC_QUIT, 0, 0, 0, 0, 0, 0); }
|
int m_proc_quit (void) { return m_syscall (SYS_PROC_QUIT, 0, 0, 0, 0, 0, 0); }
|
||||||
|
|
||||||
int m_proc_test (void) { return m_syscall (SYS_PROC_TEST, 0, 0, 0, 0, 0, 0); }
|
int m_proc_test (void) { return m_syscall (SYS_PROC_TEST, 0, 0, 0, 0, 0, 0); }
|
||||||
|
|
||||||
|
int m_proc_map (uintptr_t vaddr, size_t pages, uint32_t flags) {
|
||||||
|
return m_syscall (SYS_PROC_MAP, vaddr, (uintptr_t)pages, (uintptr_t)flags, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int m_proc_unmap (uintptr_t vaddr, size_t pages) {
|
||||||
|
return m_syscall (SYS_PROC_UNMAP, vaddr, (uintptr_t)pages, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
#ifndef _LIBMSL_M_PROC_H
|
#ifndef _LIBMSL_M_PROC_H
|
||||||
#define _LIBMSL_M_PROC_H
|
#define _LIBMSL_M_PROC_H
|
||||||
|
|
||||||
int m_proc_quit (void);
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
int m_proc_quit (void);
|
||||||
int m_proc_test (void);
|
int m_proc_test (void);
|
||||||
|
int m_proc_map (uintptr_t vaddr, size_t pages, uint32_t flags);
|
||||||
|
int m_proc_unmap (uintptr_t vaddr, size_t pages);
|
||||||
|
|
||||||
#endif // _LIBMSL_M_PROC_H
|
#endif // _LIBMSL_M_PROC_H
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
include $(platform)/src.mk
|
include $(platform)/src.mk
|
||||||
include init/src.mk
|
include init/src.mk
|
||||||
include m/src.mk
|
include m/src.mk
|
||||||
|
include string/src.mk
|
||||||
|
|||||||
1
libmsl/string/.gitignore
vendored
Normal file
1
libmsl/string/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
*.o
|
||||||
3
libmsl/string/src.mk
Normal file
3
libmsl/string/src.mk
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
c += string/string.c
|
||||||
|
|
||||||
|
o += string/string.o
|
||||||
47
libmsl/string/string.c
Normal file
47
libmsl/string/string.c
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string/string.h>
|
||||||
|
|
||||||
|
size_t memset (void* dst, uint8_t b, size_t n) {
|
||||||
|
uint8_t* dst1 = dst;
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
dst1[i] = b;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t memcpy (void* dst, const void* src, size_t n) {
|
||||||
|
uint8_t* dst1 = dst;
|
||||||
|
const uint8_t* src1 = src;
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
dst1[i] = src1[i];
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SOURCE: https://stackoverflow.com/a/48967408
|
||||||
|
void strncpy (char* dst, const char* src, size_t n) {
|
||||||
|
size_t i = 0;
|
||||||
|
while (i++ != n && (*dst++ = *src++))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t strlen (const char* str) {
|
||||||
|
const char* s;
|
||||||
|
for (s = str; *s; ++s)
|
||||||
|
;
|
||||||
|
return (s - str);
|
||||||
|
}
|
||||||
|
|
||||||
|
int memcmp (const void* s1, const void* s2, size_t n) {
|
||||||
|
unsigned char* p = (unsigned char*)s1;
|
||||||
|
unsigned char* q = (unsigned char*)s2;
|
||||||
|
|
||||||
|
while (n--) {
|
||||||
|
if (*p != *q) {
|
||||||
|
return (int)*p - (int)*q;
|
||||||
|
}
|
||||||
|
p++, q++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
13
libmsl/string/string.h
Normal file
13
libmsl/string/string.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#ifndef _LIBMSL_STRING_STRING_H
|
||||||
|
#define _LIBMSL_STRING_STRING_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
size_t memset (void* dst, uint8_t b, size_t n);
|
||||||
|
size_t memcpy (void* dst, const void* src, size_t n);
|
||||||
|
void strncpy (char* dst, const char* src, size_t n);
|
||||||
|
size_t strlen (const char* str);
|
||||||
|
int memcmp (const void* s1, const void* s2, size_t n);
|
||||||
|
|
||||||
|
#endif // _LIBMSL_STRING_STRING_H
|
||||||
Reference in New Issue
Block a user