SceSdstor

From Vita Development Wiki
Revision as of 22:12, 4 October 2022 by CelesteBlue (talk | contribs)
Jump to navigation Jump to search

Module

This module is responsible for initializing all storage devices. This includes:

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();