系统调用列表
系统调用
Id | Description |
---|---|
0x1 | Result ControlMemory(u32* outaddr, u32 addr0, u32 addr1, u32 size, u32 operation, u32 permissions) (outaddr is usually the same as the input addr0) |
0x2 | Result QueryMemory(MemoryInfo* info, PageInfo* out, u32 Addr) |
0x3 | void ExitProcess(void) |
0x4 | Result GetProcessAffinityMask(u8* affinitymask, Handle process, s32 processorcount) |
0x5 | Result SetProcessAffinityMask(Handle process, u8* affinitymask, s32 processorcount) |
0x6 | Result GetProcessIdealProcessor(s32 *idealprocessor, Handle process) |
0x7 | Result SetProcessIdealProcessor(Handle process, s32 idealprocessor) |
0x8 | Result CreateThread(Handle* thread, func entrypoint, u32 arg, u32 stacktop, s32 threadpriority, s32 processorid) |
0x9 | void ExitThread(void) |
0xA | void SleepThread(s64 nanoseconds) |
0xB | Result GetThreadPriority(s32* priority, Handle thread) |
0xC | Result SetThreadPriority(Handle thread, s32 priority) |
0xD | Result GetThreadAffinityMask(u8* affinitymask, Handle thread, s32 processorcount) |
0xE | Result SetThreadAffinityMask(Handle thread, u8* affinitymask, s32 processorcount) |
0xF | Result GetThreadIdealProcessor(s32* processorid, Handle thread) |
0x10 | Result SetThreadIdealProcessor(Handle thread, s32 processorid) |
0x11 | s32 GetCurrentProcessorNumber(void) |
0x12 | Result Run(Handle process, StartupInfo* info) (This starts the main() thread. Buf+0 is main-thread priority, Buf+4 is main-thread stack-size.) |
0x13 | Result CreateMutex(Handle* mutex, bool initialLocked) |
0x14 | Result ReleaseMutex(Handle mutex) |
0x15 | Result CreateSemaphore(Handle* semaphore, s32 initialCount, s32 maxCount) |
0x16 | Result ReleaseSemaphore(s32* count, Handle semaphore, s32 releaseCount) |
0x17 | Result CreateEvent(Handle* event, ResetType resettype) |
0x18 | Result SignalEvent(Handle event) |
0x19 | Result ClearEvent(Handle event) |
0x1A | Result CreateTimer(Handle* timer, ResetType resettype) |
0x1B | Result SetTimer(Handle timer, s64 initial, s64 interval) |
0x1C | Result CancelTimer(Handle timer) |
0x1D | Result ClearTimer(Handle timer) |
0x1E | Result CreateMemoryBlock(Handle* memblock, u32 memory, u32 size, u32 mypermission, u32 otherpermission) |
0x1F | Result MapMemoryBlock(Handle memblock, u32 addr, u32 mypermissions, u32 otherpermission) |
0x20 | Result UnmapMemoryBlock(Handle memblock, u32 addr) |
0x21 | Result CreateAddressArbiter(Handle* arbiter) |
0x22 | Result ArbitrateAddress(Handle arbiter, u32 addr, ArbitrationType type, s32 value) |
0x23 | Result CloseHandle(Handle handle) |
0x24 | Result WaitSynchronization1(Handle handle, s64 nanoseconds) |
0x25 | Result WaitSynchronizationN(s32* out, Handle* handles, s32 handlecount, bool waitAll, s64 nanoseconds) |
0x26 | Result SignalAndWait(s32* out, Handle signal, Handle* handles, s32 handleCount, bool waitAll, s64 nanoseconds) |
0x27 | Result DuplicateHandle(Handle* out, Handle original) |
0x28 | s64 GetSystemTick(void) |
0x29 | Result GetHandleInfo(s64* out, Handle handle, HandleInfoType type) |
0x2A | Result GetSystemInfo(s64* out, SystemInfoType type, s32 param) |
0x2B | Result GetProcessInfo(s64* out, Handle process, ProcessInfoType type) |
0x2C | Result GetThreadInfo(s64* out, Handle thread, ThreadInfoType type) |
0x2D | Result ConnectToPort(Handle* out, const char* portName) |
0x2E | Result SendSyncRequest1(Handle session) (Stubbed) |
0x2F | Result SendSyncRequest2(Handle session) (Stubbed) |
0x30 | Result SendSyncRequest3(Handle session) (Stubbed) |
0x31 | Result SendSyncRequest4(Handle session) (Stubbed) |
0x32 | Result SendSyncRequest(Handle session) |
0x33 | Result OpenProcess(Handle* process, u32 processId) |
0x34 | Result OpenThread(Handle* thread, Handle process, u32 threadId) |
0x35 | Result GetProcessId(u32* processId, Handle process) |
0x36 | Result GetProcessIdOfThread(u32* processId, Handle thread) |
0x37 | Result GetThreadId(u32* threadId, Handle thread) |
0x38 | Result GetResourceLimit(Handle* resourceLimit, Handle process) |
0x39 | Result GetResourceLimitLimitValues(s64* values, Handle resourceLimit, LimitableResource* names, s32 nameCount) |
0x3A | Result GetResourceLimitCurrentValues(s64* values, Handle resourceLimit, LimitableResource* names, s32 nameCount) |
0x3B | Result GetThreadContext(ThreadContext* context, Handle thread) (Stubbed) |
0x3C | Break(BreakReason) |
0x3D | OutputDebugString(void const, int) (Does nothing on non-debug units) |
0x3E | ControlPerformanceCounter(unsigned long long, int, unsigned int, unsigned long long) |
0x47 | Result CreatePort(Handle* portServer, Handle* portClient, const char* name, s32 maxSessions) |
0x48 | Result CreateSessionToPort(Handle* session, Handle port) |
0x49 | Result CreateSession(Handle* sessionServer, Handle* sessionClient) |
0x4A | Result AcceptSession(Handle* session, Handle port) |
0x4B | Result ReplyAndReceive1(s32* index, Handle* handles, s32 handleCount, Handle replyTarget) (Stubbed) |
0x4C | Result ReplyAndReceive2(s32* index, Handle* handles, s32 handleCount, Handle replyTarget) (Stubbed) |
0x4D | Result ReplyAndReceive3(s32* index, Handle* handles, s32 handleCount, Handle replyTarget) (Stubbed) |
0x4E | Result ReplyAndReceive4(s32* index, Handle* handles, s32 handleCount, Handle replyTarget) (Stubbed) |
0x4F | Result ReplyAndReceive(s32* index, Handle* handles, s32 handleCount, Handle replyTarget) |
0x50 | Result BindInterrupt(Interrupt name, Handle syncObject, s32 priority, bool isManualClear) |
0x51 | Result UnbindInterrupt(Interrupt name, Handle syncObject) |
0x52 | Result InvalidateProcessDataCache(Handle process, void* addr, u32 size) |
0x53 | Result StoreProcessDataCache(Handle process, void const* addr, u32 size) |
0x54 | Result FlushProcessDataCache(Handle process, void const* addr, u32 size) |
0x55 | Result StartInterProcessDma(Handle* dma, Handle dstProcess, void* dst, Handle srcProcess, const void* src, u32 size, const DmaConfig& config ) |
0x56 | Result StopDma(Handle dma) |
0x57 | Result GetDmaState(DmaState* state, Handle dma) |
0x58 | RestartDma(nn::Handle, void *, void const*, unsigned int, signed char) |
0x60 | Result DebugActiveProcess(Handle* debug, u32 processID) |
0x61 | Result BreakDebugProcess(Handle debug) |
0x62 | Result TerminateDebugProcess(Handle debug) |
0x63 | Result GetProcessDebugEvent(DebugEventInfo* info, Handle debug) |
0x64 | Result ContinueDebugEvent(Handle debug, u32 flags) |
0x65 | Result GetProcessList(s32* processCount, u32* processIds, s32 processIdMaxCount) |
0x66 | Result GetThreadList(s32* threadCount, u32* threadIds, s32 threadIdMaxCount, Handle domain) |
0x67 | Result GetDebugThreadContext(ThreadContext* context, Handle debug, u32 threadId, u32 controlFlags) |
0x68 | Result SetDebugThreadContext(Handle debug, u32 threadId, ThreadContext* context, u32 controlFlags) |
0x69 | Result QueryDebugProcessMemory(MemoryInfo* blockInfo, PageInfo* pageInfo, Handle process, u32 addr) |
0x6A | Result ReadProcessMemory(void* buffer, Handle debug, u32 addr, u32 size) |
0x6B | Result WriteProcessMemory(Handle debug, void const* buffer, u32 addr, u32 size) |
0x6C | Result SetHardwareBreakPoint(s32 registerId, u32 control, u32 value) |
0x6D | GetDebugThreadParam(long long *, int *, nn::Handle, unsigned int, nn::dmnt::DebugThreadParam) (Disabled on regular kernel) |
0x70 | ControlProcessMemory(Handle KProcess, unsigned int Addr0, unsigned int Addr1, unsigned int Size, unsigned int Type, unsigned int Permissions) |
0x71 | MapProcessMemory(Handle KProcess, unsigned int StartAddr, unsigned int EndAddr) |
0x72 | UnmapProcessMemory(Handle KProcess, unsigned int StartAddr, unsigned int EndAddr) |
0x73 | ? |
0x74 | Stubbed on regular kernel |
0x75 | ? |
0x76 | TerminateProcess(Handle) |
0x77 | (Handle KProcess, Handle KResourceLimit) |
0x78 | CreateResourceLimit(Handle *KResourceLimit) |
0x79 | ? |
0x7A | DisableExecuteNever(unsigned int Addr, unsigned int Size) (Stubbed for regular kernel beginning with 2.0.0-2) |
0x7C | KernelSetState(unsigned int Type, unsigned int Param0, unsigned int Param1, unsigned int Param2) (The Type determines the usage of each param) |
0x7D | QueryProcessMemory(MemInfo *Info, unsigned int *Out, Handle KProcess, unsigned int Addr) |
0xFF | Debug related (The Syscall access control mask doesn't apply for this SVC) |
新建线程
R0=s32 threadpriority R1=func entrypoint R2=u32 arg R3=u32 stacktop R4=s32 processorid
Result result=R0 Handle* thread=R1
类型和结构
枚举MemoryState
Memory state flags | Bit |
---|---|
FREE | 0 |
RESERVED | 1 |
IO | 2 |
STATIC | 3 |
CODE | 4 |
PRIVATE | 5 |
SHARED | 6 |
CONTINUOUS | 7 |
ALIASED | 8 |
ALIAS | 9 |
ALIAS CODE | 10 |
LOCKED | 11 |
枚举PageFlags
Page flags | Bit |
---|---|
LOCKED | 0 |
CHANGED | 1 |
枚举MemoryOperation
Memory operation | Id |
---|---|
FREE | 1 |
RESERVE | 2 |
COMMIT | 3 |
MAP | 4 |
UNMAP | 5 |
PROTECT | 6 |
REGION APP | 0x100 |
REGION SYSTEM | 0x200 |
REGION BASE | 0x300 |
LINEAR | 0x1000 |
枚举MemoryPermission
Memory permission | Id |
---|---|
NONE | 0 |
READ | 1 |
WRITE | 2 |
READWRITE | 3 |
DONTCARE | 0x10000000 |
枚举ResetType
Reset type | Id |
---|---|
ONESHOT | 0 |
STICKY | 1 |
PULSE | 2 |
结构MemoryInfo
Type | Field |
---|---|
u32 | Base address |
u32 | Size |
u32 | Permission |
enum MemoryState | State |
结构PageInfo
Type | Field |
---|---|
u32 | Flags |
结构StartupInfo
Type | Field |
---|---|
s32 | Priority |
u32 | Stack size |
s32 | argc |
s16* | argv |
s16* | envp |
进程
任何进程只能使用在exheader中为本进程启用的SVCs。ARM11内核SVN句柄会在SVC模式的栈中检查系统访问控制掩码以确定SVC是否已经启用,SVC没有启用时会触发kernelpanic。每个进程都有独立的SVC模式栈,这个栈和存放其中的系统访问控制掩码是在进程启动时候初始化的。应用程序一般只有那些<=0x3D的SVC访问权限,不过并非所有应用程序都有<=0x3D的所有SVCs权限。大部分应用程序可访问的SVCs并没有被应用程序使用。
每个进程都有各自的句柄表,表达大小存在exheader里面。在句柄表中的句柄不能被其他进程的上下文使用,因为这些句柄并不存在于其他的句柄表中。
0xFFFF8001是当前KProcess的句柄别称,而0xFFFF8000则是当前KThread的句柄别称。
在零售版机器上调用svcBreak只能造成调用这个SVC的进程被终止。
线程
对于svcCreateThread,用于Entrypoint_Param和StackTop输入地址常常一样,不过这可以任意设置。比如主线程的Entrypoint_Param就是0值。
用KThread句柄调用CloseHandle()会终结指定的线程。
内存映射
ControlMemory和MapMemoryBlock可以在映射内存页面时使用,这两个SVCs只支持映射不可执行的R/W页面。为这两个SVCs输入的权限和参数必须<=3,如果要取消映射,需要使用0值。对于ControlMemory参数MemoryType的位码0xF00是内存类型,该位使用0的时候,会从exheader中ARM11内核描述的内核标记中,为使用此SVC的进程读取内存类型。ControlMemory参数MemoryType取值0x10003对应的是映射GSP堆。低八位是类型:1是未映射内存,3是已经映射的内存;类型4用于备份,从Addr1到Addr0的RW内存,如果Addr1在只读区域,类型4会返回一个错误。Addr1在类型1和3中不使用。
ControlProcessMemory映射指定进程的内存,只是唯一允许映射可执行区域内存的SVC。内存映射SVC的权限格式为bit0=R, bit1=W, bit2=X。类型6设置Addr0已经映射的内存权限到输入权限。
MapProcessMemory映射指定KProcess由当前进程指定的StartAddr从0x00100000开始的RW内存。MapProcessMemory之后会映射指定进程的0x08000000到当前进程StartAddr+0x7f00000的内存。UnmapProcessMemory则取消MapProcessMemory映射的内存。
调试
DebugActiveProcess用于调试时附加进程。这个SVC只有在目标进程的exheader的ARM11描述中设置了"Enable debug"才能调用。如果目标进程的那个标记是零,那么调用这个SVC的进程必须有设置内核标记的"Force debug"标记为一才行。
KernelSetState
类型0为启动固件初始化programID,然后触发启动固件。参数0和参数2没有使用。参数1是programID低位,而programID的高位时0x00040138。
类型3用于给启动的固件初始化0x1000字节的缓存。参数2没用。当参数0为1时候,缓存会复制到FCRAM的0xF0000000开始的地址,参数1没用。当参数0为0,这段内核缓存会映射到进程地址参数1。
GetSystemInfo
类型0值为26(类型1没用)会将直接由内核启动的进程总数写到输出。对于NATIVE_FIRM/SAFE_MODE_FIRM固件的ARM11内核,结果常为5,也即是进程sm,fs,pm,loader,和pxi。