idstorage

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
User avatar
harleyg
Posts: 123
Joined: Wed Oct 05, 2005 6:15 am

idstorage

Post by harleyg »

http://harleyg.net/docs/idstorage.txt
idstorage
by harleyg {AT} 0x89 {DOT} org

Last edited: 31/12/06 - 00:36 GMT

The idstorage is located after the IPL on the nand at 0xc0000, and is used to store
low-level information on the PSP, such as the serial, mac address, umd, wlan and region.
Most idstorage keys have a pair, although some do not (explained later.) Idstorage keys
are 512(+16) bytes and are stored in an index of two nand pages (512 bytes.) Nand pages
are also 515(+16 spare area) bytes. The index of idstorage is identified by byte 6 of the spare (0x73),
byte 7 is the idstorage version, byte is either 1 or 0; depending on whether the idstorage
has been formatted or not (???), and finally byte 9 indicates if the idstorage is read-only
or not.

Example idstorage indexes:
TA-079: 0x56 0xA6 0x65 0x00 0x00 0xFF 0x00 0x37 0x00 0x00 0x00 0x00 0xA5 0xF6 0xFF 0xFF
TA-081: 0x56 0xA6 0x65 0x00 0x00 0xFF 0x00 0x40 0x00 0x00 0x00 0x00 0xA1 0xF7 0xFF 0xFF
TA-082: 0x56 0xA6 0x65 0x00 0x00 0xFF 0x00 0x38 0x00 0x00 0x00 0x00 0xA5 0xF6 0xFF 0xFF
TA-086: 0x56 0xA6 0x65 0x00 0x00 0xFF 0x00 0x?? 0x00 0x00 0x00 0x00 0xA? 0xF? 0xFF 0xFF
TA-086: 0x56 0xA6 0x65 0x00 0x00 0xFF 0x00 0x40 0x00 0x00 0x00 0x00 0xA1 0xF7 0xFF 0xFF (downgraded)

Idstorage keys are 16 bit integers and are stored in the corresponding user areas. For example,
a key appearing at position 27 (byte 54) in the index would find its associated data at the location:
0xc0000 + (27 * 512) = 0xC3600

The IPL (main.bin) reads 3 keys from the idstorage, these are 0x004, 0x005 and 0x006. These
keys play a significant part in the PSP as they are related to power. In TA-082 and TA-086 PSP's,
these keys are at different locations, causing a brick with the 1.50 IPL.
0x004:
0000000000 6E 79 72 42 01 00 00 00-10 00 00 00 BB 01 AB 1F nyrB............
0000000016 D8 00 24 00 14 31 14 00-94 01 48 00 D8 00 00 00 ..$..1....H.....

0x005:
0000000000 67 68 6C 43 01 00 00 00-01 00 00 00 CA D9 E3 9B ghlC............
0000000016 0A 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................

0x006:
0000000000 72 64 44 4D 01 00 00 00-07 00 00 00 85 BD 2C 75 rdDM..........,u
0000000016 00 00 00 85 83 81 80 00-00 00 00 00 00 00 00 00 ................

Chkreg (chkreg.prx) reads 2 keys...
0x100 and 0x102 or 0x120 and 0x122 all contain the return of getpscode 3 times.
getpscode: 0x00 0x00 0x00 0x01 0x00 0x03 0x00 0x01

0x100 (from japanese PSP):
0000000048 00 00 00 01 00 03 00 01 ........
0000000240 00 00 00 01 00 03 00 01 ........
0000000416 00 00 00 01 00 03 00 01 ........

The rest of key is filled with random data, which is unique to each PSP. If this data is changed,
getpscode will return:
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

Meaning an invalid region. The data above is also the return of getpscode inside vshbridge.prx and
chkreg.prx. The return from getpscode is determined to be valid or invalid via semaphore and openpsid...
Getpscode first reads 0x100 or 0x120 into a buffer, this buffer is then sent to semaphore_4C537C72
(the same as OpenPSID) with the following args:
semaphore_4C537C72(0, 0, scrambled_buf, 0xb8, 0x12);

Arg 1 is the Destination. ??
Arg 2 is the size. ??
Arg 3 is the buffer 0x100 or 0x120 was read into and is 512 bytes.
Arg 4 is the size. ??
Arg 5 is the semaphore key, and sends data to 2 modules, these are OpenPSID and memab. Once the
scrambled buffer has been sent, "some check" is performed. If semaphore_4C537C72 ws sucessful,
this part of getpscode returns 0, else it returns 0x80000108.

