Changes

Jump to navigation Jump to search
20 bytes added ,  06:45, 20 June 2017
m
Fix heading levels ("Skip Level 1, it is page name level." https://www.mediawiki.org/wiki/Help:Formatting)
Line 1: Line 1:  
The 3DS software stack follows a server/client architecture, where common functionality is provided by global server processes through interfaces called ''ports'' and ''services''. Applications can access this functionality by creating ''sessions'' to the provided services. Technically, this is implemented using ''interprocess communication'' (IPC).
 
The 3DS software stack follows a server/client architecture, where common functionality is provided by global server processes through interfaces called ''ports'' and ''services''. Applications can access this functionality by creating ''sessions'' to the provided services. Technically, this is implemented using ''interprocess communication'' (IPC).
   −
= Concepts =
+
== Concepts ==
   −
== Sessions ==
+
=== Sessions ===
    
Sessions are communication channels consisting of a client and server, through which data can be exchanged in the form of a request and response, respectively. Through sessions, the standard [[#Command Structure|IPC command protocol]] is implemented. Clients use their client session handle to send IPC commands to the server using svcSendSyncRequest, while servers use svcReplyAndReceive to reply. Client sessions can't be used with svcReplyAndReceive. In both cases, the kernel takes care of transferring IPC command data from the [[Thread Local Storage]] of the sending thread to the TLS of the receiving thread. Sessions can be created through svcCreateSession, which provides the caller with the client and server handles.
 
Sessions are communication channels consisting of a client and server, through which data can be exchanged in the form of a request and response, respectively. Through sessions, the standard [[#Command Structure|IPC command protocol]] is implemented. Clients use their client session handle to send IPC commands to the server using svcSendSyncRequest, while servers use svcReplyAndReceive to reply. Client sessions can't be used with svcReplyAndReceive. In both cases, the kernel takes care of transferring IPC command data from the [[Thread Local Storage]] of the sending thread to the TLS of the receiving thread. Sessions can be created through svcCreateSession, which provides the caller with the client and server handles.
Line 9: Line 9:  
Sessions are used in their raw form to implement [[FS:OpenFile|file handles]]. In this case, fs-module creates a raw session using svcCreateSession, and provides the "fs:USER" client with the resulting client session handle, keeping the server session handle for its own use. These sessions expose their [[Filesystem services#File service|own set of IPC commands]] which act on the file that was opened through fs:USER.
 
Sessions are used in their raw form to implement [[FS:OpenFile|file handles]]. In this case, fs-module creates a raw session using svcCreateSession, and provides the "fs:USER" client with the resulting client session handle, keeping the server session handle for its own use. These sessions expose their [[Filesystem services#File service|own set of IPC commands]] which act on the file that was opened through fs:USER.
   −
== Ports ==
+
=== Ports ===
    
Ports are interfaces for managing multiple client sessions to the same high-level server. Ports are created through svcCreatePort, and can be global or private. A global port is created by passing a name for the port to svcCreatePort. Clients can start IPC sessions to global ports by connecting to the port using svcConnectToPort, passing the desired port name. If the port is private, it is not possible to create a session through svcConnectToPort - sessions can only be created if one has a handle to the port itself, obtained from the call to svcCreatePort. When a client wishes to connect to a port (i.e. create a session), the server must accept the new session using svcAcceptSession. The kernel notifies the server whenever a new session is incoming via the server's port handle. The server can wait for this notification through svcWaitSynchronization or svcReplyAndReceive.
 
Ports are interfaces for managing multiple client sessions to the same high-level server. Ports are created through svcCreatePort, and can be global or private. A global port is created by passing a name for the port to svcCreatePort. Clients can start IPC sessions to global ports by connecting to the port using svcConnectToPort, passing the desired port name. If the port is private, it is not possible to create a session through svcConnectToPort - sessions can only be created if one has a handle to the port itself, obtained from the call to svcCreatePort. When a client wishes to connect to a port (i.e. create a session), the server must accept the new session using svcAcceptSession. The kernel notifies the server whenever a new session is incoming via the server's port handle. The server can wait for this notification through svcWaitSynchronization or svcReplyAndReceive.
Line 15: Line 15:  
The two global ports usually found on retail are "srv:" ([[Services|service manager]]) and "err:f" ([[ErrDisp]]).
 
The two global ports usually found on retail are "srv:" ([[Services|service manager]]) and "err:f" ([[ErrDisp]]).
   −
== Services ==
+
=== Services ===
    
Services are an abstraction of ports that are managed by service manager. Services cannot be connected to through svcConnectToPort, as the underlying port is a private port. The service name is instead entirely handled by service manager, and the kernel is not aware of it. Clients are instead expected to open a session to a service using the "srv:" port command [[SRV:GetServiceHandle|GetServiceHandle]]. The client process must pass an access permission check for each service (by name) that it attempts to request a session with. These permissions are granted in the "service access control" of the title's [[NCCH/Extended Header#ARM11 Local System Capabilities|extended header]]. A service is registered with service manager using the command [[SRV:RegisterService|RegisterService]].
 
Services are an abstraction of ports that are managed by service manager. Services cannot be connected to through svcConnectToPort, as the underlying port is a private port. The service name is instead entirely handled by service manager, and the kernel is not aware of it. Clients are instead expected to open a session to a service using the "srv:" port command [[SRV:GetServiceHandle|GetServiceHandle]]. The client process must pass an access permission check for each service (by name) that it attempts to request a session with. These permissions are granted in the "service access control" of the title's [[NCCH/Extended Header#ARM11 Local System Capabilities|extended header]]. A service is registered with service manager using the command [[SRV:RegisterService|RegisterService]].
Line 23: Line 23:  
The majority of 3DS inter-process communication is implemented as services.
 
The majority of 3DS inter-process communication is implemented as services.
   −
== Shared Memory ==
+
=== Shared Memory ===
    
Communication through port/service requests and replies may incur a big bottleneck when exchanging large amounts of data because the kernel needs to transfer the data between the two involved processes. There is hence a complementary feature to share the same physical memory between two processes. For this purpose, one process needs to create a block of shared memory using svcCreateMemoryBlock such that the other process can map it into its own virtual memory address space using svcMapMemoryBlock. The memory block handle for the latter is provided using a regular IPC command.
 
Communication through port/service requests and replies may incur a big bottleneck when exchanging large amounts of data because the kernel needs to transfer the data between the two involved processes. There is hence a complementary feature to share the same physical memory between two processes. For this purpose, one process needs to create a block of shared memory using svcCreateMemoryBlock such that the other process can map it into its own virtual memory address space using svcMapMemoryBlock. The memory block handle for the latter is provided using a regular IPC command.
Line 29: Line 29:  
Many services use shared memory as a secondary command interface (e.g. [[GSP_Shared_Memory|GSP]]), the processing of which is triggered through an IPC request (cf. [[GSPGPU:TriggerCmdReqQueue]]).
 
Many services use shared memory as a secondary command interface (e.g. [[GSP_Shared_Memory|GSP]]), the processing of which is triggered through an IPC request (cf. [[GSPGPU:TriggerCmdReqQueue]]).
   −
= Message Structure =
+
== Message Structure ==
    
IPC requests are written to the [[Thread Local Storage]] at offset 0x80 and submitted using [[SVC|svcSendSyncRequest]]. If the kernel was able to dispatch the request, the server reply will be written to TLS+0x80 before svcSendSyncRequest returns. By convention, the second word of the response data is an error code (or 0 on success). IPC requests and IPC replies follow the same structure.
 
IPC requests are written to the [[Thread Local Storage]] at offset 0x80 and submitted using [[SVC|svcSendSyncRequest]]. If the kernel was able to dispatch the request, the server reply will be written to TLS+0x80 before svcSendSyncRequest returns. By convention, the second word of the response data is an error code (or 0 on success). IPC requests and IPC replies follow the same structure.
Line 90: Line 90:  
For replies, only 0, 1, 5, 6, 7 are allowed. In other words any type 2 fields must be zeroed before calling svcReplyAndReceive on the server-side. For replies, type 0, 1, and 2 are ignored. Types 5, 6, and 7 do something with the mem pointer upon reply. The type 0 descriptor can be used to ignore parameters. The number of parameters covered by a type-0 descriptor is (desc >> 26) + 1.
 
For replies, only 0, 1, 5, 6, 7 are allowed. In other words any type 2 fields must be zeroed before calling svcReplyAndReceive on the server-side. For replies, type 0, 1, and 2 are ignored. Types 5, 6, and 7 do something with the mem pointer upon reply. The type 0 descriptor can be used to ignore parameters. The number of parameters covered by a type-0 descriptor is (desc >> 26) + 1.
   −
== Handle Translation ==
+
=== Handle Translation ===
    
Translation type 0 is used to send handles across processes. The corresponding translation descriptor has the following structure:
 
Translation type 0 is used to send handles across processes. The corresponding translation descriptor has the following structure:
Line 135: Line 135:  
|}
 
|}
   −
== Static Buffer Translation ==
+
=== Static Buffer Translation ===
    
Each thread may set up up to 16 static buffer descriptors in their [[Thread Local Storage]] at offset 0x180. These contain information about buffers in the thread's memory space that may be used for information exchange for communication with other processes. In particular, a static buffer descriptor encodes the address and size of a buffer.
 
Each thread may set up up to 16 static buffer descriptors in their [[Thread Local Storage]] at offset 0x180. These contain information about buffers in the thread's memory space that may be used for information exchange for communication with other processes. In particular, a static buffer descriptor encodes the address and size of a buffer.
Line 171: Line 171:  
|}
 
|}
   −
== Buffer Mapping Translation ==
+
=== Buffer Mapping Translation ===
    
The IPC subsystem can temporarily map a whole buffer of the sender's memory into the receiver's memory space. This is useful for large buffers, for which the overhead of copying static buffer data around would be too expensive.
 
The IPC subsystem can temporarily map a whole buffer of the sender's memory into the receiver's memory space. This is useful for large buffers, for which the overhead of copying static buffer data around would be too expensive.
Line 222: Line 222:  
|}
 
|}
   −
== Usage Examples for other Translation Types ==
+
=== Usage Examples for other Translation Types ===
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
110

edits

Navigation menu