DIY Firmware

If you're interested in making your own firmware, you're on the right page! Since I seem to be the first person on the internet to tailor the camera firmware, I figured I should publish what I've learned.

These same concepts should apply to the NX30, NX300M, and NX2000 cameras as well, possibly others. Tread carefully through this guide, as installing a bad firmware image on your camera could kill it. Sending it in for repair can be costly.

Specification

The firmware (nx300.bin) consists of the following:

    • Header
    • vImage contents
    • D4_IPL.bin contents
    • D4_PNLBL.bin contents
    • uImage contents
    • platform.img contents
    • Another header for pcache.list
    • pcache.list contents

The main header consists of:

    • Contents of version.info and some other stuff (0x0000 .. 0x003F)
    • Metadata for vImage (0x0040 .. 0x004F)
    • Metadata for D4_IPL.bin (0x0050 .. 0x005F)
    • Metadata for D4_PNLBL.bin (0x0060 .. 0x006F)
    • Metadata for uImage (0x0070 .. 0x007F)
    • Metadata for platform.img (0x0080 .. 0x008F)

The header for pcache.list is similar to the metadata for the other files.

The metadata is four 32-bit values, each is in little-endian byte order:

    • Size of the file.
    • CRC
    • Start Location in nx300.bin.
    • I assume where it goes in camera flash.

The CRC used is:

width=32 poly=0x04c11db7 init=0xffffffff refin=true refout=true xorout=0x00000000 check=0x340bc6d9 name="JAMCRC"

CRCs can be checked with jacksum:

jacksum -x -a crc:32,04c11db7,ffffffff,true,true,00000000 [file]

Pulling it Apart

Note: Linux is required for all of these steps. If you're stuck on Windows, you can use VirtualBox with a Lubuntu install. Or, any Linux LiveCD should work as long as you have a place for over 5 gigs of files.

Unzip nx300.tar.gz and pull out a few files into a new directory:

tar xvf nx300.tar.gz

mkdir tailored_fw

cp ./TIZEN/build/fw_generator ./tailored_fw

cp ./TIZEN/project/NX300/image/rootdir_3-5/etc/version.info ./tailored_fw

(Note: The version.info file can be edited to specify a version or match an existing header. For this writeup, I'm using the v1.42 binary with the v1.41 source package. I'll modify the strings to match.)

Also put the "nx300.bin" firmware file in the tailored_fw directory. Rename it so it doesn't get overwritten:

cd tailored_fw

mv nx300.bin nx300_original.bin

You'll need to write down the values from the nx300_original.bin metadata for each of the files. I use "vbindiff" to view the hex because it formats it neatly into 16-byte lines, which aligns perfectly for getting the values. Here's all the values for v1.42: (Remember that the pcache.list metadata is after the platform.img contents.)

vImage size: 0x004F4148 (5194056)

vImage CRC: 0xA54839A6

vImage offset: 0x00000090 (144)

D4_IPL.bin size: 0x00001B4C (6988)

D4_IPL.bin CRC: 0x3E2CDCC9

D4_IPL.bin offset: 0x004F41D8 (5194200)

D4_PNLBL.bin size: 0x0000F5D0 (62928)

D4_PNLBL.bin CRC: 0x1D3B7206

D4_PNLBL.bin offset: 0x004F5D24 (5201188)

uImage size: 0x0029E178 (2744696)

uImage CRC: 0xC46D6F14

uImage offset: 0x005052F4 (5264116)

platform.img size: 0x13D20000 (332529664)

platform.img CRC: 0xA353C393

platform.img offset: 0x007A346C (8008812)

pcache.list size: 0x00009000 (36864)

pcache.list CRC: 0x289E0951

pcache.list offset: 0x144C347C (340538492)

Extract each of the files from the binary with:

dd skip=[offset] count=[size] if=nx300_original.bin of=[file] bs=1

Where [file] is the filename, and [offset] and [size] are the respective integer numbers. Note: platform.img will take a while (an hour or so).

Optionally, check each of the CRCs with jacksum.

jacksum -x -a crc:32,04c11db7,ffffffff,true,true,00000000 *

3e2cdcc9 6988 D4_IPL.bin

1d3b7206 62928 D4_PNLBL.bin

289e0951 36864 pcache.list

a353c393 332529664 platform.img

c46d6f14 2744696 uImage

a54839a6 5194056 vImage

Reassembly

The easier way to make sure everything is correct is to reassemble the files and validate the new binary:

./fw_generator version.info

shasum nx300.bin nx300_original.bin

The checksums should match. If not, use vbindiff to figure out what might be wrong. Most likely, the version.info file doesn't match the firmware, or one of the files was extracted incorrectly.

