Skip to content

Commit

Permalink
initial
Browse files Browse the repository at this point in the history
  • Loading branch information
xyzz committed Jun 30, 2017
0 parents commit a1e3cb3
Show file tree
Hide file tree
Showing 5 changed files with 268 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
build
35 changes: 35 additions & 0 deletions driver/CMakeLists.txt
@@ -0,0 +1,35 @@
cmake_minimum_required(VERSION 2.8)

if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
if(DEFINED ENV{VITASDK})
set(CMAKE_TOOLCHAIN_FILE "$ENV{VITASDK}/share/vita.toolchain.cmake" CACHE PATH "toolchain file")
else()
message(FATAL_ERROR "Please define VITASDK to point to your SDK path!")
endif()
endif()

project(gamesd)
include("${VITASDK}/share/vita.cmake" REQUIRED)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-q -Wall -O3 -nostdlib")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions")

add_executable(gamesd
main.c
)

target_link_libraries(gamesd
SceIofilemgrForDriver_stub
SceSysclibForDriver_stub
SceSysmemForDriver_stub
SceModulemgrForKernel_stub
SceModulemgrForDriver_stub
SceThreadmgrForDriver_stub
SceKernelSuspendForDriver_stub
taihenForKernel_stub
taihenModuleUtils_stub
)

vita_create_self(gamesd.skprx gamesd CONFIG exports.yml UNSAFE)

vita_create_stubs(stubs gamesd ${CMAKE_SOURCE_DIR}/exports.yml KERNEL)
14 changes: 14 additions & 0 deletions driver/README.md
@@ -0,0 +1,14 @@
usbmc
=====
This is VitaShell's patches for USB storage support as a standalone plugin. If
loaded on startup (before SceShell), it will automatically mount the USB
storage as `ux0` instead of the memory card or internal memory.

To install, copy the plugin to `ur0:tai/usbmc.skprx` and add that path to the
taiHEN `ur0:tai/config.txt` under `*KERNEL`. If you have a memory card inserted
or you have a Vita with internal memory (LCD and PSTV), you must delete
`ux0:tai/config.txt` from the original memory and use `ur0:tai/config.txt` from
now on. This is because taiHEN loads before the memory card redirection patches
and will attempt to read config.txt from there first.

