SceSdstor
Module
SceSdstor module does not export any functions exсept module_start.
This module is responsible for initializing all storage devices. This includes:
- eMMC
- Game gard
- Memory card
- USB Mass Storage
Based on layout of data segment and code of some subroutines (mbr table init, partition entry table init etc) it can be said that there are 5 devices in total. However only first 4 devices are known at the moment.
Version | World | Privilege |
---|---|---|
1.69-3.60 | Non-secure | Kernel |
Libraries
Known NIDs
Version | Name | World | Visibility | NID |
---|
Interrupt Table
Index | Code | Name |
---|---|---|
0 | 0xDC | SceSdif0 |
1 | 0xDD | SceSdif1 |
2 | 0x3C | SceMsifIns |
3 | 0xF | SceUsbMass |
4 | 0xDF | SceSdif3 |
Block Device Naming Rules
First level prefix: hardware device
- int: internal eMMC
- ext: device in game card slot
- gcd: game card
- mcd: device in memory card slot
- uma: USB mass for PSTV (or pins on FAT PSVita)
- usd: ?
- xmc: external memory card
Second level prefix: partition table related?
- lp - general.
- pp - not general. cannot use on sceIoMount etc(need more test).
Third level prefix: active/inactive partition selection
- ina: inactive
- act: active
- ign: ignore (for devices, that don't support this. but seems same to ina)
Fourth level prefix: partition
- a
- unused
- idstor
- sloader
- os
- vsh
- vshdata
- vtrm
- user
- userext
- gamero
- gamerw
- updater
- sysdata
- mediaid
- pidata
- entire
Partition Block Devices
Each partition has numeric alias (string) that looks like to be used to reference the partition.
Numeric names most likely follow order of partitions in MBR.
To access device node use /dev
prefix (like /dev/gcd-lp-ign-gamero
).
In total there can be 16 aliases from 0 to 15 per physical device (eMMC, Game Card, Memory Card). Alias 16 is hardcoded and is called entire
.
Aliases 0-15 correspond to eMMC partitions.
Aliases 100-115 correspond to Game Card partitions.
Aliases 200-215 correspond to Memory Card partitions.
Not all numeric names are fixed except for hardcoded ones.
block device | numeric name |
---|---|
int-lp-ign-idstor | 000 |
int-lp-act-sloader/int-lp-ina-sloader | 001 |
- | 002 |
int-lp-act-os/int-lp-ina-os | 003 |
- | 004 |
int-lp-ign-sysdata | 005 |
int-lp-ign-vtrm | 006 |
int-lp-ign-vsh | 007 |
int-lp-ign-vshdata | 008 |
int-lp-ign-updater | 009 |
int-lp-ign-pidata | 010 |
int-lp-ign-user | 011 |
int-lp-ign-userext | 012 |
int-lp-act-entire | 016 |
gcd-lp-ign-gamero, gcd-lp-act-mediaid (need to confirm) | 100 |
gcd-lp-ign-gamerw (need to confirm) | 101 |
ext-lp-act-entire | 116 |
mcd-lp-act-mediaid | 200 |
- | 201 |
mcd-lp-act-entire | 216 |
Types
Looks like SceSdstor driver uses its own device type
Device Type Index | Description |
---|---|
0 | MMC card |
1 | SD card |
2 | Memory Card |
3 | USB Mass Storage |
typedef struct partition_entry_raw { uint32_t partitionOffset; uint32_t partitionSize; uint8_t partitionCode; uint8_t partitionType; uint8_t partitionActive; uint32_t flags; uint16_t unk; }partition_entry_raw; typedef struct partition_entry //size is 0x1C { uint32_t partitionOffset; //from MBR uint32_t partitionSize; //from MBR sdstor_mbr_ctx* ctx; partition_entry_raw* partitionEntryPtr; //pointer to raw partition entry in MBR char numericName[4]; //null terminated name (000, 001, ...) uint32_t flags1; //from MBR uint16_t unk2; //from MBR uint16_t unk3; //? }partition_entry; typedef struct sdstor_mbr_ctx //size is 0x238 { fast_mutex fast_mutex_SceSdStorPartitionTable; //size is 0x40 uint32_t unk_40; //maybe sector size ? sd_stor_device* dev; uint32_t unk_48; //maybe sector size ? uint32_t unk_4C; uint32_t unk_50; void* mbr_ptr; //pointer to corresponding MBR record in array (offset 0x40) partition_entry partitions[17]; // 16 real partition entries from MBR + some hardcoded 17th partition entry uint8_t unk_234; //some initialization flag (0, 1, 2) uint8_t unk_235; uint8_t unk_236; //some initialization flag (set to 0 if partition table is initialized) uint8_t unk_237; }sdstor_mbr_ctx; //named after "SceSdStorDevice" mutex typedef struct sd_stor_device //size is 0x54 { fast_mutex fast_mutex_SceSdStorDevice; //size is 0x40 char index1; // (0x00, 0x01, 0xFF, 0xFF, 0x03) // sd ctx index used to get sd_context_part* (0, 1 confirmed) (3 unknown) char index2; // (0x00, 0x00 / 0x01, 0x02, 0x03, 0x01) // device type idx , not related to sdif type! char unk_42; // (0, 1) looks like init flag. 1 means that device is initialized and can be accessed char unk_43; uint32_t unk_44; uint32_t unk_48; uint32_t unk_4C; void* devCtx; //pointer to dev ctx (sd_context_part_mmc*) or zero }sd_stor_device; //named after SceSdStorDeviceHandle mutex and pool typedef struct sd_stor_device_handle //size is 0x58 { fast_mutex fast_mutex_SceSdStorDeviceHandle; //size is 0x40 uint32_t unk_40; //maybe sector size ? uint32_t partitionOffset; uint32_t partitionSize; uint32_t unk_4C; partition_entry* pentry; sd_stor_device* dev; }sd_stor_device_handle; typedef struct unknown_1C2C //size is 0x1C { uint8_t data[0x1C]; }unknown_1C2C; #define CARD_REMOVE_SDSTOR_REQUEST_EVENT_FLAG 0x01 #define IO_DEVCTL_SDSTOR_REQUEST_EVENT_FLAG 0x02 #define CARD_INSERT_SDSTOR_REQUEST_EVENT_FLAG 0x10 #define SUSPEND_SDSTOR_REQUEST_EVENT_FLAG 0x100 #define RESUME_SDSTOR_REQUEST_EVENT_FLAG 0x1000 typedef struct interrupt_argument //size is 0x28 { uint32_t unk_0; SceUID SceSdstorRequest_evid; // event id SceUID SceSdstorOpSync_evid; // event id interrupt_info* intr_info; // unknown_1C2C* unk_10; //card swap protection char cid_rnd[0x10]; // cid of the card / randomly generated non zero byte array / zero uint8_t intr_table_index; // check interrupt table section (also sd_stor_device index) uint8_t unk_25; // = 0 uint8_t unk_26; // = 0 uint8_t unk_27; } interrupt_argument; typedef int(insert_handler)(int unk, interrupt_argument* arg); typedef int(remove_handler)(int unk, interrupt_argument* arg); #define SDSTOR_SUBINTERRUPT_CODE_INSERT 0 #define SDSTOR_SUBINTERRUPT_CODE_REMOVE 1 typedef struct interrupt_info //size is 0xC { insert_handler* SceSdstorCardInsert_handler; remove_handler* SceSdstorCardRemove_handler; uint8_t intr_table_index; // check interrupt table section uint8_t SceSdstorCardInsert_subintr_code; uint8_t SceSdstorCardRemove_subintr_code; uint8_t unk_B; } interrupt_info;
Data segment layout
Address | Size | Description |
---|---|---|
0x0000 | 0x20 | unknown |
0x0020 | 0x14 | array of 5 integers (number created device handles?) (each corresponds to sd_stor_device) |
0x0034 | 0x4 | unknown |
0x0038 | 0x4 | SceSdStorDeviceHandle mempool SceUID of size 0x2000
|
0x003C | 0x4 | unknown |
0x0040 | 0x200 | MBR of eMMC |
0x0240 | 0x200 | MBR of Game gard |
0x0440 | 0x200 | MBR of Memory card |
0x0640 | 0x200 | MBR of USB Mass Storage |
0x0840 | 0x200 | unknown (most likely for MBR since there are 5 elements in all arrays) |
0x0A40 | 0x238 | sdstor_mbr_ctx element 0 |
0x0C78 | 0x238 | sdstor_mbr_ctx element 1 |
0x0EB0 | 0x238 | sdstor_mbr_ctx element 2 |
0x10E8 | 0x238 | sdstor_mbr_ctx element 3 |
0x1320 | 0x238 | sdstor_mbr_ctx element 4 |
0x1558 | 0x54 | sd_stor_device element 0 |
0x15AC | 0x54 | sd_stor_device element 1 |
0x1600 | 0x54 | sd_stor_device element 2 |
0x1654 | 0x54 | sd_stor_device element 3 |
0x16A8 | 0x54 | sd_stor_device element 4 |
0x16FC | 0x20 | vfs_add_data sdstor_dev_fs node
|
0x171C | 0x04 | SceSdStorVfs mempool SceUID of size 0x2000
|
0x1720 | 0x200 | first sector of external partition (0xD) (gcd-lp-act-mediaid) of game card (interrupt index 1) |
0x1920 | 0x200 | first sector of external partition (0xD) (mcd-lp-act-mediaid) of memory card (interrupt index 2) |
0x1B20 | 0xC8 | array of 5 interrupt_argument structures
|
0x1BE8 | 0x8 | suspend_register_callback opt |
0x1BF0 | 0x3C | array of 5 interrupt_info structures
|
0x1C2C | 0x8C | array of 5 unknown_1C2C structures
|
0x1CB8 | 0x8 | unknown |
0x1CC0 | 0x200 | MBR of Game card |
SceSdstor
module_start
Version | NID |
---|---|
3.60 | 0x935cd196 |
int module_start();