Difference between revisions of "Safemode"
Line 47: | Line 47: | ||
Safemode sets up service sessions for [[NS_Services|ns:su]] and [[Network_Interface_services#nifm:u|nifm:u]]. | Safemode sets up service sessions for [[NS_Services|ns:su]] and [[Network_Interface_services#nifm:u|nifm:u]]. | ||
− | It calls [[Network_Interface_services#nifm:u|CreateRequest ]] with '''request_id''' 0x02. | + | It calls [[Network_Interface_services#nifm:u|CreateRequest]] with '''request_id''' 0x02. |
Then calls [[Network_Interface_services#nifm:u|GetSystemEventReadableHandles]] on the returned [[Network_Interface_services#IRequest|IRequest]] and creates an event object. | Then calls [[Network_Interface_services#nifm:u|GetSystemEventReadableHandles]] on the returned [[Network_Interface_services#IRequest|IRequest]] and creates an event object. | ||
Line 55: | Line 55: | ||
After submitting the first request, safemode repeats the request process again and waits for it to finish. If the request fails to finish at this point, [[PCV_services#bpc|RebootSystem]] is called. | After submitting the first request, safemode repeats the request process again and waits for it to finish. If the request fails to finish at this point, [[PCV_services#bpc|RebootSystem]] is called. | ||
− | It calls [[NS_Services#ns:su| | + | It calls [[NS_Services#ns:su|OpenSystemUpdateControl]] and creates a system update event by calling: |
* [[Network_Interface_services#nifm:u|GetClientId]] to obtain the current client's ID; | * [[Network_Interface_services#nifm:u|GetClientId]] to obtain the current client's ID; | ||
* [[Network_Interface_services#nifm:u|IsAnyInternetRequestAccepted]] with the returned client ID (if no request was accepted, error 0x2A810 is returned); | * [[Network_Interface_services#nifm:u|IsAnyInternetRequestAccepted]] with the returned client ID (if no request was accepted, error 0x2A810 is returned); | ||
− | * [[NS_Services# | + | * [[NS_Services#ISystemUpdateControl|RequestDownloadLatestUpdate]]. |
− | After this, an event object is created and safemode loops waiting on it while calling [[NS_Services#ns:su| | + | After this, an event object is created and safemode loops waiting on it while calling [[NS_Services#ns:su|GetDownloadProgress]]. |
− | When the system update event is signalled, safemode calls [[NS_Services#ns:su| | + | When the system update event is signalled, safemode calls [[NS_Services#ns:su|GetBackgroundNetworkUpdateState]] and if this fails, [[PCV_services#bpc|RebootSystem]] is called. |
− | Finally, [[NS_Services# | + | Finally, [[NS_Services#ISystemUpdateControl|ApplyDownloadedUpdate]] is called and the process exits. |
Revision as of 21:46, 24 March 2018
This process was added in firmware version 4.0.0.
Safemode can be launched by a button combo at boot and has the task of performing any pending system updates.
Initialization
It calls GetServiceDiscoveryControlSettings to check whether updates need to be installed or not. If no updates need to be installed it calls RebootSystem, otherwise, the process continues.
It creates and starts a new thread with the sole purpose of setting up the display and showing a progress bar using raw graphics data embedded in the sysmodule's binary.
The display is configured as follows:
*(u32 *)DC_CMD_DISPLAY_WINDOW_HEADER = 0x00000040; // WINDOW_C_SELECT *(u32 *)DC_WIN_WIN_OPTIONS = 0x00000000; // NO_OPTIONS *(u32 *)DC_CMD_DISPLAY_WINDOW_HEADER = 0x00000020; // WINDOW_B_SELECT *(u32 *)DC_WIN_WIN_OPTIONS = 0x00000000; // NO_OPTIONS *(u32 *)DC_CMD_DISPLAY_WINDOW_HEADER = 0x00000010; // WINDOW_A_SELECT *(u32 *)DC_WIN_WIN_OPTIONS = 0x00000000; // NO_OPTIONS *(u32 *)DC_DISP_DISP_WIN_OPTIONS = 0x20000000; // DSI_ENABLE *(u32 *)DC_WIN_COLOR_DEPTH = 0x0000000D; // WIN_COLOR_DEPTH_R8G8B8A8 *(u32 *)DC_WIN_WIN_OPTIONS = 0x00000000; // NO_OPTIONS *(u32 *)DC_WIN_WIN_OPTIONS = 0x00000000; // NO_OPTIONS *(u32 *)DC_WIN_POSITION = 0x00000000; *(u32 *)DC_WIN_H_INITIAL_DDA = 0x00000000; *(u32 *)DC_WIN_V_INITIAL_DDA = 0x00000000; *(u32 *)DC_WIN_PRESCALED_SIZE = 0x05000B40; // H_PRESCALED_SIZE=1280, V_PRESCALED_SIZE=2880 *(u32 *)DC_WIN_DDA_INCREMENT = 0x10001000; // H_DDA_INC=0x1000, V_DDA_INC=0x1000 *(u32 *)DC_WIN_SIZE = 0x050002D0; // H_SIZE=1280, V_SIZE=720 *(u32 *)DC_WIN_LINE_STRIDE = 0x06000C00; // UV_LINE_STRIDE=0x600, LINE_STRIDE=0xC00 *(u32 *)DC_WIN_BUFFER_CONTROL = 0x00000000; // BUFFER_CONTROL_HOST *(u32 *)DC_WIN_BUFFER_SURFACE_KIND = 0x00000000; // DC_WIN_BUFFER_SURFACE_PITCH *(u32 *)DC_WINBUF_START_ADDR = 0xC0000000; *(u32 *)DC_WINBUF_ADDR_H_OFFSET = 0x00000000; *(u32 *)DC_WINBUF_ADDR_V_OFFSET = 0x00000000; *(u32 *)DC_WIN_WIN_OPTIONS = 0x00000000; // NO_OPTIONS *(u32 *)DC_DISP_DISP_WIN_OPTIONS = 0x20000000; // DSI_ENABLE *(u32 *)DC_WIN_WIN_OPTIONS = 0x00000000; // NO_OPTIONS *(u32 *)DC_DISP_DISP_WIN_OPTIONS = 0x20000000; // DSI_ENABLE *(u32 *)DC_WIN_WIN_OPTIONS = 0x00000000; // NO_OPTIONS *(u32 *)DC_DISP_DISP_WIN_OPTIONS = 0x20000000; // DSI_ENABLE *(u32 *)DC_WIN_WIN_OPTIONS = 0x40000000; // WIN_ENABLE *(u32 *)DC_CMD_DISPLAY_COMMAND = 0x00000020; // DISP_CTRL_MODE_C_DISPLAY *(u32 *)DC_CMD_STATE_CONTROL = 0x00000300; // GENERAL_UPDATE | WIN_A_UPDATE *(u32 *)DC_CMD_STATE_CONTROL = 0x00000003; // GENERAL_ACT_REQ | WIN_A_ACT_REQ
While this thread is running, safemode proceeds with the actual update process.
System update
Safemode sets up service sessions for ns:su and nifm:u.
It calls CreateRequest with request_id 0x02.
Then calls GetSystemEventReadableHandles on the returned IRequest and creates an event object.
It uses GetRequestState and GetResult for synchronizing with the request object, calls Submit on the request and waits for it to finish.
After submitting the first request, safemode repeats the request process again and waits for it to finish. If the request fails to finish at this point, RebootSystem is called.
It calls OpenSystemUpdateControl and creates a system update event by calling:
- GetClientId to obtain the current client's ID;
- IsAnyInternetRequestAccepted with the returned client ID (if no request was accepted, error 0x2A810 is returned);
- RequestDownloadLatestUpdate.
After this, an event object is created and safemode loops waiting on it while calling GetDownloadProgress.
When the system update event is signalled, safemode calls GetBackgroundNetworkUpdateState and if this fails, RebootSystem is called.
Finally, ApplyDownloadedUpdate is called and the process exits.