ottokiksmaler / nx500_nx1_modding

Samsung NX500 and NX1 Modding
GNU Affero General Public License v3.0
124 stars 42 forks source link

Recovering a bricked NX500 #121

Open bortek opened 1 year ago

bortek commented 1 year ago

I apologies if this question is inappropriate but please bear with me since this is the only technically advanced place I know of where I can get some expert opinion.

There is one interesting discussion in a closed Issue about bricking of nx500 and possibly fixing it using special recovery fw which only is available at Samsung. Have tried to contact them in the past with no result. I have one bricked nx500 since a few years back which I am still keeping in the drawer in the hope (just dreaming :) that one day I would get hold of such fw and recover it.

But now I have got my hands on nx300 and I wonder if:

ge0rg commented 1 year ago
  • It is possible to get the fw/image out of it in some way and pour it into the nx500 to bring it to life?

No, they have a different CPU and architecture. I've recently documented the different architecture generations in https://github.com/ge0rg/samsung-nx-hacks#device-support however even with two cameras from the same generations, you can not do a 1:1 firmware swap.

The service manual for other NX cameras outline that you can do an emergency install of a standard firmware file from SD card by shortening two triangle pins on the board. I haven't found these pins on the NX500 board though, and I don't have the service manual.

Here's how it looks for the NX300: image

If you find those pins on the NX500 board, then download and unzip the file from https://www.samsung.com/uk/support/model/EV-NX500ZBMHDE/#downloads to a FAT32 SD card, short these pins and turn on the camera. When the LED stops blinking and turns off, you should have a new firmware installed.

ge0rg commented 1 year ago
  • Alternatively is it possible to swap parts of the HW from nx300 into nx500 thus having nx500 back to life ?

This will not be possible, except maybe for some tiny parts like buttons or dials.

bortek commented 1 year ago

Thanks for the tips. So there's a hope to reincarnate my nx500. I think I have a service manual. Need to look for the pins to short if they exist on nx500 board. Will update this post in a couple of days.

bortek commented 1 year ago

I digged into the service manual and it says basically what I wrote above. To recover using shorting pins you need nx500.bin and also downloader.bin which only Samsung has. :(

image
ge0rg commented 1 year ago

I'm very sorry. I've now checked the OSS dumps I have from Samsung, but the only downloader I was able to find is the one from NX300, https://github.com/ge0rg/samsung-nx-hacks/issues/16

I'm pretty sure it won't work as is on the NX500 due to the different architecture.

bortek commented 1 year ago

Thanks for taking your time and checking it out! That dnloader.bin file you linked to is 27KB and looks like a binary executable file with ASCII characters/error strings at the end of file and references. So a similar file but for nx500 exist(ed). What does that file actually do, if you know that?

I tried searching that file via wayback machine (archive.org) and using some links I had to the file but that did not went that well.

If you come up with some other idea just let me know. :)

ge0rg commented 1 year ago

I assume that dnloader.bin is a helper tool that is needed by the boot loader to flash the nx500.bin from the SD card in recovery mode. I've also asked Samsung OSS team to provide it, but their answer was negative:

EV-NX500 is a model released about 8 years ago. Unfortunately, since it has been a long time, please understand that it is difficult for the development team that developed the project to handle your request. Please accept our apology for not being able to handle your request up to your satisfaction.

Bummer.

ge0rg commented 1 year ago

Samsung has uploaded the source code for Galaxy NX, and there is also a TIZEN folder, with a packages/bootloader_gu inside. This is the bootloader source code apparently, but again for a different device! Maybe it will help us at least finding out what exactly is happening where.

bortek commented 1 year ago

I can have a look inside it and see if I can find anything valuable.

Will also try to email contacts that are available at their open source site. I'm pretty sure they have all the software archived internally. Just finding the right person at Samsung wiling to help can solve it too.

ge0rg commented 1 year ago

I even contacted the developer who packaged the NX500 source zip, and he told me that he's working in a different Samsung department and doesn't have access to old source code. I think we really need an insider to make any further progress.

That said, I've documented the "SLP" bin file format and had a look at the boot / flashing process. Flashing the NX300 works by starting the "vImage" Linux kernel + initramfs from the nx300.bin file, and it does the heavy lifting then. The NX500 comes with three different Linux kernels:

chunk-00.bin: u-boot legacy uImage, Linux-3.5.0, Linux/ARM, OS Kernel Image (Not compressed), 6139400 bytes, Tue Feb 17 06:28:40 2015, Load Address: 0X86008000, Entry Point: 0X86008000, Header CRC: 0X518EC06, Data CRC: 0XC3B1954A
chunk-02.bin: u-boot legacy uImage, Linux-3.5.0, Linux/ARM, OS Kernel Image (Not compressed), 3174056 bytes, Mon Feb 23 07:37:53 2015, Load Address: 0X86008000, Entry Point: 0X86008000, Header CRC: 0XFF79B284, Data CRC: 0XE43ADD40
chunk-03.bin: u-boot legacy uImage, Linux-3.5.0, Linux/ARM, OS Kernel Image (Not compressed), 6150920 bytes, Tue Feb 17 06:29:45 2015, Load Address: 0X86008000, Entry Point: 0X86008000, Header CRC: 0X9D221717, Data CRC: 0XE6323FE4

chunk-00 and 03 are >6MB, so I suppose at least one of them contains the "regular" firmware update code, but I didn't look inside yet. chunk-01 is the DRIMe5 bootloader that's probably responsible for the recovery mode, but it doesn't contain any of the relevant file names ("nx500.bin", "downloader.bin").

