Skip to content

Western Digital Firmware

Ryan Miceli edited this page May 14, 2026 · 2 revisions

The firmware for Western Digital drives contains section headers for each segment, a loader segment, and several code and data segments. Some segments may be compressed but no encryption or obfuscation is used.

Section Headers

At the very beginning of the firmware image are the section headers which describe each section contained in the image. The section headers have the following structure:

struct section_header
{
    /* 0x00 */ unsigned char id;                       // Block id
    /* 0x01 */ unsigned char flags;                    // 1 = compressed, 2 = data, 4 = bootloader
    /* 0x02 */ unsigned short decompressed_size_hi;    // High 16 bits of decompressed size
    /* 0x04 */ unsigned int total_size;                // Size of the section including the checksum
    /* 0x08 */ unsigned int raw_size;                  // Size of the section without the checksum
    /* 0x0C */ unsigned int offset;                    // Offset of the section data
    /* 0x10 */ unsigned int address;                   // Base address of the section in memory
    /* 0x14 */ unsigned int entry_point;               // Entry point of the section (bootloader only)
    /* 0x18 */ unsigned int unknown1;
    /* 0x1C */ unsigned short decompressed_size_low;   // Low 16 bits of the decompressed size
    /* 0x1E */ unsigned char unknown2;                 // Not used?
    /* 0x1F */ unsigned char header_checksum;          // Checksum of section header data minus this byte
};

Each section header has a checksum which is an 8-bit summation of the first 32 bytes of the section header. The section data pointed to by the offset field is composed of raw_size number of bytes followed by a checksum which uses the same 8-bit summation calculation as the section headers. The total_size field is the size of the section data and checksum byte combine.

The first section header should always be the loader section which is responsible for loading the remaining sections into memory during bootup.

Flags

The following table describes the possible section flags and their meanings:

Value Description
0x01 Indicates the section data is compressed.
0x02 Section contains data (i.e.: non-executable).
0x04 Section is the loader code.

Compression

Some sections can be compressed which is indicated by flag 0x1. The compression algorithm used is LZHUF with a few modifications:

  • The N constant was changed from 2048 to 4096.
  • The run length calculation now subtracts THRESHOLD instead of adding it, ex: j = c - 255 - THRESHOLD.

For a complete implementation see lzhuf.py.

Checksum

Each section header and block of section data contains an 8-bit summation checksum that's found at the end of the section header/block of data. The checksum can be calculated by adding every byte together like so:

unsigned char calculate_checksum(unsigned char* data, unsigned int length)
{
	unsigned char checksum = 0;
	
	for (unsigned int i = 0; i < length; i++)
		checksum += data[i];
		
	return checksum;
}

Clone this wiki locally