Getpscode reads 0x120 using sceIdStorageLookup with the following args.
sceIdStorageLookup(0x120, 0x38, scrambled_buf, 0xb8);

Arg 1 is the idstorage key.
Arg 2 is the offset within the 512 byte leaf. The 1st occurrence of the region (getpscode) is at 0x38,
the second at 0xF0 and the third at 0x1A8. Each occurrence is 0xAF (175 bytes) apart.
Arg 3 is the buffer.
Arg 4 is the amount of buffer to retrieve.

Byte 5 is the region, and are as follows:
0x03 = Japan = PSP-1000
0x04 = USA = PSP-1001
0x09 = Australia and New Zealand = PSP-1002
0x05 = UK = PSP-1003
0x05 = Europe, Middle East and Africa = PSP-1004
0x06 = Korea = PSP-1005
0x0A = Hong Kong and Singapore = PSP-1006
0x?? = Taiwan = PSP-1007
0x?? = Russia = PSP-1008
0x?? = China = PSP-1009

Memab (memab.prx) reads 1 key... once again being 0x100 or 0x120.

Mgr (mgr.prx) reads 2 keys...
0x040:
00000001E0 03 86 00 20 F8 47 90 88-58 99 2E 88 F8 47 90 88 ... .G..X....G..
00000001F0 25 00 00 00 64 99 2E 88-01 00 00 00 D0 99 2E 88 %...d...........

0x???:
This idstorage key is calculated from someting. ???

OpenPSID (openpsid.prx) reads 2 keys, both relating to the region.
0x101 or 0x121 and 0x102 or 0x122.
The OpenPSID is calculated via the above keys and semaphore. It first reads 0x101 or 0x121 into
a buffer, if this fails it returns 0xC0520001 and reads 0x102 or 0x122 into the buffer, if this
fails again, it returns 0xC0520002. this is then passed to semaphore_4C537C72 with the following
args:
semaphore_4C537C72(0, 0, buf, 184, 0x12);

The args are explained above.
If the function returns 1, OpenPSID returns 0x0xC0520001, else it returns 0.

Power (power.prx) reads 1 key, 0x0004. This key is related to power and is also read by the IPL.

Umdman (umdman.prx) reads 1 key, 0x102. This key is related to the region, and is probably used to
determine what UMD video's can be read on the PSP.

USB (usb.prx) reads 1 key, 0x041. This key has information on the USB types.
0x041:
0000000000 4C 05 00 00 0A 03 53 00-6F 00 6E 00 79 00 00 00 L.....S.o.n.y...
0000000064 00 00 00 00 05 00 00 00-C8 01 00 00 16 03 50 00 ..............P.
0000000080 53 00 50 00 20 00 54 00-79 00 70 00 65 00 20 00 S.P. .T.y.p.e. .
0000000096 41 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 A...............
0000000128 00 00 00 00 00 00 00 00-00 00 00 00 C9 01 00 00 ................
0000000144 16 03 50 00 53 00 50 00-20 00 54 00 79 00 70 00 ..P.S.P. .T.y.p.
0000000160 65 00 20 00 42 00 00 00-00 00 00 00 00 00 00 00 e. .B...........
0000000208 CA 01 00 00 16 03 50 00-53 00 50 00 20 00 54 00 ......P.S.P. .T.
0000000224 79 00 70 00 65 00 20 00-43 00 00 00 00 00 00 00 y.p.e. .C.......
0000000272 00 00 00 00 CB 01 00 00-16 03 50 00 53 00 50 00 ..........P.S.P.
0000000288 20 00 54 00 79 00 70 00-65 00 20 00 44 00 00 00 .T.y.p.e. .D...
0000000336 00 00 00 00 00 00 00 00-CC 01 00 00 16 03 50 00 ..............P.
0000000352 53 00 50 00 20 00 54 00-79 00 70 00 65 00 20 00 S.P. .T.y.p.e. .
0000000368 45 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 E...............

