SceSdstor
Module
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
SceSdstor module does not export any function exсept module_start.
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
Name | Index | Description |
---|---|---|
int | 0 | eMMC |
ext | 1 | sd card |
gcd | 1 | game card |
mcd | 2 | memory card |
uma | 3 | USB mass |
usd | 4 | unknown |
xmc | 0xFF | external memory card |
Second level prefix: partition table related?
- lp - general.
- pp - no part.
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
- unused
- idstor
- sloader
- os
- vsh
- vshdata
- vtrm
- user
- userext
- gamero
- gamerw
- updater
- sysdata
- mediaid
- pidata
- entire - just device entry
Partition Block Devices
Each partition has a numeric alias (string) that seems 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
).
There can be up to 16 aliases from 0 to 15 per physical device (eMMC, Game Card, Memory Card) and alias 16 is hardcoded and called entire
.
Aliases 000-015 correspond to eMMC partitions.
Alias 016 corresponds to entire eMMC.
Aliases 100-115 correspond to Game Card partitions.
Alias 116 corresponds to entire Game Card or SD Card.
Aliases 200-215 correspond to Memory Card partitions.
Alias 216 corresponds to entire Memory Card.
Not all numeric names are fixed except for hardcoded ones.
block device | numeric name | hardcoded |
---|---|---|
int-lp-ign-idstor | 000 | n |
int-lp-act-sloader/int-lp-ina-sloader | 001 | n |
int-lp-act-sloader/int-lp-ina-sloader | 002 | n |
int-lp-act-os/int-lp-ina-os | 003 | n |
int-lp-act-os/int-lp-ina-os | 004 | n |
int-lp-ign-sysdata | 005 | n |
int-lp-ign-vtrm | 006 | n |
int-lp-ign-vsh | 007 | n |
int-lp-ign-vshdata | 008 | n |
int-lp-ign-updater | 009 | n |
int-lp-ign-pidata | 010 | n |
int-lp-ign-user | 011 | n |
int-lp-ign-userext | 012 | n |
int-lp-act-entire | 016 | y |
gcd-lp-ign-gamero, gcd-lp-act-mediaid (need to confirm) | 100 | n |
gcd-lp-ign-gamerw (need to confirm) | 101 | n |
ext-lp-act-entire | 116 | y |
mcd-lp-act-mediaid | 200 | n |
mcd-lp-ign-userext | 201 | n |
mcd-lp-act-entire | 216 | y |
uma-lp-act-entire | 316 | y |
usd-lp-act-entire | 416 | y |
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 | MBR of usd device |
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 (xmc) |
SceSdstor
module_start
Version | NID |
---|---|
3.60 | 0x935cd196 |
int module_start();