Implemented heap, transfer memory, bsd cmd0

This commit is contained in:
plutoo 2017-09-10 23:17:57 +02:00
parent 0d8a5a6839
commit 30650b5d69
9 changed files with 174 additions and 1 deletions

View File

@ -24,7 +24,7 @@ VERSION := $(LIBNX_MAJOR).$(LIBNX_MINOR).$(LIBNX_PATCH)
#---------------------------------------------------------------------------------
TARGET := nx
#BUILD := build
SOURCES := source/kernel source/services
SOURCES := source/kernel source/services source/heap
DATA := data
INCLUDES := include

View File

@ -12,6 +12,9 @@ extern "C" {
#include <switch/result.h>
#include <switch/svc.h>
#include <switch/ipc.h>
#include <switch/heap.h>
#include <switch/kernel/tmem.h>
#include <switch/services/sm.h>

2
nx/include/switch/heap.h Normal file
View File

@ -0,0 +1,2 @@
void* heapAllocPages(size_t size);
void* heapAlloc(size_t size);

View File

@ -0,0 +1,10 @@
typedef struct {
Handle MemHandle;
size_t Size;
} TransferMemory;
typedef enum {
PERM_NONE = 0,
PERM_R = 1,
PERM_RW = 3
} Permission;

View File

@ -20,6 +20,7 @@ static inline void* armGetTls(void) {
Result svcQueryMemory(u32 *meminfo_ptr, u32 *pageinfo, u64 addr);
Result svcCloseHandle(Handle handle);
Result svcCreateTransferMemory(Handle* out, void* addr, size_t size, u32 perm);
Result svcWaitSynchronization(s32* index, const Handle* handles, s32 handleCount, u64 timeout);
Result svcConnectToNamedPort(Handle* session, const char* name);
Result svcSendSyncRequest(Handle session);

89
nx/source/heap/heap.c Normal file
View File

@ -0,0 +1,89 @@
// Copyright 2017 plutoo
// Worst heap ever xD
#include <switch.h>
typedef struct HeapHeader HeapHeader;
typedef enum {
USED = 0x55534544,
FREE = 0x46524545
} HeapState;
struct HeapHeader {
size_t State;
size_t Size;
HeapHeader* Next;
HeapHeader* Prev;
};
static HeapHeader g_LastFree;
void heapInit(void* base, size_t size) {
// Called by crt0.
HeapHeader* hdr = (HeapHeader*) base;
hdr->Next = &g_LastFree;
hdr->Prev = &g_LastFree;
hdr->Size = size - sizeof(HeapHeader);
hdr->State = FREE;
g_LastFree.Next = hdr;
g_LastFree.Prev = hdr;
}
void* heapAllocPages(size_t size) {
void* ptr = heapAlloc(size + 0x1000);
if (ptr != NULL) {
ptr = (void*) ((((uintptr_t) ptr) + 0xFFF) &~ 0xFFF);
}
return ptr;
}
void* heapAlloc(size_t size) {
size = (size + 15) &~ 15;
HeapHeader* hdr = &g_LastFree;
while ((hdr = hdr->Next) != &g_LastFree) {
if (hdr->Size >= size) {
size_t rem = hdr->Size - size;
if (rem < sizeof(HeapHeader)) {
size = hdr->Size;
rem = 0;
}
hdr->State = USED;
hdr->Size = size;
hdr->Prev->Next = hdr->Next;
hdr->Next->Prev = hdr->Prev;
if (rem != 0) {
HeapHeader* rem_hdr = (HeapHeader*) (((uintptr_t)(hdr + 1)) + size);
rem_hdr->State = FREE;
rem_hdr->Size = rem - sizeof(HeapHeader);
rem_hdr->Next = g_LastFree.Next;
rem_hdr->Prev = &g_LastFree;
g_LastFree.Next = rem_hdr;
}
return (void*) (((uintptr_t) hdr) + sizeof(HeapHeader));
}
}
return NULL;
}
void heapFree(void* ptr) {
HeapHeader* hdr = (HeapHeader*) (((uintptr_t) ptr) - sizeof(HeapHeader));
hdr->State = FREE;
hdr->Next = g_LastFree.Next;
g_LastFree.Next = hdr;
hdr->Prev = &g_LastFree;
}

View File

@ -24,6 +24,14 @@ SVC_BEGIN svcCloseHandle
ret
SVC_END
SVC_BEGIN svcCreateTransferMemory
str x0, [sp, #-16]!
svc 0x15
ldr x2, [sp], #16
str w1, [x2]
ret
SVC_END
SVC_BEGIN svcWaitSynchronization
str x0, [sp, #-16]!
svc 0x18

21
nx/source/kernel/tmem.c Normal file
View File

@ -0,0 +1,21 @@
#include <switch.h>
Result tmemCreate(TransferMemory* t, size_t size, Permission perm) {
t->Size = size;
Result rc = 0;
void* addr = heapAllocPages(size);
if (addr == NULL)
rc = -1;
if (R_SUCCEEDED(rc)) {
rc = svcCreateTransferMemory(&t->MemHandle, addr, size, perm);
}
return rc;
}
Result tmemClose(TransferMemory* t) {
return svcCloseHandle(t->MemHandle);
}

39
nx/source/services/bsd.c Normal file
View File

@ -0,0 +1,39 @@
// Copyright 2017 plutoo
#include <switch.h>
static Handle g_bsdHandle = -1;
Result bsdInitialize(TransferMemory* tmem) {
Result rc = smGetService(&g_bsdHandle, "bsd:s");
if (R_FAILED(rc)) {
rc = smGetService(&g_bsdHandle, "bsd:u");
}
if (R_SUCCEEDED(rc)) {
IpcCommand c;
ipcInitialize(&c);
ipcSendPid(&c);
ipcSendHandleCopy(&c, tmem->MemHandle);
struct {
u64 magic;
u64 cmd_id;
u64 unk[5];
u64 tmem_sz;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 0;
raw->unk[0] = 0;
raw->unk[1] = 0;
raw->unk[2] = 0;
raw->unk[3] = 0;
raw->unk[4] = 0;
raw->tmem_sz = tmem->Size;
}
return rc;
}