Reading SDRAM configuration data with the Bus Pirate
SDRAM DIMMs have a standardized way of storing configuration data in an on-chip EEPROM. In this case the EEPROM is a 24C02, 256 Byte one. The storage of information in it is defined by the Serial Presence Detect - SPD standard. It integrates into the SMBus when plugged into a computer, and the BIOS uses the data contained to initialize memory access.
Wiring up a Bus Pirate, one could read that configuration directly from the RAM module.
Connections are done as follows:
- SCL => CLOCK
- SDA => MOSI
- VSS => GND
- VCC => 3.3V
Additionally, the Bus Pirate’s pull up pin VPU is connected with the supplied 5V pin. Now we can read the whole 256 Bytes of address space the EEPROM provides:
=~=~=~=~=~=~=~=~=~=~=~= PuTTY log 2012.10.04 01:21:37 =~=~=~=~=~=~=~=~=~=~=~= RESET Bus Pirate v3b Firmware v5.10 (r559) Bootloader v4.4 DEVID:0x0447 REVID:0x3043 (24FJ64GA002 B5) http://dangerousprototypes.com HiZ>m 1. HiZ 2. 1-WIRE 3. UART 4. I2C 5. SPI 6. 2WIRE 7. 3WIRE 8. LCD 9. DIO x. exit(without change) (1)>4 Set speed: 1. ~5KHz 2. ~50KHz 3. ~100KHz 4. ~400KHz (1)>3 Ready I2C>W Power supplies ON I2C>P Pull-up resistors ON I2C>v Pinstates: 1.(BR) 2.(RD) 3.(OR) 4.(YW) 5.(GN) 6.(BL) 7.(PU) 8.(GR) 9.(WT) 0.(Blk) GND 3.3V 5.0V ADC VPU AUX SCL SDA – – P P P I I I I I I I GND 3.29V 4.97V 0.00V 5.00V L H H H H I2C>(1) Searching I2C address space. Found devices at: 0xA0(0x50 W) 0xA1(0x50 R) I2C>[0xa0 0] I2C START BIT WRITE: 0xA0 ACK WRITE: 0x00 ACK I2C STOP BIT I2C>[0xa1 r:256] I2C START BIT WRITE: 0xA1 ACK READ: 0x00 ACK 0x08 ACK 0x04 ACK 0x0B ACK 0x09 ACK 0x02 ACK 0x40 ACK 0x00 ACK 0x01 ACK 0x75 ACK ….. NACK I2C STOP BIT I2C>
According to the SPD specification one could now associate the raw data with it’s meanings:
0x00 number of bytes written by manufacturer 0x08 size == 256 bytes 0x04 type == 4 == SPD SDRAM 0x0B bank row address 0x09 bank column address 0x02 number of banks == 2 0x40 module data width low == 64 0x00 data width high 0x01 interface voltage level 0x75 clock cycle time at highest CAS latency 0x60 sdram access time 0x00 DIMM config type => 0 == non-ECC 0x80 refresh period: self 0x08 bank1 data width == 8 0x00 bank1 ECC width == 0 0x01 clock delay for column reads == 0 0x8F burst lengths supported == 10001111b == page/8/4/2/1 0x02 banks per device == 2 ...