mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-25 19:56:51 +01:00
libNX FS Initalization (v0.3)
What was added: * libNX FS initalization What was fixed: * Release builds
This commit is contained in:
parent
e44809355c
commit
19eae34315
1
app/.gitignore
vendored
1
app/.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
/build
|
/build
|
||||||
|
/release
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
cmake_minimum_required(VERSION 3.8)
|
cmake_minimum_required(VERSION 3.8)
|
||||||
project(Skyline VERSION 1 LANGUAGES CXX)
|
project(Skyline VERSION 0.3 LANGUAGES CXX)
|
||||||
|
|
||||||
set(BUILD_TESTING OFF)
|
set(BUILD_TESTING OFF)
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
|
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0")
|
set(CMAKE_CXX_FLAGS_RELEASE "-Ofast -flto=full -Wno-unused-command-line-argument")
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -flto=full")
|
|
||||||
add_subdirectory("libraries/tinyxml2")
|
add_subdirectory("libraries/tinyxml2")
|
||||||
add_subdirectory("libraries/fmt")
|
add_subdirectory("libraries/fmt")
|
||||||
|
|
||||||
@ -35,6 +34,7 @@ add_library(skyline SHARED
|
|||||||
${source_DIR}/skyline/kernel/services/am/appletOE.cpp
|
${source_DIR}/skyline/kernel/services/am/appletOE.cpp
|
||||||
${source_DIR}/skyline/kernel/services/hid/hid.cpp
|
${source_DIR}/skyline/kernel/services/hid/hid.cpp
|
||||||
${source_DIR}/skyline/kernel/services/time/time.cpp
|
${source_DIR}/skyline/kernel/services/time/time.cpp
|
||||||
|
${source_DIR}/skyline/kernel/services/fs/fs.cpp
|
||||||
)
|
)
|
||||||
target_link_libraries(skyline fmt tinyxml2)
|
target_link_libraries(skyline fmt tinyxml2)
|
||||||
target_compile_options(skyline PRIVATE -Wno-c++17-extensions)
|
target_compile_options(skyline PRIVATE -Wno-c++17-extensions)
|
||||||
|
@ -7,19 +7,24 @@ android {
|
|||||||
applicationId "skyline.emu"
|
applicationId "skyline.emu"
|
||||||
minSdkVersion 26
|
minSdkVersion 26
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
versionCode 1
|
versionCode 3
|
||||||
versionName "1.0"
|
versionName "0.3"
|
||||||
ndk {
|
ndk {
|
||||||
abiFilters "arm64-v8a"
|
abiFilters "arm64-v8a"
|
||||||
}
|
}
|
||||||
signingConfig signingConfigs.debug
|
|
||||||
}
|
}
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
|
debuggable true
|
||||||
minifyEnabled true
|
minifyEnabled true
|
||||||
|
shrinkResources true
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
|
signingConfig signingConfigs.debug
|
||||||
}
|
}
|
||||||
debug {
|
debug {
|
||||||
|
debuggable true
|
||||||
minifyEnabled false
|
minifyEnabled false
|
||||||
|
shrinkResources false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
|
@ -34,6 +34,8 @@ namespace skyline::kernel::service {
|
|||||||
time,
|
time,
|
||||||
time_ISystemClock,
|
time_ISystemClock,
|
||||||
time_ITimeZoneService,
|
time_ITimeZoneService,
|
||||||
|
fs_fsp,
|
||||||
|
fs_IFileSystem,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,6 +63,8 @@ namespace skyline::kernel::service {
|
|||||||
{"time:a", Service::time},
|
{"time:a", Service::time},
|
||||||
{"time:ISystemClock", Service::time_ISystemClock},
|
{"time:ISystemClock", Service::time_ISystemClock},
|
||||||
{"time:ITimeZoneService", Service::time_ITimeZoneService},
|
{"time:ITimeZoneService", Service::time_ITimeZoneService},
|
||||||
|
{"fsp-srv", Service::fs_fsp},
|
||||||
|
{"fs:IFileSystem", Service::fs_IFileSystem},
|
||||||
};
|
};
|
||||||
|
|
||||||
class ServiceManager;
|
class ServiceManager;
|
||||||
|
18
app/src/main/cpp/skyline/kernel/services/fs/fs.cpp
Normal file
18
app/src/main/cpp/skyline/kernel/services/fs/fs.cpp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#include "fs.h"
|
||||||
|
|
||||||
|
namespace skyline::kernel::service::fs {
|
||||||
|
fsp::fsp(const DeviceState &state, ServiceManager& manager) : BaseService(state, manager, false, Service::fs_fsp, {
|
||||||
|
{0x1, SFunc(fsp::SetCurrentProcess)},
|
||||||
|
{0x12, SFunc(fsp::OpenSdCardFileSystem)}
|
||||||
|
}) {}
|
||||||
|
|
||||||
|
void fsp::SetCurrentProcess(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
|
process = *reinterpret_cast<pid_t*>(request.cmdArg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fsp::OpenSdCardFileSystem(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
|
manager.RegisterService(std::make_shared<IFileSystem>(FsType::SdCard, state, manager), session, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
IFileSystem::IFileSystem(FsType type, const DeviceState &state, ServiceManager &manager) : type(type), BaseService(state, manager, false, Service::fs_IFileSystem, {}) {}
|
||||||
|
}
|
45
app/src/main/cpp/skyline/kernel/services/fs/fs.h
Normal file
45
app/src/main/cpp/skyline/kernel/services/fs/fs.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <kernel/services/base_service.h>
|
||||||
|
#include <kernel/services/serviceman.h>
|
||||||
|
|
||||||
|
namespace skyline::kernel::service::fs {
|
||||||
|
/**
|
||||||
|
* @brief These are the possible types of the filesystem
|
||||||
|
*/
|
||||||
|
enum FsType {
|
||||||
|
Nand,
|
||||||
|
SdCard,
|
||||||
|
GameCard
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief fsp-srv or IFileSystemProxy is responsible for providing handles to file systems (https://switchbrew.org/wiki/Filesystem_services#fsp-srv)
|
||||||
|
*/
|
||||||
|
class fsp : public BaseService {
|
||||||
|
public:
|
||||||
|
pid_t process{}; //!< This holds the PID set by SetCurrentProcess
|
||||||
|
|
||||||
|
fsp(const DeviceState &state, ServiceManager& manager);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This sets the PID of the process using FS currently (https://switchbrew.org/wiki/Filesystem_services#SetCurrentProcess)
|
||||||
|
*/
|
||||||
|
void SetCurrentProcess(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This returns a handle to an instance of #IFileSystem (https://switchbrew.org/wiki/Filesystem_services#IFileSystem) with type SDCard
|
||||||
|
*/
|
||||||
|
void OpenSdCardFileSystem(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief IFileSystem is used to interact with a filesystem (https://switchbrew.org/wiki/Filesystem_services#IFileSystem)
|
||||||
|
*/
|
||||||
|
class IFileSystem : public BaseService {
|
||||||
|
public:
|
||||||
|
FsType type;
|
||||||
|
|
||||||
|
IFileSystem(FsType type, const DeviceState &state, ServiceManager& manager);
|
||||||
|
};
|
||||||
|
}
|
@ -33,7 +33,7 @@ namespace skyline::kernel::service::hid {
|
|||||||
u64 appletUserId;
|
u64 appletUserId;
|
||||||
} *input = reinterpret_cast<InputStruct *>(request.cmdArg);
|
} *input = reinterpret_cast<InputStruct *>(request.cmdArg);
|
||||||
styleSet = *reinterpret_cast<StyleSet *>(&input->styleSet);
|
styleSet = *reinterpret_cast<StyleSet *>(&input->styleSet);
|
||||||
state.logger->Write(Logger::Info, "Controller Support: Pro-Controller: {} Joy-Con: Handheld: {}, Dual: {}, L: {}, R: {} GameCube: {} PokeBall: {} NES: {} NES Handheld: {} SNES: {}", static_cast<bool>(styleSet->pro_controller), static_cast<bool>(styleSet->joycon_handheld), static_cast<bool>(styleSet->joycon_dual), static_cast<bool>(styleSet->joycon_left), static_cast<bool>
|
state.logger->Write(Logger::Debug, "Controller Support: Pro-Controller: {} Joy-Con: Handheld: {}, Dual: {}, L: {}, R: {} GameCube: {} PokeBall: {} NES: {} NES Handheld: {} SNES: {}", static_cast<bool>(styleSet->pro_controller), static_cast<bool>(styleSet->joycon_handheld), static_cast<bool>(styleSet->joycon_dual), static_cast<bool>(styleSet->joycon_left), static_cast<bool>
|
||||||
(styleSet->joycon_right), static_cast<bool>(styleSet->gamecube), static_cast<bool>(styleSet->pokeball), static_cast<bool>(styleSet->nes), static_cast<bool>(styleSet->nes_handheld), static_cast<bool>(styleSet->snes));
|
(styleSet->joycon_right), static_cast<bool>(styleSet->gamecube), static_cast<bool>(styleSet->pokeball), static_cast<bool>(styleSet->nes), static_cast<bool>(styleSet->nes_handheld), static_cast<bool>(styleSet->snes));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "fatal/fatal.h"
|
#include "fatal/fatal.h"
|
||||||
#include "hid/hid.h"
|
#include "hid/hid.h"
|
||||||
#include "time/timesrv.h"
|
#include "time/timesrv.h"
|
||||||
|
#include "fs/fs.h"
|
||||||
|
|
||||||
namespace skyline::kernel::service {
|
namespace skyline::kernel::service {
|
||||||
ServiceManager::ServiceManager(const DeviceState &state) : state(state) {}
|
ServiceManager::ServiceManager(const DeviceState &state) : state(state) {}
|
||||||
@ -68,6 +69,9 @@ namespace skyline::kernel::service {
|
|||||||
case Service::time:
|
case Service::time:
|
||||||
serviceObj = std::make_shared<time::time>(state, *this);
|
serviceObj = std::make_shared<time::time>(state, *this);
|
||||||
break;
|
break;
|
||||||
|
case Service::fs_fsp:
|
||||||
|
serviceObj = std::make_shared<fs::fsp>(state, *this);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw exception("GetService called on missing object");
|
throw exception("GetService called on missing object");
|
||||||
}
|
}
|
||||||
@ -81,23 +85,31 @@ namespace skyline::kernel::service {
|
|||||||
|
|
||||||
std::shared_ptr<BaseService> ServiceManager::NewService(const Service serviceType, type::KSession &session, ipc::IpcResponse &response) {
|
std::shared_ptr<BaseService> ServiceManager::NewService(const Service serviceType, type::KSession &session, ipc::IpcResponse &response) {
|
||||||
auto serviceObject = GetService(serviceType);
|
auto serviceObject = GetService(serviceType);
|
||||||
|
handle_t handle{};
|
||||||
if (response.isDomain) {
|
if (response.isDomain) {
|
||||||
session.domainTable[++session.handleIndex] = serviceObject;
|
session.domainTable[++session.handleIndex] = serviceObject;
|
||||||
response.domainObjects.push_back(session.handleIndex);
|
response.domainObjects.push_back(session.handleIndex);
|
||||||
} else
|
handle = session.handleIndex;
|
||||||
response.moveHandles.push_back(state.thisProcess->NewHandle<type::KSession>(serviceObject).handle);
|
} else {
|
||||||
state.logger->Write(Logger::Debug, "Service has been created: \"{}\"", serviceObject->getName());
|
handle = state.thisProcess->NewHandle<type::KSession>(serviceObject).handle;
|
||||||
|
response.moveHandles.push_back(handle);
|
||||||
|
}
|
||||||
|
state.logger->Write(Logger::Debug, "Service has been created: \"{}\" (0x{:X})", serviceObject->getName(), handle);
|
||||||
return serviceObject;
|
return serviceObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServiceManager::RegisterService(std::shared_ptr<BaseService> serviceObject, type::KSession &session, ipc::IpcResponse &response) {
|
void ServiceManager::RegisterService(std::shared_ptr<BaseService> serviceObject, type::KSession &session, ipc::IpcResponse &response) { // NOLINT(performance-unnecessary-value-param)
|
||||||
serviceVec.push_back(serviceObject);
|
serviceVec.push_back(serviceObject);
|
||||||
|
handle_t handle{};
|
||||||
if (response.isDomain) {
|
if (response.isDomain) {
|
||||||
session.domainTable[++session.handleIndex] = serviceObject;
|
session.domainTable[++session.handleIndex] = serviceObject;
|
||||||
response.domainObjects.push_back(session.handleIndex);
|
response.domainObjects.push_back(session.handleIndex);
|
||||||
} else
|
handle = session.handleIndex;
|
||||||
response.moveHandles.push_back(state.thisProcess->NewHandle<type::KSession>(serviceObject).handle);
|
} else {
|
||||||
state.logger->Write(Logger::Debug, "Service has been registered: \"{}\"", serviceObject->getName());
|
handle = state.thisProcess->NewHandle<type::KSession>(serviceObject).handle;
|
||||||
|
response.moveHandles.push_back(handle);
|
||||||
|
}
|
||||||
|
state.logger->Write(Logger::Debug, "Service has been registered: \"{}\" (0x{:X})", serviceObject->getName(), handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServiceManager::CloseSession(const handle_t handle) {
|
void ServiceManager::CloseSession(const handle_t handle) {
|
||||||
|
@ -98,7 +98,6 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WaitSynchronization(DeviceState &state) {
|
void WaitSynchronization(DeviceState &state) {
|
||||||
state.thisThread->timeout = GetCurrTimeNs() + state.nce->GetRegister(Xreg::X3);
|
|
||||||
auto numHandles = state.nce->GetRegister(Wreg::W2);
|
auto numHandles = state.nce->GetRegister(Wreg::W2);
|
||||||
if (numHandles > constant::MaxSyncHandles) {
|
if (numHandles > constant::MaxSyncHandles) {
|
||||||
state.nce->SetRegister(Wreg::W0, constant::status::MaxHandles);
|
state.nce->SetRegister(Wreg::W0, constant::status::MaxHandles);
|
||||||
@ -126,6 +125,7 @@ namespace skyline::kernel::svc {
|
|||||||
state.thisThread->waitObjects.push_back(syncObject);
|
state.thisThread->waitObjects.push_back(syncObject);
|
||||||
syncObject->waitThreads.push_back(state.thisThread->pid);
|
syncObject->waitThreads.push_back(state.thisThread->pid);
|
||||||
}
|
}
|
||||||
|
state.thisThread->timeout = GetCurrTimeNs() + state.nce->GetRegister(Xreg::X3);
|
||||||
state.thisThread->status = type::KThread::ThreadStatus::WaitSync;
|
state.thisThread->status = type::KThread::ThreadStatus::WaitSync;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ namespace skyline::kernel::type {
|
|||||||
MapPrivateRegion(0, constant::DefHeapSize, {true, true, true}, memory::Type::Heap, memory::Region::Heap);
|
MapPrivateRegion(0, constant::DefHeapSize, {true, true, true}, memory::Type::Heap, memory::Region::Heap);
|
||||||
memFd = open(fmt::format("/proc/{}/mem", pid).c_str(), O_RDWR | O_CLOEXEC); // NOLINT(hicpp-signed-bitwise)
|
memFd = open(fmt::format("/proc/{}/mem", pid).c_str(), O_RDWR | O_CLOEXEC); // NOLINT(hicpp-signed-bitwise)
|
||||||
if (memFd == -1)
|
if (memFd == -1)
|
||||||
throw exception(fmt::format("Cannot open file descriptor to /proc/{}/mem", pid));
|
throw exception(fmt::format("Cannot open file descriptor to /proc/{}/mem, \"{}\"", pid, strerror(errno)));
|
||||||
}
|
}
|
||||||
|
|
||||||
KProcess::~KProcess() {
|
KProcess::~KProcess() {
|
||||||
|
@ -73,7 +73,7 @@ namespace skyline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (state->thisThread->status == kernel::type::KThread::ThreadStatus::WaitSync || state->thisThread->status == kernel::type::KThread::ThreadStatus::Sleeping || state->thisThread->status == kernel::type::KThread::ThreadStatus::WaitCondVar) {
|
} else if (state->thisThread->status == kernel::type::KThread::ThreadStatus::WaitSync || state->thisThread->status == kernel::type::KThread::ThreadStatus::Sleeping || state->thisThread->status == kernel::type::KThread::ThreadStatus::WaitCondVar) {
|
||||||
if (state->thisThread->timeout >= GetCurrTimeNs()) {
|
if (state->thisThread->timeout <= GetCurrTimeNs()) {
|
||||||
if (state->thisThread->status == kernel::type::KThread::ThreadStatus::WaitSync || state->thisThread->status == kernel::type::KThread::ThreadStatus::WaitCondVar)
|
if (state->thisThread->status == kernel::type::KThread::ThreadStatus::WaitSync || state->thisThread->status == kernel::type::KThread::ThreadStatus::WaitCondVar)
|
||||||
SetRegister(Wreg::W0, constant::status::Timeout);
|
SetRegister(Wreg::W0, constant::status::Timeout);
|
||||||
state->thisThread->status = kernel::type::KThread::ThreadStatus::Runnable;
|
state->thisThread->status = kernel::type::KThread::ThreadStatus::Runnable;
|
||||||
|
Loading…
Reference in New Issue
Block a user