loader: completely rewrite.

This commit is contained in:
Michael Scire
2019-06-26 15:46:19 -07:00
parent 9217e4c5f9
commit 61fcf5e0f4
49 changed files with 2523 additions and 5817 deletions

View File

@@ -29,7 +29,6 @@
#include "pm_registration.hpp"
#include "pm_boot_mode.hpp"
static std::vector<u64> g_launched_titles;
static bool IsHexadecimal(const char *str) {
while (*str) {
@@ -42,23 +41,11 @@ static bool IsHexadecimal(const char *str) {
return true;
}
static bool HasLaunchedTitle(u64 title_id) {
return std::find(g_launched_titles.begin(), g_launched_titles.end(), title_id) != g_launched_titles.end();
}
static void SetLaunchedTitle(u64 title_id) {
g_launched_titles.push_back(title_id);
}
static void ClearLaunchedTitles() {
g_launched_titles.clear();
}
static void LaunchTitle(u64 title_id, FsStorageId storage_id, u32 launch_flags, u64 *pid) {
u64 local_pid = 0;
/* Don't launch a title twice during boot2. */
if (HasLaunchedTitle(title_id)) {
if (Registration::HasLaunchedTitle(title_id)) {
return;
}
@@ -80,8 +67,6 @@ static void LaunchTitle(u64 title_id, FsStorageId storage_id, u32 launch_flags,
if (pid) {
*pid = local_pid;
}
SetLaunchedTitle(title_id);
}
static bool GetGpioPadLow(GpioPadName pad) {
@@ -199,9 +184,6 @@ void EmbeddedBoot2::Main() {
/* Wait until fs.mitm has installed itself. We want this to happen as early as possible. */
WaitForMitm("fsp-srv");
/* Clear titles. */
ClearLaunchedTitles();
/* psc, bus, pcv is the minimal set of required titles to get SD card. */
/* bus depends on pcie, and pcv depends on settings. */
/* Launch psc. */
@@ -260,7 +242,7 @@ void EmbeddedBoot2::Main() {
while ((ent = readdir(titles_dir)) != NULL) {
if (strlen(ent->d_name) == 0x10 && IsHexadecimal(ent->d_name)) {
u64 title_id = (u64)strtoul(ent->d_name, NULL, 16);
if (HasLaunchedTitle(title_id)) {
if (Registration::HasLaunchedTitle(title_id)) {
continue;
}
char title_path[FS_MAX_PATH] = {0};
@@ -290,7 +272,4 @@ void EmbeddedBoot2::Main() {
/* We no longer need the SD card. */
fsdevUnmountAll();
/* Free the memory used to track what boot2 launches. */
ClearLaunchedTitles();
}

View File

@@ -15,6 +15,9 @@
*/
#include <switch.h>
#include <stratosphere/ldr.hpp>
#include <stratosphere/ldr/ldr_pm_api.hpp>
#include "pm_registration.hpp"
#include "pm_info.hpp"
@@ -22,9 +25,26 @@ Result InformationService::GetTitleId(Out<u64> tid, u64 pid) {
std::scoped_lock<ProcessList &> lk(Registration::GetProcessList());
std::shared_ptr<Registration::Process> proc = Registration::GetProcess(pid);
if (proc != NULL) {
tid.SetValue(proc->tid_sid.title_id);
return ResultSuccess;
if (proc == NULL) {
return ResultPmProcessNotFound;
}
return ResultPmProcessNotFound;
tid.SetValue(proc->tid_sid.title_id);
return ResultSuccess;
}
Result InformationService::AtmosphereGetProcessId(Out<u64> pid, u64 tid) {
std::scoped_lock<ProcessList &> lk(Registration::GetProcessList());
std::shared_ptr<Registration::Process> proc = Registration::GetProcessByTitleId(tid);
if (proc == nullptr) {
return ResultPmProcessNotFound;
}
pid.SetValue(proc->pid);
return ResultSuccess;
}
Result InformationService::AtmosphereHasLaunchedTitle(Out<bool> out, u64 tid) {
return sts::ldr::pm::HasLaunchedTitle(out.GetPointer(), sts::ncm::TitleId{tid});
}

View File

@@ -20,14 +20,23 @@
enum InformationCmd {
Information_Cmd_GetTitleId = 0,
Information_Cmd_AtmosphereGetProcessId = 65000,
Information_Cmd_AtmosphereHasCreatedTitle = 65001,
};
class InformationService final : public IServiceObject {
private:
/* Actual commands. */
Result GetTitleId(Out<u64> tid, u64 pid);
/* Atmosphere commands. */
Result AtmosphereGetProcessId(Out<u64> pid, u64 tid);
Result AtmosphereHasLaunchedTitle(Out<bool> out, u64 tid);
public:
DEFINE_SERVICE_DISPATCH_TABLE {
MakeServiceCommandMeta<Information_Cmd_GetTitleId, &InformationService::GetTitleId>(),
MakeServiceCommandMeta<Information_Cmd_AtmosphereGetProcessId, &InformationService::AtmosphereGetProcessId>(),
MakeServiceCommandMeta<Information_Cmd_AtmosphereHasCreatedTitle, &InformationService::AtmosphereHasLaunchedTitle>(),
};
};

View File

@@ -36,7 +36,7 @@ extern "C" {
u32 __nx_applet_type = AppletType_None;
#define INNER_HEAP_SIZE 0x30000
#define INNER_HEAP_SIZE 0x40000
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
char nx_inner_heap[INNER_HEAP_SIZE];
@@ -100,12 +100,12 @@ void __appInit(void) {
DoWithSmSession([&]() {
R_ASSERT(fsprInitialize());
R_ASSERT(smManagerInitialize());
/* This works around a bug with process permissions on < 4.0.0. */
RegisterPrivilegedProcessesWithFs();
/* Use AMS manager extension to tell SM that FS has been worked around. */
R_ASSERT(smManagerInitialize());
R_ASSERT(sts::sm::manager::EndInitialDefers());
R_ASSERT(lrInitialize());
@@ -145,7 +145,7 @@ int main(int argc, char **argv)
s_server_manager.AddWaitable(new ServiceServer<ShellService>("pm:shell", 3));
s_server_manager.AddWaitable(new ServiceServer<DebugMonitorService>("pm:dmnt", 3));
s_server_manager.AddWaitable(new ServiceServer<BootModeService>("pm:bm", 6));
s_server_manager.AddWaitable(new ServiceServer<InformationService>("pm:info", 3));
s_server_manager.AddWaitable(new ServiceServer<InformationService>("pm:info", 19));
/* Loop forever, servicing our services. */
s_server_manager.Process();

View File

@@ -13,9 +13,12 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <atomic>
#include <switch.h>
#include <stratosphere.hpp>
#include <atomic>
#include <stratosphere/ldr.hpp>
#include <stratosphere/ldr/ldr_pm_api.hpp>
#include "pm_registration.hpp"
#include "pm_resource_limits.hpp"
@@ -492,6 +495,12 @@ Handle Registration::GetBootFinishedEventHandle() {
return g_boot_finished_event->GetHandle();
}
bool Registration::HasLaunchedTitle(u64 title_id) {
bool has_launched = false;
R_ASSERT(sts::ldr::pm::HasLaunchedTitle(&has_launched, sts::ncm::TitleId{title_id}));
return has_launched;
}
void Registration::SignalBootFinished() {
g_boot_finished_event->Signal();
}

View File

@@ -204,6 +204,8 @@ class Registration {
static Result LaunchProcess(u64 title_id, FsStorageId storage_id, u64 launch_flags, u64 *out_pid);
static Result LaunchProcessByTidSid(TidSid tid_sid, u64 launch_flags, u64 *out_pid);
static bool HasLaunchedTitle(u64 title_id);
static void SignalBootFinished();
static bool HasApplicationProcess(std::shared_ptr<Process> *out = nullptr);