Skip to content

SLP Firmware Format

Georg Lukas edited this page Mar 7, 2023 · 8 revisions

Reverse engineering of SLP firmware files

This is the container format used for Samsung Linux Platform (SLP) on NX300/NX1/Gear360/..., e.g. nx300.bin. The firmware file contains a header and multiple partition files. There are two versions of the firmware header format:

  • V1 (DRIMe4, NX300/NX2000/NX30/Galaxy NX): 5 hardcoded partitions (with optional pcache.list)
  • V2 (DRIMe5, NX1/NX500/Gear360): 9 or 10 partitions

The information documented here has been implemented into slp-firmware.py:

usage: slp-firmware.py [-h] [-p] [-x] [-o DIR] FILE.bin [FILE.bin ...]

positional arguments:
  FILE.bin              firmware file to analyze / extract

options:
  -h, --help            show this help message and exit
  -p, --partitions      print detailed partition information
  -x, --extract         extract partitions into sub-directory ./FILE/
  -o DIR, --output DIR  override output directory for partitions

Relevant links:

Additional data from:

  • reverse engineering of NX300 and Galaxy NX (V1) fw_generator (thanks Samsung for shipping debug symbols!)

Firmware Meta Header fwfile_meta

Each firmware file begins with a 64 byte meta header, defined as follows:

Offset Size Type Name Comment
0 4 char[4] magic_code "SLP\0" in all known files, "DRM5" apparently also valid
4 8 char[8] version_user null-terminated version string like "1.01"
12 16 char[16] project_name human readable device name, e.g. "NX1"
28 16 char[16] version_date firmware release, e.g. "NX1GLUANK6"
44 1 char has_pcache V1: 0/1 bool; V2: num_image number of partition images (usually 9 or 10, max: 15)
45 4 uint32 pcache_offset V1: offset to pcache fw_image_header in firmware file; V2: flag "snapshot image included"
49 15 char[15] reserved V1: unused; V2: board version string

It's constructed by the fw_generator from a version.info file that's part of release planning and is also often bundled into the rootfs.

Example version.info content from the extracted nx300m.bin, with version_user, project_name, version_date and ???:

1.15
NX300M
NX300MGLUANL1
DSP_NX300MGLUANL1_SR1

Firmware Image Structure fw_image_header

The firmware meta header is followed by the image header, containing a list of partition images. For each partition, the following data is stored:

Offset Size Type Name Comment
0 4 uint32 img_len Length of partition image
4 4 uint32 crc32 CRC32 of partition image
8 4 uint32 img_offset Offset of partition image in bin file
12 4 uint32 magic 0x87654321 shifted depending on the partition position
16 8 char[8] ??? Only V2: often filled with zero bytes, second entry is seven-digit hex (e.g. "3D3BFA3")

In V1 files, there are always five image headers with 16 bytes each, in V2 it's 9x or 10x 24 bytes.

V1 Partitions

The order of the images is hardcoded in fw_generator, e.g. as follows for V1:

  1. vImage - Linux image for firmware updater (~6MB)
  2. D4_IPL.bin - Initial Program Load
  3. D4_PNLBL.bin - Second Stage Nand Bootloader
  4. uImage - Linux image for normal boot (~2MB)
  5. platform.img - Linux rootfs

They can be extracted from the image with dd and re-created using the fw_generator.

V2 Partitions

There is currently no known documentation of the partition ordering, but from NX1 firmware 1.01 the following results are analyzed:

  1. vImage - Linux image for firmware updater (~6MB)
  2. "DRIMe5 bootloader" - seems to be combined IPL & PNLBL as opposed to DRIMe4
  3. uImage - Linux image for normal boot (~4MB)
  4. "T-Kernel Version 2.01.03" - TRON image for Cortex-A7 core? (~10MB)
  5. rootfs - ext4 image of the Linux rootfs (730MB)
  6. 54KB Intel HEX dump of something
  7. opt - ext4 image for /opt (100MB)
  8. library cache? (28KB)
  9. swap - Linux swap partition for software suspend (100MB)

Starting with 1.21, the NX1 firmware adds another Linux kernel(!) and uses LZO compression for the filesystems.

Actual data

The actual partitions are concatenated right after the image header.