0x0000 - idVendor - 0x4C 0x05
0x0002 - ??? - 0x00 0x00
0x0004 - bLength - 0x0A
0x0005 - ??? - 0x03
0x0006 - iManufacturer String - 0x53 0x00 0x6F 0x00 0x6E 0x00 0x79
0x0044 - ? bNum - 0x05
0x0045 - ??? - 0x00 0x00 0x00
0x0048 - idProduct - 0xC8 0x01
0x004A - ??? - 0x00 0x00
0x004C - bLength - 0x16
0x004D - ? bDescriptorType - 0x03
0x004E - iProduct String - 0x50 0x00 0x53 0x00 0x50 0x00 0x20 0x00 0x54 0x0 0x79 0x00
0x70 0x00 0x65 0x00 0x20 0x00 0x41
0x008C - idProduct - 0xC9 0x01
0x008E - ??? - 0x00 0x00
0x0090 - bLength - 0x16
0x0091 - ? bDescriptorType - 0x03
0x0092 - iProduct String - 0x50 0x00 0x53 0x00 0x50 0x00 0x20 0x00 0x54 0x0 0x79 0x00
0x70 0x00 0x65 0x00 0x20 0x00 0x42
0x00D0 - idProduct - 0xCA 0x01
0x00D2 - ??? - 0x00 0x00
0x00D4 - bLength - 0x16
0x00D5 - ? bDescriptorType - 0x03
0x00D6 - iProduct String - 0x50 0x00 0x53 0x00 0x50 0x00 0x20 0x00 0x54 0x0 0x79 0x00
0x70 0x00 0x65 0x00 0x20 0x00 0x43
0x0114 - idProduct - 0xCB 0x01
0x0116 - ??? - 0x00 0x00
0x0118 - bLength - 0x16
0x0119 - ? bDescriptorType - 0x03
0x011A - iProduct String - 0x50 0x00 0x53 0x00 0x50 0x00 0x20 0x00 0x54 0x0 0x79 0x00
0x70 0x00 0x65 0x00 0x20 0x00 0x44
0x0158 - idProduct - 0xCC 0x01
0x015A - ??? - 0x00 0x00
0x015C - bLength - 0x16
0x015D - ? bDescriptorType - 0x03
0x015E - iProduct String - 0x50 0x00 0x53 0x00 0x50 0x00 0x20 0x00 0x54 0x0 0x79 0x00
0x70 0x00 0x65 0x00 0x20 0x00 0x45

USBstor (usbstor.prx) reads 1 key, 0x043.
0x043:
0000000000 55 73 74 72 53 6F 6E 79-20 20 20 20 50 53 50 20 UstrSony PSP
0000000016 20 20 20 20 20 20 20 20-20 20 20 20 31 2E 30 30 1.00
0000000032 50 00 53 00 50 00 00 00-00 00 00 00 00 00 00 00 P.S.P...........

WLAN (wlan.prx) reads 2 keys, 0x044 and 0x045.
0x044:
0000000000 00 16 FE 86 FA 28 .....(

0x045:
0000000000 03 00 01 ...

This key contains the MAC address of the PSP. This can be changed, but does not effect the hardware,
ONLY THE VSH.

Sysconf_plugin (sysconf_plugin.prx) reads 1 key, 0x044. This is probably why the VSH displays a different
MAC address when 0x044 is changed.

0x044: Above ^^

Vshmain (vshmain.prx) reads 1 key, 0x046.
0x046: Empty, however vshmain uses the first byte of this key to set a param for vshImposeSetParam.


*** For a complete table of the idstorage keys above, see ...
http://harleyg.net/docs/idtable.txt ***


Each firmware provides a driver for the idstorage (idstorage.prx) to faciliate the idstorage
itself and the keys inside it.

int sceIdStorageLookup(u16 key, u32 offset, void *buf, u32 len); - Retrieves the value associated
with a key
Arg 1 is the idstorage key.
Arg 2 is the offset within the 512 byte leaf.
Arg 3 is the buffer with enough storage.
Arg 4 is the amount of data to retrieve. (offset + len must be <= 512 bytes)

int sceIdStorageReadLeaf(u16 key, void *buf); - Retrieves the whole 512 byte container for the key
Arg 1 is the idstorage key.
Arg 2 is the buffer with at least 512 bytes of storage.

int sceIdStorageWriteLeaf(u16 key, void *buf); - Writes 512 bytes to a key
Arg 1 is the idstorage key.
Arg 2 is the buffer with at least 512 bytes of data.

int sceIdStorageIsReadOnly(void); - Checks the idstorage for readonly status

int sceIdStorageFlush(void); - Finalizes a write

When writing to the idstorage, you must write to a keys pair. For example, 0x040's pair will probably
be 0x020 or 0x060. There is always "20" between each pair. After writing the same data to the pairs,
you must use sceIdStorageFlush to finalize the write. Some keys, such as 0x004 do not have pairs, and
some keys such as 0x005 have their pair as 0x006. Each idstorage is different.

To identify a PSP's hardware version from the idstorage, you can check the serial and the region.
(This includes the return of getpscode)

TA-079 and TA-081:
0x050:
0000000000 34 57 4D 42 30 39 34 38-32 34 34 57 4D 31 35 32 4WMB0948244WM152
0000000016 39 38 31 32 30 34 30 33-32 35 30 39 30 39 01 03 98120403250909..
0000000032 00 01 00 01 01 01 01 01-01 01 01 01 01 00 00 00 ................

TA-082 and TA-086:
0x050:
0000000000 30 30 30 30 30 30 30 30-30 30 30 30 30 30 30 30 0000000000000000
0000000016 30 30 30 30 30 30 30 30-30 30 30 30 30 30 02 05 00000000000000..
0000000032 00 02 00 01 01 01 01 01-01 01 01 01 01 00 00 00 ................

0x21 (byte 33) is either 0x01 or 0x02.

TA-079 and TA-081:
0x100:
0000000048 00 00 00 01 00 03 00 01 ........

TA-082 and TA-086:
0x100:
0000000048 00 00 00 01 00 03 00 02 ........

Byte 0x3F (byte 63) is either 0x01 or 0x02.

Another way is to check the NAND-ID, but i guess that isn't idstorage
related... :)

