Updating Bluray Drive Firmware on Linux: Difference between revisions

From PS3 Developer wiki
Jump to navigation Jump to search
 
(29 intermediate revisions by 5 users not shown)
Line 1: Line 1:
[[Category:OtherOS]]
=Introduction=
=Introduction=


* No use actually but just for the sake of scientific research :)
* Incredibly useful for grabbing ps3 firmware dumps using DRAM exploit + TOCTOU bug in bd fw update :)
* see https://www.youtube.com/watch?v=LNFgKBfo2d8


=Current BD FW Version=
=Current BD FW Version=
Line 22: Line 24:
</pre>
</pre>


Or reading it from BD drive istelf, see http://www.ps3devwiki.com/wiki/BD_Drive_Reverse_Engineering#Get_Version.
Or reading it from BD drive istelf, see: [[BD_Drive_Reverse_Engineering#Get_Version|Get Version]]


=BD Drive Type=
=BD Drive Type=
* Use SCSI Inquiry to fetch BD drive identification string.
<pre>
sudo sg_inq /dev/sr0
</pre>
* PUP file contains several BD update packages.
* Update manager matches BD drive type against '''h_id''' from update package header.
* h_id is at offset 0x8 (8 bytes) in the update package header.
* E.g. h_id from BDPT_FIRMWARE_PACKAGE_306R.pkg is 0x0000000000000007.


{| class="wikitable FCK__ShowTableBorders"
{| class="wikitable FCK__ShowTableBorders"
Line 32: Line 45:
! Flag
! Flag
|-
|-
| SONY    EmerFlashROM  
| SONY    EmerFlashROM
|  
| 0x2100000000000001
|
| 0
|-
| SONY    PS-EMBOOT  300R
| 0x2100000000000001
| 0
|-
| SONY    BDRW AQUAM(BDIT)
| 0x1100000000000001
| 0
|-
| SONY    PS-SYSTEM  300R
| 0x1100000000000001
| 0
|-
| SONY    PS-SYSTEM  V300
| 0x1100000000000001
| 0
|-
| SCEI    EMER-FLASH-8
| 0x2200000000000002
| 0
|-
| SONY    PS-EMBOOT  301R
| 0x2200000000000002
| 0
|-
| SONY    PS-SYSTEM  301R
| 0x1200000000000002
| 0
|-
| SONY    PS-EMBOOT  302R
| 0x2200000000000003
| 1
|-
| SONY    PS-SYSTEM  302R
| 0x1200000000000003
| 1
|-
| SONY    PS-EMBOOT  303R
| 0x2200000000000004
| 0
|-
| SONY    PS-SYSTEM  303R
| 0x1200000000000004
| 0
|-
| SONY    PS-EMBOOT  304R
| 0x2200000000000005
| 1
|-
| SONY    PS-SYSTEM  304R
| 0x1200000000000005
| 1
|-
| SONY    PS-EMBOOT  306R
| 0x2200000000000007
| 1
|-
| SONY    PS-SYSTEM  306R
| 0x1200000000000007
| 1
|-
| SONY    PS-EMBOOT  308R
| 0x2200000000000008
| 1
|-
| SONY    PS-SYSTEM  308R
| 0x1200000000000008
| 1
|-
| SONY    PS-EMBOOT  310R
| 0x2200000000000009
| 1
|-
| SONY    PS-SYSTEM  310R
| 0x1200000000000009
| 1
|-
| SONY    PS-EMBOOT  312R
| 0x220000000000000A
| 1
|-
| SONY    PS-SYSTEM  312R
| 0x120000000000000A
| 1
|-
| SONY    PS-EMBOOT  314R
| 0x220000000000000B
| 1
|-
| SONY    PS-SYSTEM  314R
| 0x120000000000000B
| 1
|-
| SONY    PS-EMBOOT  316R
| 0x220000000000000C
| 1
|-
| SONY    PS-SYSTEM  316R
| 0x120000000000000C
| 1
|-
| SONY    PS-EMBOOT  318R
| 0x220000000000000D
| 1
|-
| SONY    PS-SYSTEM  318R
| 0x120000000000000D
| 1
|-
|}
|}
BD drive type and FW type check:
<pre>
if ((type & 0x00FFFFFFFFFFFFFF) == h_id)
  FW is OK
else
  FW is NOT OK
fi
</pre>


=Sending BD Firmware to BD Drive=
=Sending BD Firmware to BD Drive=
* BD update package is first decrypted and then sent to BD drive.
* BD buffer 0 is used to send BD firmware to BD drive.
* The BD firmware is sent in chunks of size 0x8000 bytes with SCSI command WRITE BUFFER mode 7.
See my bd_update_fw tool for PS3 Linux.
http://gitorious.ps3dev.net/ps3linux/bd-tools
=Test=
* Tested with my PS3 slim and OtherOS++.
* It should work on PC too. You can update your BD drive on PC but first you need to authenticate it with '''bd_get_version'''.
* Downgrading works too. I tested it myself and downgraded from 3.50 to 3.40 and back again.
* Use '''ps3dm sm get_version''' or '''bd_get_version''' to verify that the new version was installed successfully.
Valid firmware:
<pre>
sudo ./bd_update_fw -v -f ~/ofw355/BDPT_FIRMWARE_PACKAGE_306R.bin/content
firmware length 786432
firmware h_id 0
=== INQUIRY (0x12) ===
vendor id SONY   
product id PS-SYSTEM  306R
=== START STOP (0x1b) ===
=== TEST UNIT READY (0x00) ===
=== WRITE BUFFER (0x3b): offset 0 length 8000 ===
=== WRITE BUFFER (0x3b): offset 8000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 10000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 18000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 20000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 28000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 30000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 38000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 40000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 48000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 50000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 58000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 60000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 68000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 70000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 78000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 80000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 88000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 90000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 98000 length 8000 ===
=== WRITE BUFFER (0x3b): offset a0000 length 8000 ===
=== WRITE BUFFER (0x3b): offset a8000 length 8000 ===
=== WRITE BUFFER (0x3b): offset b0000 length 8000 ===
=== WRITE BUFFER (0x3b): offset b8000 length 8000 ===
=== TEST UNIT READY (0x00) ===
req sense 20407 (because of invalid command issued. ignore it)
=== TEST UNIT READY (0x00) ===
req sense 20407 (because of invalid command issued. ignore it)
=== TEST UNIT READY (0x00) ===
req sense 20407 (because of invalid command issued. ignore it)
=== TEST UNIT READY (0x00) ===
req sense 20407 (because of invalid command issued. ignore it)
=== TEST UNIT READY (0x00) ===
req sense 20407 (because of invalid command issued. ignore it)
=== TEST UNIT READY (0x00) ===
req sense 20407 (because of invalid command issued. ignore it)
=== TEST UNIT READY (0x00) ===
req sense 20407 (because of invalid command issued. ignore it)
=== TEST UNIT READY (0x00) ===
req sense 20407 (because of invalid command issued. ignore it)
=== TEST UNIT READY (0x00) ===
req sense 20401 (unknown)
=== TEST UNIT READY (0x00) ===
req sense 20401 (unknown)
=== TEST UNIT READY (0x00) ===
req sense 20401 (unknown)
=== TEST UNIT READY (0x00) ===
req sense 20401 (unknown)
=== TEST UNIT READY (0x00) ===
req sense 20401 (unknown)
=== TEST UNIT READY (0x00) ===
req sense 20401 (unknown)
=== TEST UNIT READY (0x00) ===
req sense 23a00 (success)
</pre>
Invalid firmware:
<pre>
sudo ./bd_update_fw -v -f ~/ofw355/BDPT_FIRMWARE_PACKAGE_306R.bin/info1 
firmware length 64
firmware h_id 0
=== INQUIRY (0x12) ===
vendor id SONY   
product id PS-SYSTEM  306R
=== START STOP (0x1b) ===
=== TEST UNIT READY (0x00) ===
=== WRITE BUFFER (0x3b): offset 0 length 40 ===
WRITE BUFFER failed: req sense 52600 (invalid firmware combination or hash error)
</pre>
{{Linux}}<noinclude>[[Category:Main]]</noinclude>

Latest revision as of 01:55, 8 August 2024

Introduction[edit | edit source]

Current BD FW Version[edit | edit source]

Using Storage Manager service get_version:

sudo ./ps3dm sm get_version
00 03 00 50 00 00 00 00

Using SC Manager service get_region_data:

sudo ps3dm scm get_region_data 8 | hexdump -C
00000000  00 03 00 50 00 00 00 00  00 00 00 00 00 00 00 00  |...P............|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000030

Or reading it from BD drive istelf, see: Get Version

BD Drive Type[edit | edit source]

  • Use SCSI Inquiry to fetch BD drive identification string.
sudo sg_inq /dev/sr0
  • PUP file contains several BD update packages.
  • Update manager matches BD drive type against h_id from update package header.
  • h_id is at offset 0x8 (8 bytes) in the update package header.
  • E.g. h_id from BDPT_FIRMWARE_PACKAGE_306R.pkg is 0x0000000000000007.
Identification string Type Flag
SONY EmerFlashROM 0x2100000000000001 0
SONY PS-EMBOOT 300R 0x2100000000000001 0
SONY BDRW AQUAM(BDIT) 0x1100000000000001 0
SONY PS-SYSTEM 300R 0x1100000000000001 0
SONY PS-SYSTEM V300 0x1100000000000001 0
SCEI EMER-FLASH-8 0x2200000000000002 0
SONY PS-EMBOOT 301R 0x2200000000000002 0
SONY PS-SYSTEM 301R 0x1200000000000002 0
SONY PS-EMBOOT 302R 0x2200000000000003 1
SONY PS-SYSTEM 302R 0x1200000000000003 1
SONY PS-EMBOOT 303R 0x2200000000000004 0
SONY PS-SYSTEM 303R 0x1200000000000004 0
SONY PS-EMBOOT 304R 0x2200000000000005 1
SONY PS-SYSTEM 304R 0x1200000000000005 1
SONY PS-EMBOOT 306R 0x2200000000000007 1
SONY PS-SYSTEM 306R 0x1200000000000007 1
SONY PS-EMBOOT 308R 0x2200000000000008 1
SONY PS-SYSTEM 308R 0x1200000000000008 1
SONY PS-EMBOOT 310R 0x2200000000000009 1
SONY PS-SYSTEM 310R 0x1200000000000009 1
SONY PS-EMBOOT 312R 0x220000000000000A 1
SONY PS-SYSTEM 312R 0x120000000000000A 1
SONY PS-EMBOOT 314R 0x220000000000000B 1
SONY PS-SYSTEM 314R 0x120000000000000B 1
SONY PS-EMBOOT 316R 0x220000000000000C 1
SONY PS-SYSTEM 316R 0x120000000000000C 1
SONY PS-EMBOOT 318R 0x220000000000000D 1
SONY PS-SYSTEM 318R 0x120000000000000D 1

BD drive type and FW type check:

if ((type & 0x00FFFFFFFFFFFFFF) == h_id)
   FW is OK
else
   FW is NOT OK
fi

Sending BD Firmware to BD Drive[edit | edit source]

  • BD update package is first decrypted and then sent to BD drive.
  • BD buffer 0 is used to send BD firmware to BD drive.
  • The BD firmware is sent in chunks of size 0x8000 bytes with SCSI command WRITE BUFFER mode 7.

See my bd_update_fw tool for PS3 Linux.

http://gitorious.ps3dev.net/ps3linux/bd-tools

Test[edit | edit source]

  • Tested with my PS3 slim and OtherOS++.
  • It should work on PC too. You can update your BD drive on PC but first you need to authenticate it with bd_get_version.
  • Downgrading works too. I tested it myself and downgraded from 3.50 to 3.40 and back again.
  • Use ps3dm sm get_version or bd_get_version to verify that the new version was installed successfully.

Valid firmware:

sudo ./bd_update_fw -v -f ~/ofw355/BDPT_FIRMWARE_PACKAGE_306R.bin/content 
firmware length 786432
firmware h_id 0
=== INQUIRY (0x12) ===
vendor id SONY    
product id PS-SYSTEM   306R
=== START STOP (0x1b) ===
=== TEST UNIT READY (0x00) ===
=== WRITE BUFFER (0x3b): offset 0 length 8000 ===
=== WRITE BUFFER (0x3b): offset 8000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 10000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 18000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 20000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 28000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 30000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 38000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 40000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 48000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 50000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 58000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 60000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 68000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 70000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 78000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 80000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 88000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 90000 length 8000 ===
=== WRITE BUFFER (0x3b): offset 98000 length 8000 ===
=== WRITE BUFFER (0x3b): offset a0000 length 8000 ===
=== WRITE BUFFER (0x3b): offset a8000 length 8000 ===
=== WRITE BUFFER (0x3b): offset b0000 length 8000 ===
=== WRITE BUFFER (0x3b): offset b8000 length 8000 ===
=== TEST UNIT READY (0x00) ===
req sense 20407 (because of invalid command issued. ignore it)
=== TEST UNIT READY (0x00) ===
req sense 20407 (because of invalid command issued. ignore it)
=== TEST UNIT READY (0x00) ===
req sense 20407 (because of invalid command issued. ignore it)
=== TEST UNIT READY (0x00) ===
req sense 20407 (because of invalid command issued. ignore it)
=== TEST UNIT READY (0x00) ===
req sense 20407 (because of invalid command issued. ignore it)
=== TEST UNIT READY (0x00) ===
req sense 20407 (because of invalid command issued. ignore it)
=== TEST UNIT READY (0x00) ===
req sense 20407 (because of invalid command issued. ignore it)
=== TEST UNIT READY (0x00) ===
req sense 20407 (because of invalid command issued. ignore it)
=== TEST UNIT READY (0x00) ===
req sense 20401 (unknown)
=== TEST UNIT READY (0x00) ===
req sense 20401 (unknown)
=== TEST UNIT READY (0x00) ===
req sense 20401 (unknown)
=== TEST UNIT READY (0x00) ===
req sense 20401 (unknown)
=== TEST UNIT READY (0x00) ===
req sense 20401 (unknown)
=== TEST UNIT READY (0x00) ===
req sense 20401 (unknown)
=== TEST UNIT READY (0x00) ===
req sense 23a00 (success)

Invalid firmware:

sudo ./bd_update_fw -v -f ~/ofw355/BDPT_FIRMWARE_PACKAGE_306R.bin/info1   
firmware length 64
firmware h_id 0
=== INQUIRY (0x12) ===
vendor id SONY    
product id PS-SYSTEM   306R
=== START STOP (0x1b) ===
=== TEST UNIT READY (0x00) ===
=== WRITE BUFFER (0x3b): offset 0 length 40 ===
WRITE BUFFER failed: req sense 52600 (invalid firmware combination or hash error)