Skip to content

Commit 163e5bf

Browse files
committed
module_driver: Use module_driver to properly load other modules from memory
1 parent 4f02884 commit 163e5bf

9 files changed

Lines changed: 113 additions & 6 deletions

File tree

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,6 @@ dkms.conf
5757
app/drivers/audio_driver.S
5858
app/drivers/display_driver.S
5959
app/drivers/fs_driver.S
60-
app/drivers/input_driver.S
60+
app/drivers/module_driver.S
6161
app/*.json
6262
app/*.log

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
SUBDIRS = audio_driver display_driver fs_driver app launcher
1+
SUBDIRS = audio_driver display_driver fs_driver module_driver app launcher
22

33
all:
44
@for dir in $(SUBDIRS); do $(MAKE) -C $$dir; done

app/include/kernel_functions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ extern "C" {
77

88
#include <pspctrl.h>
99
#include <pspiofilemgr.h>
10+
#include <pspmodulemgr.h>
1011

1112
// Kernel function prototypes
1213

@@ -34,6 +35,9 @@ extern int pspIoRename(const char *oldname, const char *newname);
3435
extern int pspIoRemoveFile(const char *file);
3536
extern int pspIoDevctl(const char *dev, unsigned int cmd, void *indata, int inlen, void *outdata, int outlen);
3637

38+
// module_driver functions
39+
extern int pspKernelLoadModuleBuffer(SceSize size, void *buf, s32 flag, const SceKernelLMOption *option);
40+
3741
#if defined (__cplusplus)
3842
}
3943
#endif

app/source/kernel_functions.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,6 @@ int pspIoGetstat(const char *file, SceIoStat *stat);
2323
int pspIoRename(const char *oldname, const char *newname);
2424
int pspIoRemoveFile(const char *file);
2525
int pspIoDevctl(const char *dev, unsigned int cmd, void *indata, int inlen, void *outdata, int outlen);
26+
27+
// module_driver functions
28+
int pspKernelLoadModuleBuffer(SceSize size, void *buf, s32 flag, const SceKernelLMOption *option);

app/source/utils.cpp

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ enum PspCtrlButtons PSP_CTRL_ENTER, PSP_CTRL_CANCEL;
2121
BROWSE_STATE device = BROWSE_STATE_EXTERNAL;
2222
int g_psp_language = PSP_SYSTEMPARAM_LANGUAGE_ENGLISH;
2323

24-
extern unsigned char audio_driver_prx_start[], display_driver_prx_start[], fs_driver_prx_start[];
25-
extern unsigned int audio_driver_prx_size, display_driver_prx_size, fs_driver_prx_size;
24+
extern unsigned char audio_driver_prx_start[], display_driver_prx_start[], fs_driver_prx_start[], module_driver_prx_start[];
25+
extern unsigned int audio_driver_prx_size, display_driver_prx_size, fs_driver_prx_size, module_driver_prx_size;
2626

2727
namespace Utils {
2828
constexpr unsigned int CTRL_DEADZONE_DELAY = 500000;
@@ -33,6 +33,7 @@ namespace Utils {
3333
static int last_button_tick = 0, deadzone_tick = 0;
3434
static bool usb_module_loaded = false;
3535
static bool usb_actived = false;
36+
static SceUID module_driver_id = 0;
3637

3738
typedef struct {
3839
const char *path = nullptr;
@@ -116,7 +117,7 @@ namespace Utils {
116117
}
117118

118119
// Basically removes and re-creates prx from memory -> then remove it after inital load
119-
static int LoadStartModuleMem(const char *path, const void *buf, SceSize size) {
120+
static int LoadStartModuleMemInitial(const char *path, const void *buf, SceSize size) {
120121
int ret = 0;
121122
SceUID modID = 0;
122123

@@ -140,6 +141,23 @@ namespace Utils {
140141
return 0;
141142
}
142143

144+
static int LoadStartModuleMem(const char *path, void *buf, SceSize size) {
145+
int ret = 0;
146+
SceUID modID = 0;
147+
148+
if (R_FAILED(ret = modID = pspKernelLoadModuleBuffer(size, buf, 0, nullptr))) {
149+
Log::Error("kuKernelLoadModule(%s) failed: 0x%08x\n", path, ret);
150+
return ret;
151+
}
152+
153+
if (R_FAILED(ret = sceKernelStartModule(modID, 0, nullptr, nullptr, nullptr))) {
154+
Log::Error("sceKernelStartModule(%s) failed: 0x%08x\n", path, ret);
155+
return ret;
156+
}
157+
158+
return 0;
159+
}
160+
143161
static void StopUnloadModules(SceUID modID) {
144162
sceKernelStopModule(modID, 0, nullptr, nullptr, nullptr);
145163
sceKernelUnloadModule(modID);
@@ -245,19 +263,23 @@ namespace Utils {
245263
}
246264

247265
void InitKernelDrivers(void) {
266+
module_driver_id = LoadStartModuleMemInitial("module_driver.prx", module_driver_prx_start, module_driver_prx_size);
267+
248268
for (unsigned int i = 0; i < kernel_modules.size(); ++i)
249269
kernel_modules[i].id = Utils::LoadStartModuleMem(kernel_modules[i].path, kernel_modules[i].data, kernel_modules[i].size);
250270

251271
Utils::InitUSB();
252272
}
253273

254274
void TermKernelDrivers(void) {
275+
Utils::ExitUSB();
276+
255277
for (int i = kernel_modules.size() - 1; i >= 0; --i) {
256278
Utils::StopUnloadModules(kernel_modules[i].id);
257279
kernel_modules[i].id = -1;
258280
}
259281

260-
Utils::ExitUSB();
282+
Utils::StopUnloadModules(module_driver_id);
261283
}
262284

263285
void UpdateUSB(void) {

module_driver/Makefile

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
TARGET = module_driver
2+
OBJS = module_driver.o exports.o ModuleMgrForKernel.o
3+
4+
PRX_EXPORTS = exports.exp
5+
6+
# Use the kernel's small inbuilt libc
7+
USE_KERNEL_LIBC = 1
8+
# Use only kernel libraries
9+
USE_KERNEL_LIBS = 1
10+
11+
CFLAGS = -Os -G0 -Wall -fno-builtin-printf
12+
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
13+
ASFLAGS = $(CFLAGS)
14+
15+
LDFLAGS = -nostartfiles
16+
17+
PSPSDK=$(shell psp-config --pspsdk-path)
18+
include $(PSPSDK)/lib/build_prx.mak
19+
20+
all:
21+
psp-build-exports -s $(PRX_EXPORTS)
22+
mv module_driver.S "../app/drivers/"
23+
mv module_driver.prx "../app/data/"

module_driver/ModuleMgrForKernel.S

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
.set noreorder
2+
3+
#include "pspimport.s"
4+
5+
IMPORT_START "ModuleMgrForKernel",0x00010000
6+
IMPORT_FUNC "ModuleMgrForKernel",0xFFB9B760,sceKernelLoadModule
7+
IMPORT_FUNC "ModuleMgrForKernel",0xE6BF3960,sceKernelStartModule
8+
IMPORT_FUNC "ModuleMgrForKernel",0x0D053026,sceKernelUnloadModule
9+
IMPORT_FUNC "ModuleMgrForKernel",0x32292450,_sceKernelLoadModuleWithApitype2
10+
IMPORT_FUNC "ModuleMgrForKernel",0xE3CCC6EA,sceKernelLoadModule_620
11+
IMPORT_FUNC "ModuleMgrForKernel",0xDF8FFFAB,sceKernelStartModule_620
12+
IMPORT_FUNC "ModuleMgrForKernel",0x9CEB18C4,sceKernelUnloadModule_620
13+
IMPORT_FUNC "ModuleMgrForKernel",0xB691CB9F,sceKernelLoadModuleWithApitype2_620
14+
IMPORT_FUNC "ModuleMgrForKernel",0x939E4270,sceKernelLoadModule_660
15+
IMPORT_FUNC "ModuleMgrForKernel",0x3FF74DF1,sceKernelStartModule_660
16+
IMPORT_FUNC "ModuleMgrForKernel",0x387E3CA9,sceKernelUnloadModule_660
17+
IMPORT_FUNC "ModuleMgrForKernel",0x2B7FC10D,sceKernelLoadModuleWithApitype2_660
18+
IMPORT_FUNC "ModuleMgrForKernel",0x4E62C48A,sceKernelLoadModuleBufferForKernel

module_driver/exports.exp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Define the exports for the prx
2+
PSP_BEGIN_EXPORTS
3+
4+
# These four lines are mandatory (although you can add other functions like module_stop)
5+
# syslib is a psynonym for the single mandatory export.
6+
PSP_EXPORT_START(syslib, 0, 0x8000)
7+
PSP_EXPORT_FUNC(module_start)
8+
PSP_EXPORT_FUNC(module_stop)
9+
PSP_EXPORT_VAR(module_info)
10+
PSP_EXPORT_END
11+
12+
PSP_EXPORT_START(module_driver, 0, 0x4001)
13+
PSP_EXPORT_FUNC(pspKernelLoadModuleBuffer)
14+
PSP_EXPORT_END
15+
16+
PSP_END_EXPORTS

module_driver/module_driver.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include <pspsdk.h>
2+
3+
PSP_MODULE_INFO("module_driver", PSP_MODULE_KERNEL, 1, 0);
4+
PSP_NO_CREATE_MAIN_THREAD();
5+
6+
SceUID sceKernelLoadModuleBufferForKernel(SceSize size, void *buf, s32 flag, const SceKernelLMOption *option);
7+
8+
int pspKernelLoadModuleBuffer(SceSize size, void *buf, s32 flag, const SceKernelLMOption *option) {
9+
int k1 = pspSdkSetK1(0);
10+
int ret = sceKernelLoadModuleBufferForKernel(size, buf, flag, option);
11+
pspSdkSetK1(k1);
12+
return ret;
13+
}
14+
15+
int module_start(SceSize args, void *argp) {
16+
return 0;
17+
}
18+
19+
int module_stop(void) {
20+
return 0;
21+
}

0 commit comments

Comments
 (0)