module_driver: Use module_driver to properly load other modules from memory

This commit is contained in:
Joel16 2022-07-29 22:15:46 -04:00
parent 4f02884c2d
commit 163e5bf4a2
9 changed files with 113 additions and 6 deletions

2
.gitignore vendored
View File

@ -57,6 +57,6 @@ dkms.conf
app/drivers/audio_driver.S
app/drivers/display_driver.S
app/drivers/fs_driver.S
app/drivers/input_driver.S
app/drivers/module_driver.S
app/*.json
app/*.log

View File

@ -1,4 +1,4 @@
SUBDIRS = audio_driver display_driver fs_driver app launcher
SUBDIRS = audio_driver display_driver fs_driver module_driver app launcher
all:
@for dir in $(SUBDIRS); do $(MAKE) -C $$dir; done

View File

@ -7,6 +7,7 @@ extern "C" {
#include <pspctrl.h>
#include <pspiofilemgr.h>
#include <pspmodulemgr.h>
// Kernel function prototypes
@ -34,6 +35,9 @@ extern int pspIoRename(const char *oldname, const char *newname);
extern int pspIoRemoveFile(const char *file);
extern int pspIoDevctl(const char *dev, unsigned int cmd, void *indata, int inlen, void *outdata, int outlen);
// module_driver functions
extern int pspKernelLoadModuleBuffer(SceSize size, void *buf, s32 flag, const SceKernelLMOption *option);
#if defined (__cplusplus)
}
#endif

View File

@ -23,3 +23,6 @@ int pspIoGetstat(const char *file, SceIoStat *stat);
int pspIoRename(const char *oldname, const char *newname);
int pspIoRemoveFile(const char *file);
int pspIoDevctl(const char *dev, unsigned int cmd, void *indata, int inlen, void *outdata, int outlen);
// module_driver functions
int pspKernelLoadModuleBuffer(SceSize size, void *buf, s32 flag, const SceKernelLMOption *option);

View File

@ -21,8 +21,8 @@ enum PspCtrlButtons PSP_CTRL_ENTER, PSP_CTRL_CANCEL;
BROWSE_STATE device = BROWSE_STATE_EXTERNAL;
int g_psp_language = PSP_SYSTEMPARAM_LANGUAGE_ENGLISH;
extern unsigned char audio_driver_prx_start[], display_driver_prx_start[], fs_driver_prx_start[];
extern unsigned int audio_driver_prx_size, display_driver_prx_size, fs_driver_prx_size;
extern unsigned char audio_driver_prx_start[], display_driver_prx_start[], fs_driver_prx_start[], module_driver_prx_start[];
extern unsigned int audio_driver_prx_size, display_driver_prx_size, fs_driver_prx_size, module_driver_prx_size;
namespace Utils {
constexpr unsigned int CTRL_DEADZONE_DELAY = 500000;
@ -33,6 +33,7 @@ namespace Utils {
static int last_button_tick = 0, deadzone_tick = 0;
static bool usb_module_loaded = false;
static bool usb_actived = false;
static SceUID module_driver_id = 0;
typedef struct {
const char *path = nullptr;
@ -116,7 +117,7 @@ namespace Utils {
}
// Basically removes and re-creates prx from memory -> then remove it after inital load
static int LoadStartModuleMem(const char *path, const void *buf, SceSize size) {
static int LoadStartModuleMemInitial(const char *path, const void *buf, SceSize size) {
int ret = 0;
SceUID modID = 0;
@ -140,6 +141,23 @@ namespace Utils {
return 0;
}
static int LoadStartModuleMem(const char *path, void *buf, SceSize size) {
int ret = 0;
SceUID modID = 0;
if (R_FAILED(ret = modID = pspKernelLoadModuleBuffer(size, buf, 0, nullptr))) {
Log::Error("kuKernelLoadModule(%s) failed: 0x%08x\n", path, ret);
return ret;
}
if (R_FAILED(ret = sceKernelStartModule(modID, 0, nullptr, nullptr, nullptr))) {
Log::Error("sceKernelStartModule(%s) failed: 0x%08x\n", path, ret);
return ret;
}
return 0;
}
static void StopUnloadModules(SceUID modID) {
sceKernelStopModule(modID, 0, nullptr, nullptr, nullptr);
sceKernelUnloadModule(modID);
@ -245,6 +263,8 @@ namespace Utils {
}
void InitKernelDrivers(void) {
module_driver_id = LoadStartModuleMemInitial("module_driver.prx", module_driver_prx_start, module_driver_prx_size);
for (unsigned int i = 0; i < kernel_modules.size(); ++i)
kernel_modules[i].id = Utils::LoadStartModuleMem(kernel_modules[i].path, kernel_modules[i].data, kernel_modules[i].size);
@ -252,12 +272,14 @@ namespace Utils {
}
void TermKernelDrivers(void) {
Utils::ExitUSB();
for (int i = kernel_modules.size() - 1; i >= 0; --i) {
Utils::StopUnloadModules(kernel_modules[i].id);
kernel_modules[i].id = -1;
}
Utils::ExitUSB();
Utils::StopUnloadModules(module_driver_id);
}
void UpdateUSB(void) {

23
module_driver/Makefile Normal file
View File

@ -0,0 +1,23 @@
TARGET = module_driver
OBJS = module_driver.o exports.o ModuleMgrForKernel.o
PRX_EXPORTS = exports.exp
# Use the kernel's small inbuilt libc
USE_KERNEL_LIBC = 1
# Use only kernel libraries
USE_KERNEL_LIBS = 1
CFLAGS = -Os -G0 -Wall -fno-builtin-printf
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
LDFLAGS = -nostartfiles
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build_prx.mak
all:
psp-build-exports -s $(PRX_EXPORTS)
mv module_driver.S "../app/drivers/"
mv module_driver.prx "../app/data/"

View File

@ -0,0 +1,18 @@
.set noreorder
#include "pspimport.s"
IMPORT_START "ModuleMgrForKernel",0x00010000
IMPORT_FUNC "ModuleMgrForKernel",0xFFB9B760,sceKernelLoadModule
IMPORT_FUNC "ModuleMgrForKernel",0xE6BF3960,sceKernelStartModule
IMPORT_FUNC "ModuleMgrForKernel",0x0D053026,sceKernelUnloadModule
IMPORT_FUNC "ModuleMgrForKernel",0x32292450,_sceKernelLoadModuleWithApitype2
IMPORT_FUNC "ModuleMgrForKernel",0xE3CCC6EA,sceKernelLoadModule_620
IMPORT_FUNC "ModuleMgrForKernel",0xDF8FFFAB,sceKernelStartModule_620
IMPORT_FUNC "ModuleMgrForKernel",0x9CEB18C4,sceKernelUnloadModule_620
IMPORT_FUNC "ModuleMgrForKernel",0xB691CB9F,sceKernelLoadModuleWithApitype2_620
IMPORT_FUNC "ModuleMgrForKernel",0x939E4270,sceKernelLoadModule_660
IMPORT_FUNC "ModuleMgrForKernel",0x3FF74DF1,sceKernelStartModule_660
IMPORT_FUNC "ModuleMgrForKernel",0x387E3CA9,sceKernelUnloadModule_660
IMPORT_FUNC "ModuleMgrForKernel",0x2B7FC10D,sceKernelLoadModuleWithApitype2_660
IMPORT_FUNC "ModuleMgrForKernel",0x4E62C48A,sceKernelLoadModuleBufferForKernel

16
module_driver/exports.exp Normal file
View File

@ -0,0 +1,16 @@
# Define the exports for the prx
PSP_BEGIN_EXPORTS
# These four lines are mandatory (although you can add other functions like module_stop)
# syslib is a psynonym for the single mandatory export.
PSP_EXPORT_START(syslib, 0, 0x8000)
PSP_EXPORT_FUNC(module_start)
PSP_EXPORT_FUNC(module_stop)
PSP_EXPORT_VAR(module_info)
PSP_EXPORT_END
PSP_EXPORT_START(module_driver, 0, 0x4001)
PSP_EXPORT_FUNC(pspKernelLoadModuleBuffer)
PSP_EXPORT_END
PSP_END_EXPORTS

View File

@ -0,0 +1,21 @@
#include <pspsdk.h>
PSP_MODULE_INFO("module_driver", PSP_MODULE_KERNEL, 1, 0);
PSP_NO_CREATE_MAIN_THREAD();
SceUID sceKernelLoadModuleBufferForKernel(SceSize size, void *buf, s32 flag, const SceKernelLMOption *option);
int pspKernelLoadModuleBuffer(SceSize size, void *buf, s32 flag, const SceKernelLMOption *option) {
int k1 = pspSdkSetK1(0);
int ret = sceKernelLoadModuleBufferForKernel(size, buf, flag, option);
pspSdkSetK1(k1);
return ret;
}
int module_start(SceSize args, void *argp) {
return 0;
}
int module_stop(void) {
return 0;
}