Note: All of the files that were pulled from the nx300_original.bin file are used by fw_generator. It will open the files by the names listed above, and output "nx300.bin". So be sure to have the names correct and expect nx300.bin to be overwritten.

At this point, you're ready to edit the platform.img file and customize your camera.

Editing platform.img

You can't directly edit platform.img in a hex editor. It's a UBI image file which uses compression. But, you can mount it in a simulated device and reconstruct the file after you tailor the contents.

Prep

Backup your original platform.img file since it'll be overwritten:

cd tailored_fw

cp platform.img platform_original.img

Obtain the UBI configuration file and put it in the tailored_fw directory:

cp ../TIZEN/project/NX300/image/ubi_rootdir.conf ./

FYI, the contents of ubi_rootdir.conf are:

[rootdir.volume]

mode=ubi

image=rootfs.ubifs

vol_id=0

vol_name=rootdir

vol_size=350MiB

vol_type=dynamic

vol_alignment=1

vol_flags=autoresize

Install the utility needed to work with UBI images.

sudo apt-get install mtd-utils

Simulating the UBI

I assume you're still in the tailored_fw directory. The steps below for simulating the NAND and recreating the platform.img file should all be done in one sitting. Rebooting gets rid of the simulated NAND device. Everthing below needs root access, so log in as root:

sudo su

Create a simulated 512mb NAND flash with 2048 byte pages. Note that this uses RAM by default. Here, I include the cache_file parameter to use disk instead.

modprobe nandsim cache_file=./temp_nand.dat first_id_byte=0x20 second_id_byte=0xac third_id_byte=0x00 fourth_id_byte=0x15

Show it with:

cat /proc/mtd

dev: size erasesize name

mtd0: 20000000 00020000 "NAND simulator partition 0"

Copy the platform.img (original) over to the NAND:

dd if=platform_original.img of=/dev/mtd0 bs=2048

Attach UBI to the NAND MTD:

modprobe ubi

ubiattach -m 0 -O 2048

Mount it:

mkdir /mnt/ubi

mount -t ubifs ubi0_0 /mnt/ubi

At this point, /mnt/ubi is a read-write directory with the camera software.

My Updates

Although you can run scripts from the MMC, I'd like a more permanent solution. My trivial update is to run a custom script from the read-write UBI1 partition on the camera, which is the same place where the settings seem to be stored. I can test the script from the MMC first, then move it to UBI1 when I'm comfortable with making it "semi-permanent". System boot seems to call /sbin/init (which is busybox), which calls /etc/init.d/rcS by default. Beware though, from trial and error, I found that rcS can't seem to access /mnt/ubi1 for a few seconds. (Tested with a 3 second delay. The camera seems to fully boot in 2 seconds, so 3 should be ideal)

Edit /mnt/ubi/etc/init.d/rcS and add this to the end:

sleep 3

/mnt/ubi1/custom.sh &

Then, root the device and copy in whatever script you want. It'll run when the camera boots. Best of all, you can tweak it without generating new firmware and reflashing the camera.

Repackaging the Firmware

FYI, the camera's MTD information is as follows. The numbers in the commands below come from here.

nx300:/# mtdinfo /dev/mtd4 -u

mtd4

Name: platform_img

Type: nand

Eraseblock size: 131072 bytes, 128.0 KiB

Amount of eraseblocks: 3200 (419430400 bytes, 400.0 MiB)

Minimum input/output unit size: 2048 bytes

Sub-page size: 2048 bytes

OOB size: 64 bytes

Character device major/minor: 90:8

Bad blocks are allowed: true

Device is writable: true

Default UBI VID header offset: 2048

Default UBI data offset: 4096

Default UBI LEB size: 126976 bytes, 124.0 KiB

Maximum UBI volumes count: 128

Create the platform.img file with the following commands. You don't need to be root for these, and I assume you're in the tailored_fw directory.

mkfs.ubifs -r /mnt/ubi -m 2048 -e 126976 -c 3200 -o rootfs.ubifs

ubinize -o platform.img -p 128KiB -m 2048 ubi_rootdir.conf

It would be wise to put this new platform.img into a simulated NAND MTD just to be sure things look correct and that the UBI drivers correctly read the data. You'll need to reboot and follow the "Simulating the UBI" steps with this new file.

Then, rebuild the nx300.bin:

./fw_generator version.info

I'd also check to make sure the headers look correct:

vbindiff nx300_original.bin nx300.bin

Follow Samsung's steps for upgrading the firmware to install the tailored nx300.bin into the camera. Good luck!