Analysis of "ROM" on Western Digital WD2500BB-55RDA0 PCB

Research and Development. This is the place to report experimental stuff related to data recovery.
fzabkar
Contributor
Contributor
Posts: 550
Joined: Tue Apr 16, 2013 9:28 am
Location: Australia

Analysis of "ROM" on Western Digital WD2500BB-55RDA0 PCB

Postby fzabkar » Wed Apr 24, 2013 4:56 am

Analysis of the "ROM" code on a Western Digital WD2500BB-55RDA0 PCB

This article is an attempt to understand the structure of Western Digital's "ROM" code as implemented in boards based on Marvell's MCUs. I have borrowed heavily from the following resource:

Some research on WD Marvell ROM, SA modules and firmware:
http://www.nazyura.newmail.ru/Part02.htm
http://translate.google.com/translate?h ... Part02.htm

Utilities For Studying Service Area Of WD HDDs:
http://www.nazyura.newmail.ru/000006.htm

I am using the following resource dump for my analysis:

WD2500BB-55RDA0 resources (retrieved with NazYura's tools):
download/file.php?id=137

The beginning of the ROM consists of a "Flash Code LoadMap Table".

Table of Program Memory Code Blocks (PMCBlock)

Code: Select all

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

Beginning of "Flash Code LoadMap Table"

00000000  5A 04 00 00 2D 07 00 00 2C 07 00 00 60 01 00 00
00000010  00 F0 00 00 00 F0 00 00 01 0A 00 00 00 00 00 11

00000020  01 01 00 00 31 3B 00 00 30 3B 00 00 8D 08 00 00
00000030  00 00 00 00 FF FF FF FF 01 0A 00 00 A0 4A 00 5F

00000040  02 01 00 00 29 45 00 00 28 45 00 00 BE 43 00 00
00000050  DC 4A 00 00 FF FF FF FF 01 0A 00 00 94 63 00 03

00000060  03 01 00 00 01 06 00 00 00 06 00 00 E7 88 00 00
00000070  98 AE 00 00 FF FF FF FF 01 0A 00 00 5C 07 00 30

00000080  04 03 00 00 45 01 00 00 44 01 00 00 E8 8E 00 00
00000090  50 00 00 04 FF FF FF FF 01 0A 00 00 E8 01 00 4C

000000A0  05 03 00 00 59 00 00 00 58 00 00 00 2D 90 00 00
000000B0  94 24 00 04 FF FF FF FF 01 0A 00 00 30 01 00 6A

000000C0  06 03 00 00 2D 15 00 00 2C 15 00 00 86 90 00 00
000000D0  00 00 00 21 FF FF FF FF 01 0A 00 00 50 21 00 3B

000000E0  07 01 01 00 49 DB 00 00 48 DB 00 00 B3 A5 00 00
000000F0  00 DC E0 FF FF FF FF FF 01 0A 00 00 D4 1A 00 58

00000100  08 01 00 00 E5 3B 00 00 E4 3B 00 00 FC 80 01 00
00000110  00 08 E2 FF FF FF FF FF 01 0A 00 00 B0 4D 00 B2

00000120  09 01 00 00 99 0E 00 00 98 0E 00 00 E1 BC 01 00
00000130  80 26 FE FF FF FF FF FF 01 0A 00 00 4C 13 00 FE

00000140  0A 00 00 00 15 1F 00 00 14 1F 00 00 7A CB 01 00
00000150  00 00 FE FF 00 00 00 00 01 0A 00 00 00 00 00 BF

End of "Flash Code LoadMap Table"

Start of first PMCBlock:

00000160  57 00 00 FA 03 1C 10 B5 02 E0 10 C9 04 3A 10 C3 
00000170  04 2A FA D2 10 BD 70 B5 74 4D 06 1C 28 68 0C 1C 
00000180  41 68 88 B0 20 22 68 46 FF F7 EC FF 63 1C 29 D0 
...
00000880  11 11 11 11 00 00 00 00 00 00 00 00 74 A0 4A 00 

In our example there are 11 PMCBlocks. Each has a 32-byte entry in the above table. The data are generally in little endian format.

The structure of the table appears to be as follows:

Code: Select all

Offset        Description       

0x00          PMCBlock number    This is 0x5A for PMCBlock #0 and 0xnn for PMCBlock #nn
0x01 - 0x03   Page / Segment     NazYura speculates that these bytes may denote Page / Segment
0x04 - 0x07   CKSM location      location of the 8-bit checksum for the PMCBlock
0x08 - 0x0B   BlkLen             length of PMCBlock in bytes
0x0C - 0x0F   BlkStart           beginning of PMCBlock
0x10 - 0x13   Load Address #1    load address range for PMCBlock in memory
0x14 - 0x17   Load Address #2
0x18 - 0x0B   CPU-ID             NazYura speculates that these bytes may identify the CPU
0x0C - 0x0D   1stWord            first word of the PMCBlk (except the first and last)
0x0E                             always 0x00
0x0F          CKSM               checksum for previous 31 bytes in table

Let's take PMCBlk #1 as an example.

The checksum for this table entry is 0x5F and is computed by summing the previous 31 bytes at offsets 0x20 - 0x3E.

In HxD (http://mh-nexus.de/en/hxd) you would drag your cursor over the area to be checksummed. Then select Analysis -> Checksums, choose Checksum-8 as the algorithm, "Selection" as the Region, then OK.

The code for PMCBlk #1 begins at offset 0x0000088D and has a length of 0x00003B30. Its checksum byte is located at offset 0x00003B31 relative to the start of the block.

This works out to ...

0x0000088D + 0x00003B31 - 1 = 0x43BD

Therefore the checksum should be 0x9D.

Code: Select all

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000880                                         A0 4A 00
00000890  00 B8 15 3E D2 98 F1 80 CC 21 B2 8D 05 F4 0D 64
000008A0  7E 15 4F 53 5F 07 18 A9 74 EC 03 B5 70 2B F6 16
...
000043B0  3B AB 76 A5 76 75 03 B5 29 00 00 00 8E 9D

NazYura's MAVR_FL.COM will read the ROM of a WD drive with a Marvell CPU.

CHECK_FL.COM will analyse the FLS ROM image generated by MAVR_FL.COM. Unfortunately NazYura's tools were written for pre-ROYL drives, so CHECK_FL will only check the first 128KB of the ROM. This means that 192KB or 256KB ROM checks will fail for those PMCBlks which extend beyond 128KB.

Code: Select all

 Check Control Sum Flash Files For WD-Marvell
 (C)NazYura Krasnodar 2006
 Email: nazyura@rambler.ru

------------------------------------------------------------------------------
 Flash Code File Name --> 01_0100.FLS

 LDSC:00 CS  + -->[11-11] - PMCBlk:00 Size:[072D] Sign:[0000] CS  + -->[74-74]
 LDSC:01 CS  + -->[5F-5F] - PMCBlk:01 Size:[3B31] Sign:[A04A] CS  + -->[9D-9D]
 LDSC:02 CS  + -->[03-03] - PMCBlk:02 Size:[4529] Sign:[9463] CS  + -->[86-86]
 LDSC:03 CS  + -->[30-30] - PMCBlk:03 Size:[0601] Sign:[5C07] CS  + -->[0E-0E]
 LDSC:04 CS  + -->[4C-4C] - PMCBlk:04 Size:[0145] Sign:[E801] CS  + -->[FF-FF]
 LDSC:05 CS  + -->[6A-6A] - PMCBlk:05 Size:[0059] Sign:[3001] CS  + -->[A5-A5]
 LDSC:06 CS  + -->[3B-3B] - PMCBlk:06 Size:[152D] Sign:[5021] CS  + -->[9C-9C]
 LDSC:07 CS  + -->[58-58] - PMCBlk:07 Size:[DB49] Sign:[D41A] CS  + -->[50-50]
 LDSC:08 CS  + -->[B2-B2] - PMCBlk:08 Size:[3BE5] Sign:[B04D] CS  + -->[16-16]
 LDSC:09 CS  + -->[FE-FE] - PMCBlk:09 Size:[0E99] Sign:[4C13] CS  + -->[2F-2F]
 LDSC:0A CS  + -->[BF-BF] - PMCBlk:0A Size:[1F15] Sign:[0000] CS  + -->[3B-3B]
------------------------------------------------------------------------------

 *** All File Checked And Have GOOD Control Sum !!!

 History:
 CS     - Control Sum
 +      - GOOD Control Sum
 BAD    - BAD Control Sum Found
 LDSC   - PM Loader Config String
 PMCBlk - Programm Memory Code Block
 Sign   - Signature Block Code

NazYura refers to checksum as "control sum". The first column verifies the checksum of each of the entries in the table (LDSC). The last column verifies the checksum of each PCMBlk. The "sign" column verifies the "1stWord" bytes.

Here is the memory map for the ROM, including several MODs at the end:

    Flash Map:
    ________________________________________________________________________________
    00000000 \ _Table of flash code blocks [11x32] (Not Fixed Size / Count)
    0000015f /
    00000160 \ _Block 00 (Not Fixed Offset / Size)
    000008D7 /
    000008D8 \ _Block 01 (Not Fixed Offset / Size)
    000043BD /
    000043BE \ _Block 02 (Not Fixed Offset / Size)
    000088E6 /
    000088E7 \ _Block 03 (Not Fixed Offset / Size)
    00008EE7 /
    00008EE8 \ _Block 04 (Not Fixed Offset / Size)
    0000902C /
    0000902D \ _Block 05 (Not Fixed Offset / Size)
    00009085 /
    00009086 \ _Block 06 (Not Fixed Offset / Size)
    0000A5B2 /
    0000A5B3 \ _Block 07 (Not Fixed Offset / Size)
    000180FB /
    000180FC \ _Block 08 (Not Fixed Offset / Size)
    0001BCE0 /
    0001BCE1 \ _Block 09 (Not Fixed Offset / Size)
    0001CB79 /
    0001CB7A \ _Block 0A (Not Fixed Offset / Size)
    0001EA8E /
    0001EA8F \ _Reserved (Filled with "FF" pattern) (Not Fixed Offset / Size)
    0001FA77 /
    0001FA78 \ _MOD 0D (Firmware version 20.00K20) [64 bytes]
    0001FAB7 /
    0001FAB8 \ _MOD 47 (Default SA Adaptives) (Fixed Size) [512 bytes]
    0001FCB7 /
    0001FCB8 \ _MOD 30 (Not Fixed Offset / Size) [512 bytes]
    0001FEB7 /
    0001FEB8 \ _Reserved (Filled with "FF" or "00" pattern) [256 bytes]
    0001FFB7 /
    0001FFB8 \ _MOD 0A (Default Config Drive) (Fixed Offset / Size) [56 bytes]
    0001FFEF /
    0001FFF0 \ _Reserved (Filled with "FF" pattern) (Fixed Offset / Size) [16 bytes]
    0001FFFF /

Here is MOD 0D:

Code: Select all

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

0001FA70                          04 0C 06 26 0D 32 30 41          ...&.20A
0001FA80  30 3F 00 00 00 00 00 00 00 00 00 00 00 00 01 00  0?..............
0001FA90  00 01 32 30 2E 30 30 4B 32 30 00 01 03 02 00 00  ..20.00K20......
0001FAA0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
0001FAB0  00 00 00 00 00 00 00 00                         

Here is MOD 47:

Code: Select all

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

0001FAB0                          04 0C 06 2D 47 52 2E 39          ...-GR.9
0001FAC0  59 3F 18 00 FC 00 20 01 00 00 00 00 55 38 01 00  Y?..ü. .....U8..
0001FAD0  40 50 C0 60 F0 80 B9 1A 03 04 0E 13 28 6D 28 1D
0001FAE0  0B 05 02 00 00 38 80 30 0C 5D 44 00 80 70 05 08
0001FAF0  06 0A 05 08 06 0A 40 55 C0 80 F0 80 B9 1A 02 02
0001FB00  06 0D 20 67 24 1B 08 05 02 00 00 2F 80 30 0C 5D
0001FB10  44 00 80 70 05 09 07 0B 05 09 07 0B 40 5C C0 60
0001FB20  F0 80 B9 1A 00 04 03 0F 1A 64 1D 18 06 05 02 00
0001FB30  00 2F 80 30 0C 5D 44 00 80 70 05 08 07 0A 05 08
0001FB40  07 0A 40 5D C0 70 E0 80 B9 1A 01 01 05 08 1B 60
0001FB50  1E 17 07 04 02 00 00 2E 80 30 0C 5D 44 00 80 70
0001FB60  05 07 07 09 05 07 07 09 40 58 C0 80 F0 80 B9 1A
0001FB70  03 01 07 0A 20 65 23 1A 07 04 02 00 00 2F 80 30
0001FB80  0C 5D 44 00 80 70 05 0C 09 0D 05 0C 09 0D 40 4C
0001FB90  C0 80 F0 80 B9 1A 01 00 03 07 1E 63 22 19 06 03
0001FBA0  02 00 00 30 80 30 0C 5D 44 00 80 70 05 0D 0A 0E
0001FBB0  05 0D 0A 0E 0A 00 2A 95 2C 9D 0A 00 2B 95 2D 9D
0001FBC0  0A 00 2E 95 30 9D 0B 09 27 95 29 9D 08 00 2D 95
0001FBD0  2F 9D 0B 09 2B 95 2D 9D 18 04 54 04 3A 04 64 04
0001FBE0  38 04 70 04 00 00 00 00 00 00 00 00 00 00 00 00
0001FBF0  00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00
...
0001FCA0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
0001FCB0  00 00 00 00 00 00 00 00                         

Here is MOD 30:

Code: Select all

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

0001FCB0                          08 14 31 1D 30 31 35 30          ..1.0150
0001FCC0  30 3F 00 00 00 00 00 00 00 00 00 00 00 00 02 00  0?..............
0001FCD0  2C 00 00 00 30 02 00 00 00 00 00 00 01 00 00 00  ,...0...........
0001FCE0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
...
0001FEA0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
0001FEB0  00 00 00 00 00 00 00 00                         

Here is MOD 0A:

Code: Select all

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

0001FFB0                          09 18 03 D4 0A 30 30 30          ...Ô.000
0001FFC0  30 3F 00 00 00 00 00 00 00 00 00 00 00 00 01 00  0?..............
0001FFD0  20 06 00 06 06 3F 3F 00 00 00 00 00 00 00 00 00   
0001FFE0  00 00 FF 0F 00 00 00 00 00 00 00 00 00 00 42 FE 

Each MOD has header information, including ...

Code: Select all

Offset          Description

0x03            Checksum byte
0x04            MOD ID
0x05 - 0x08     MOD version (ASCII)

The checksum byte is chosen so that the 8-bit sum of all the bytes within the MOD, including the checksum byte, is zero.
Attachments
PCMBlk1_tabl_cksm.jpg
PCMBlk1_tabl_cksm_calc.jpg
PCMBlk1_select_block.jpg
PCMBlk1_select_block.jpg (16.01 KiB) Viewed 1427 times
PCMBlk1_select_block_end.jpg
PCMBlk1_code_cksm_calc.jpg

Moltke
Guest
Guest

Re: Analysis of "ROM" on Western Digital WD2500BB-55RDA0 PCB

Postby Moltke » Mon May 06, 2013 7:52 pm

0x01 - 0x03 Page / Segment NazYura speculates that these bytes may denote Page / Segment

offset 01h-- FLAG. if 01h-unit packed,02h-not packed.


Return to “R&D - Experiments”

Who is online

Users browsing this forum: No registered users and 1 guest