mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 12:32:40 +02:00
Implemented heap, transfer memory, bsd cmd0
This commit is contained in:
parent
0d8a5a6839
commit
30650b5d69
@ -24,7 +24,7 @@ VERSION := $(LIBNX_MAJOR).$(LIBNX_MINOR).$(LIBNX_PATCH)
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
TARGET := nx
|
TARGET := nx
|
||||||
#BUILD := build
|
#BUILD := build
|
||||||
SOURCES := source/kernel source/services
|
SOURCES := source/kernel source/services source/heap
|
||||||
|
|
||||||
DATA := data
|
DATA := data
|
||||||
INCLUDES := include
|
INCLUDES := include
|
||||||
|
@ -12,6 +12,9 @@ extern "C" {
|
|||||||
#include <switch/result.h>
|
#include <switch/result.h>
|
||||||
#include <switch/svc.h>
|
#include <switch/svc.h>
|
||||||
#include <switch/ipc.h>
|
#include <switch/ipc.h>
|
||||||
|
#include <switch/heap.h>
|
||||||
|
|
||||||
|
#include <switch/kernel/tmem.h>
|
||||||
|
|
||||||
#include <switch/services/sm.h>
|
#include <switch/services/sm.h>
|
||||||
|
|
||||||
|
2
nx/include/switch/heap.h
Normal file
2
nx/include/switch/heap.h
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
void* heapAllocPages(size_t size);
|
||||||
|
void* heapAlloc(size_t size);
|
10
nx/include/switch/kernel/tmem.h
Normal file
10
nx/include/switch/kernel/tmem.h
Normal 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;
|
@ -20,6 +20,7 @@ static inline void* armGetTls(void) {
|
|||||||
|
|
||||||
Result svcQueryMemory(u32 *meminfo_ptr, u32 *pageinfo, u64 addr);
|
Result svcQueryMemory(u32 *meminfo_ptr, u32 *pageinfo, u64 addr);
|
||||||
Result svcCloseHandle(Handle handle);
|
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 svcWaitSynchronization(s32* index, const Handle* handles, s32 handleCount, u64 timeout);
|
||||||
Result svcConnectToNamedPort(Handle* session, const char* name);
|
Result svcConnectToNamedPort(Handle* session, const char* name);
|
||||||
Result svcSendSyncRequest(Handle session);
|
Result svcSendSyncRequest(Handle session);
|
||||||
|
89
nx/source/heap/heap.c
Normal file
89
nx/source/heap/heap.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
@ -24,6 +24,14 @@ SVC_BEGIN svcCloseHandle
|
|||||||
ret
|
ret
|
||||||
SVC_END
|
SVC_END
|
||||||
|
|
||||||
|
SVC_BEGIN svcCreateTransferMemory
|
||||||
|
str x0, [sp, #-16]!
|
||||||
|
svc 0x15
|
||||||
|
ldr x2, [sp], #16
|
||||||
|
str w1, [x2]
|
||||||
|
ret
|
||||||
|
SVC_END
|
||||||
|
|
||||||
SVC_BEGIN svcWaitSynchronization
|
SVC_BEGIN svcWaitSynchronization
|
||||||
str x0, [sp, #-16]!
|
str x0, [sp, #-16]!
|
||||||
svc 0x18
|
svc 0x18
|
||||||
|
21
nx/source/kernel/tmem.c
Normal file
21
nx/source/kernel/tmem.c
Normal 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
39
nx/source/services/bsd.c
Normal 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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user