There are a few firmware update related strings in chunk-05.bin, but it's 11MB and probably the whole OS for the "real-time" CPU core of the DRIMe5, and also no mention of the two interesting file names.

If you want to further reverse engineer the "regular" updater:

  1. extract chunk-00.bin from the nx500.bin using slp-firmware.py or dd, it will contain a gzip compressed Linux + initramfs
  2. binwalk chunk-00.bin to find out the "gzip compressed data" and extract that into vImage.gz
  3. extract vImage and ignore the trailing garbage
  4. binwalk vImage to find "gzip compressed data" (should be around 4.5MB) and extract into initramfs.cpio.gz
  5. extract initramfs.cpio and have fun with it!
bortek commented 1 year ago

wow looks like you have already done quite a lot work👍 :) If I follow the recipe above and reach point 5, having initramfs.cpio in hand will likely not yield downloader.bin but could just be a fun exercise to do.

bortek commented 1 year ago

Got a reply from Samsung, of course a standard reply and with reference to their open source site. Interestingly there is a 1.3G file available called NX500_opensource.zip if you search for it using this URL https://opensource.samsung.com/uploadSearch?searchValue=nx500

I wonder if you have previously looked into it in case if contains source for the downloader that could be compiled into a binary?

ge0rg commented 1 year ago

I checked the NX500_opensource.zip, it contains the Linux kernel and a large collection of boring OSS packages. It's missing all of the booting and flashing related things and any resemblance of a fw_generator that was part of the NX300 drop.

I've also made some progress with the chunk-00 "vImage" partition. It contains a shell script /init that's called by the Linux kernel, and that runs various preparation tasks, culminating in calling fw_update /mnt/mmc/nx500.bin - fw_update is a compiled ELF binary that does sanity checks of the bin file, then loads /etc/parttab to know which partition images in the bin correspond to which eMMC partition (it's using a standard DOS partition table with an extended partition and quite a few small partitions, all typed "Linux"): https://github.com/ottokiksmaler/nx500_nx1_modding/issues/13#issuecomment-218549512

I'd say the rough execution is as follows:

  1. load and print firmware info
  2. check if the board version matches
  3. Load /etc/parttab to know the partitions and which ones to format (create "preprocessing" function table)
  4. Call preprocessing functions (TODO; backup config files?)
  5. Call mkfs functions (TODO)
  6. Call postproc functions (TODO)
  7. Create empty /etc/snapshot file (I suppose this is some notification mechanism for the main firmware?)
  8. Flash MICOM firmware /tmp/micom.hex (no idea what a MICOM is, probably unused on NX500)
  9. Reboot
bortek commented 1 year ago

Thus suddenly started to look like an impossible task 😒

ge0rg commented 1 year ago

There are actually three init script templates inside the initramfs:

I assume that the rImage is flashed to the eMMC as part of the regular update process, and used as some kind of fallback if firmware updating fails, and xImage is loaded from SD based on some magic inside the bootloader that I haven't identified yet. Maybe "downloader.bin" was a red herring after all and we need something else?

bortek commented 1 year ago

You mean downloader.bin is questionable and was not even used, since you cannot find any references to it, so long. If that is the case then the whole recovery process of a bricked nx500 is being questioned. Do we have anyone doing that in the past successfully?

ge0rg commented 1 year ago

I don't think we have anybody who unbricked an NX500 or NX1 before.

I've now extracted the actual bootloader from a camera's /dev/mmcblk0boot0 and it's quite surprising. It's not a direct copy of bootloader.bin from chunk-01, but it has a 512 byte header followed by the bootloader. The first 256 bytes are a standard interrupt/reset vector table, where all but the reset vector run an endless loop, and reset jumps to memory location 0x80000000, i.e. 2GB. I'm not sure what is mapped to that address, but I would rather have expected a jump to +512 bytes to end up in the actual bootloader.

The second 256 bytes are quite interesting, as they have a version identifier and some kind of file table mentioning interesting files:

00000100: 4452 494d 4535 5f00 4435 5f44 4d43 5f45  DRIME5_.D5_DMC_E
00000110: 535f 5f00 5245 5630 3030 3000 0400 0000  S__.REV0000.....
00000120: 0000 0000 7d00 0000 0002 0002 626f 6f74  ....}.......boot
00000130: 6c6f 6164 6572 2e62 696e 0000 0000 0000  loader.bin......
00000140: 0180 0200 b41a 0000 c07f 0086 7549 6d61  ............uIma
00000150: 6765 0000 0000 0000 0000 0000 0000 0000  ge..............
00000160: 0000 0000 2501 0000 0000 0018 6465 7669  ....%.......devi
00000170: 6365 6d34 2e62 696e 0000 0000 0000 0000  cem4.bin........
00000180: 01d0 0200 225c 0000 0000 0080 726f 6d2e  ...."\......rom.
00000190: 6269 6e00 0000 0000 0000 0000 0000 0000  bin.............
000001a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

I'm not sure yet what this header is about, bootloader.bin is just that partition, uImage, devicem4.bin and rom.bin are other partitions of the system. I also didn't see any references to that table in the code yet.

ge0rg commented 1 year ago

To add confusion to the list of (non)bootloaders. I've now dumped the first 32KB of physical memory, starting at 0x00000000, which probably contain the flash(ROM?) of the initial bootloader, and there is a mention of "downloader.bin" inside of it indeed. It also starts with a vector table, and code that looks like a bootloader indeed, but zero strings, making it rather hard to reverse-engineer.

I've uploaded the extracted memory to https://op-co.de/tmp/nx500-memory-dump-0x00000000.bin - if anybody is bored enough, it's ARM7 code to be loaded to memory location 0x00000000 and the reset vector is the first command in there.