Full credits to The_FloW for these patches.
15 changes: 15 additions & 0 deletions driver/exports.yml
@@ -0,0 +1,15 @@
VitaShellKernel:
attributes: 0
version:
major: 1
minor: 0
main:
start: module_start
stop: module_stop
modules:
VitaShellKernelLibrary:
syscall: true
functions:
- shellKernelIsUx0Redirected
- shellKernelRedirectUx0
- shellKernelUnredirectUx0
203 changes: 203 additions & 0 deletions driver/main.c
@@ -0,0 +1,203 @@
/*
VitaShell
Copyright (C) 2015-2017, TheFloW
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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 <psp2kern/kernel/cpu.h>
#include <psp2kern/kernel/modulemgr.h>
#include <psp2kern/kernel/sysmem.h>
#include <psp2kern/io/fcntl.h>

#include <stdio.h>
#include <string.h>

#include <taihen.h>

#define MOUNT_POINT_ID 0x800

int module_get_offset(SceUID pid, SceUID modid, int segidx, size_t offset, uintptr_t *addr);

typedef struct {
const char *dev;
const char *dev2;
const char *blkdev;
const char *blkdev2;
int id;
} SceIoDevice;

typedef struct {
int id;
const char *dev_unix;
int unk;
int dev_major;
int dev_minor;
const char *dev_filesystem;
int unk2;
SceIoDevice *dev;
int unk3;
SceIoDevice *dev2;
int unk4;
int unk5;
int unk6;
int unk7;
} SceIoMountPoint;

static SceIoDevice uma_ux0_dev = { "ux0:", "exfatux0", "sdstor0:gcd-lp-ign-entire", "sdstor0:gcd-lp-ign-entire", MOUNT_POINT_ID };

static SceIoMountPoint *(* sceIoFindMountPoint)(int id) = NULL;

static SceIoDevice *ori_dev = NULL, *ori_dev2 = NULL;

static int exists(const char *path) {
int fd = ksceIoOpen(path, SCE_O_RDONLY, 0);
if (fd < 0)
return 0;
ksceIoClose(fd);
return 1;
}

static void io_remount(int id) {
ksceIoUmount(id, 0, 0, 0);
ksceIoUmount(id, 1, 0, 0);
ksceIoMount(id, NULL, 0, 0, 0, 0);
}

int shellKernelIsUx0Redirected() {
SceIoMountPoint *mount = sceIoFindMountPoint(MOUNT_POINT_ID);
if (!mount) {
return -1;
}

if (mount->dev == &uma_ux0_dev && mount->dev2 == &uma_ux0_dev) {
return 1;
}

return 0;
}

int shellKernelRedirectUx0() {
SceIoMountPoint *mount = sceIoFindMountPoint(MOUNT_POINT_ID);
if (!mount) {
return -1;
}

if (mount->dev != &uma_ux0_dev && mount->dev2 != &uma_ux0_dev) {
ori_dev = mount->dev;
ori_dev2 = mount->dev2;
}

mount->dev = &uma_ux0_dev;
mount->dev2 = &uma_ux0_dev;

return 0;
}

int shellKernelUnredirectUx0() {
SceIoMountPoint *mount = sceIoFindMountPoint(MOUNT_POINT_ID);
if (!mount) {
return -1;
}

if (ori_dev && ori_dev2) {
mount->dev = ori_dev;
mount->dev2 = ori_dev2;

ori_dev = NULL;
ori_dev2 = NULL;
}

return 0;
}

// ux0 redirect by theflow
int redirect_ux0() {
// Get tai module info
tai_module_info_t info;
info.size = sizeof(tai_module_info_t);
if (taiGetModuleInfoForKernel(KERNEL_PID, "SceIofilemgr", &info) < 0)
return -1;

// Get important function
module_get_offset(KERNEL_PID, info.modid, 0, 0x138C1, (uintptr_t *)&sceIoFindMountPoint);

shellKernelRedirectUx0();
io_remount(MOUNT_POINT_ID);

return 0;
}

int poke_gamecard() {
tai_module_info_t info;
info.size = sizeof(tai_module_info_t);
if (taiGetModuleInfoForKernel(KERNEL_PID, "SceSdstor", &info) < 0)
return -1;

void *args = 0;
int (*int_insert)() = 0;
int (*int_remove)() = 0;

module_get_offset(KERNEL_PID, info.modid, 0, 0x3BD5, (uintptr_t *)&int_insert);
module_get_offset(KERNEL_PID, info.modid, 0, 0x3BC9, (uintptr_t *)&int_remove);

module_get_offset(KERNEL_PID, info.modid, 1, 0x1B20 + 40 * 1, (uintptr_t *)&args);

int_remove(0, args);
ksceKernelDelayThread(500 * 1000);
int_insert(0, args);
ksceKernelDelayThread(500 * 1000);

return 0;
}

int suspend_callback(int resume, int eventid, void *args, void *opt) {
if (eventid != 0x100000)
return 0;

poke_gamecard();

return 0;
}

int register_callback() {
ksceKernelRegisterSuspendCallback("gamesd", suspend_callback, NULL);
}

int gen_init_2_patch_uid;

// allow SD cards, patch by motoharu
void patch_sdstor() {
tai_module_info_t sdstor_info;
sdstor_info.size = sizeof(tai_module_info_t);
if (taiGetModuleInfoForKernel(KERNEL_PID, "SceSdstor", &sdstor_info) >= 0) {
//patch for proc_initialize_generic_2 - so that sd card type is not ignored
char zeroCallOnePatch[4] = {0x01, 0x20, 0x00, 0xBF};
gen_init_2_patch_uid = taiInjectDataForKernel(KERNEL_PID, sdstor_info.modid, 0, 0x2498, zeroCallOnePatch, 4); //patch (BLX) to (MOVS R0, #1 ; NOP)
}
}

void _start() __attribute__ ((weak, alias("module_start")));
int module_start(SceSize args, void *argp) {
patch_sdstor();
poke_gamecard();
register_callback();
redirect_ux0();

return SCE_KERNEL_START_SUCCESS;
}

int module_stop(SceSize args, void *argp) {
return SCE_KERNEL_STOP_SUCCESS;
}

0 comments on commit a1e3cb3

Please sign in to comment.