13,747 bytes added
, 13:08, 29 March 2013
@SVC
==
= 系统调用 =
{| class="wikitable" border="1"
|-
! 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|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 ==
{| class="wikitable" border="1"
! 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 ==
{| class="wikitable" border="1"
! Page flags
! Bit
|-
| LOCKED
| 0
|-
| CHANGED
| 1
|}
== 枚举MemoryOperation ==
{| class="wikitable" border="1"
! 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 ==
{| class="wikitable" border="1"
! Memory permission
! Id
|-
| NONE
| 0
|-
| READ
| 1
|-
| WRITE
| 2
|-
| READWRITE
| 3
|-
| DONTCARE
| 0x10000000
|}
== 枚举ResetType ==
{| class="wikitable" border="1"
! Reset type
! Id
|-
| ONESHOT
| 0
|-
| STICKY
| 1
|-
| PULSE
| 2
|}
== 结构MemoryInfo ==
{| class="wikitable" border="1"
! Type
! Field
|-
| u32
| Base address
|-
| u32
| Size
|-
| u32
| Permission
|-
| enum MemoryState
| State
|}
== 结构PageInfo ==
{| class="wikitable" border="1"
! Type
! Field
|-
| u32
| Flags
|}
== 结构StartupInfo ==
{| class="wikitable" border="1"
! Type
! Field
|-
| s32
| Priority
|-
| u32
| Stack size
|-
| s32
| argc
|-
| s16*
| argv
|-
| s16*
| envp
|}
= 进程 =
任何进程只能使用在[[NCCH#CXI|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[[Memory_layout|堆]]。低八位是类型: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为启动[[FIRM|固件]]初始化programID,然后触发启动[[FIRM|固件]]。参数0和参数2没有使用。参数1是programID低位,而programID的高位时0x00040138。
类型3用于给启动的[[FIRM|固件]]初始化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。