To enable a TA-082 PSP to run with the 1.50 IPL, you must change and move some idstorage keys.
0x042 -> 0x043
0x041 -> 0x042
0x006 -> 0x041
0x005 -> 0x006
0x004 -> 0x005
0x046 -> 0x004
0x045 -> 0x046
Set the 1st byte of 0x045 to 0x09.
0x045 -> 0x047

The process must be done in that order. After the keys have been changed, soft-reboot the PSP
to finalise the keys, then run 1.50 updater (using Dark_AleX's generic downdater.)
Thought i better post it... :)
Last edited by harleyg on Sun Dec 31, 2006 10:30 am, edited 1 time in total.
jas0nuk
Posts: 137
Joined: Thu Apr 27, 2006 8:00 am

Post by jas0nuk »

Good job! :D
Art
Posts: 642
Joined: Wed Nov 09, 2005 8:01 am

Post by Art »

0x?? = Australia and New Zealand = PSP-1002
It's 0x09.
TA-079 and TA-081:
0x050:
0000000000 34 57 4D 42 30 39 34 38-32 34 34 57 4D 31 35 32 4WMB0948244WM152
0000000016 39 38 31 32 30 34 30 33-32 35 30 39 30 39 01 03 98120403250909..
0000000032 00 01 00 01 01 01 01 01-01 01 01 01 01 00 00 00 ................

TA-082 and TA-086:
0x050:
0000000000 30 30 30 30 30 30 30 30-30 30 30 30 30 30 30 30 0000000000000000
0000000016 30 30 30 30 30 30 30 30-30 30 30 30 30 30 02 05 00000000000000..
0000000032 00 02 00 01 01 01 01 01-01 01 01 01 01 00 00 00 ................
That's not unconditionaly true (although it's true for my PSP units).
There are TA-079 boards that are identified as TA-082 that way.
They have the all zeros serial too.
Art.
jas0nuk
Posts: 137
Joined: Thu Apr 27, 2006 8:00 am

Post by jas0nuk »

Yes, some people reported that. However the combination of NAND ID and presence of serial number helps to work out if its 082/086 or not :)
User avatar
harleyg
Posts: 123
Joined: Wed Oct 05, 2005 6:15 am

Post by harleyg »

Thanks for that serial art.
However, i was not refering to the 00's.
0x21 (byte 33) is either 0x01 or 0x02.
Art
Posts: 642
Joined: Wed Nov 09, 2005 8:01 am

Post by Art »

I mean they have the zero serial as well as the TA-082 identifier.
They have the all zeros serial too.
That means I haven't heard of any TA-079 mainboards claiming to be
a TA-082 by the definition above without also having a zero serial by
the definition above.
User avatar
harleyg
Posts: 123
Joined: Wed Oct 05, 2005 6:15 am

Post by harleyg »

All TA-082's have 00's and 02 at 0x21. TA-079 and TA-081 can have 00's, but always have a 01 at 0x21.

I was refering to TA-082 and TA-086 when i said they are always 00's.



Yes i notice the doc isnt as clear as it should be... :)
Post Reply