Serial Console on WansView M-Series NCM625W Camera

Recently, I got a WansView NCM625W, which is one of their „M Series“ IP cameras. Sites like Open IP Camera Forum suggest that most such cameras have pads for a serial console somewhere on the mainboard, but I could not find anything specific for this model. Thus, I switched on the scope and began to look for potential candidates on the mainboard.

IMPORTANT NOTE: The following steps will void the warranty of your camera. It is easy to brick your camera (on hardware level when trying to connect to the serial port or by doing a mistake on software level). Furthermore, you should be experienced in doing these kinds of hardware/software modifications; I am not going to describe every step in all detail. I take no responsibility for your actions. WansView may change the hardware/software at any time (even without changing the type label), rendering this description completely useless or even harmful. You have been warned.

Here is the bottom view of the camera, the screws are below the four small pads (already removed in the picture):

Bottom view of the camera
Bottom view of the camera

The component side of the board looks like this. The serial port has the typical four pads and is labeled J13 on my camera:

NCM625W Mainboard with location of serial port
NCM625W Mainboard with location of serial port
Serial Port Pinout
Serial Port Pinout

Serial port is 3.3v (i.e. you will need a level converter like this one). Pinout is:

1 TX from board (first pin is marked with a square pad)
2 Ground
3 RX into board
4 Probably +3.3v (not needed for serial communication, do not attach)

Serial settings are 38400 Baud, 8N1

Booting

Here is the output from the serial console when booting (until init is started in the initial ramdisk):

MP SPI-NOR Bootstrap v0.2
Boot image offset: 0x10000. Booting Image .....
0567Will set the following freq...
PLL1: 800 MHz, PLL2: 540 MHz, CPU freq: 540 MHz, AHB freq: 270 MHz, DDR freq: 800 MHz
go...

*********************************************
Please input Space to run Linux
Please input ESC to run UBOOT
Please input . to run burn-in
Otherwise, system will run Linux after 1 sec
*********************************************
Load image from SPI-NOR offset 0xd0000 to sdram 0x4000000
Jump 0x4000000
Uncompressing Linux........................................................................................................................................................................................................................ done, booting the kernel.
Linux version 2.6.28 (root@gm8126.localdomain) (gcc version 4.4.0 (Faraday C/C++ Compiler Release 20100325) ) #175 PREEMPT Wed Jul 24 10:05:05 HKT 2013
CPU: FA626TE [66056261] revision 1 (ARMv5TE), cr=0000797f
CPU: VIPT aliasing data cache, VIPT aliasing instruction cache
Machine: Faraday GM8126
Warning: bad configuration page, trying to continue
Memory policy: ECC disabled, Data cache writeback
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 32512
Kernel command line: mem=128M console=uart,shift,2,io,0xF9830000,38400
Early serial console at I/O port 0xf9830000 (options '38400', shift 2)
console [uart0] enabled
PID hash table entries: 512 (order: 9, 2048 bytes)
IC: GM8128 MP
GM Clock: CPU = 540 MHz, AHBCLK = 270 MHz, PLL1CLK = 800 MHz, PLL2CLK = 540 MHz
console handover: boot [uart0] -> real [ttyS0]
Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
Memory: 128MB = 128MB total
Memory: 122708KB available (3677K code, 355K data, 2984K init)
Calibrating delay loop... 532.48 BogoMIPS (lpj=266240)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
net_namespace: 288 bytes
Fmem: node 0 is online, alloc pages = 8192(active pages = 32768)
high_memory:0xc8000000, VM Start:0xc8800000, End:0xe0000000
NET: Registered protocol family 16
PMU: Mapped at 0xf9900000
pmu_get_cpu_clk:221
Attach GM AHB-DMA Driver
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
cfg80211: Using static regulatory domain info
cfg80211: Regulatory domain: US
(start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
(2402000 KHz - 2472000 KHz @ 40000 KHz), (600 mBi, 2700 mBm)
(5170000 KHz - 5190000 KHz @ 40000 KHz), (600 mBi, 2300 mBm)
(5190000 KHz - 5210000 KHz @ 40000 KHz), (600 mBi, 2300 mBm)
(5210000 KHz - 5230000 KHz @ 40000 KHz), (600 mBi, 2300 mBm)
(5230000 KHz - 5330000 KHz @ 40000 KHz), (600 mBi, 2300 mBm)
(5735000 KHz - 5835000 KHz @ 40000 KHz), (600 mBi, 3000 mBm)
cfg80211: Calling CRDA for country: US
Switched to NOHz mode on CPU #0
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 4096 (order: 3, 32768 bytes)
TCP bind hash table entries: 4096 (order: 2, 16384 bytes)
TCP: Hash tables configured (established 4096 bind 4096)
TCP reno registered
NET: Registered protocol family 1
Video Timer(timer3) Max 31000ms in 0xf9720840 HZ.
JFFS2 version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
msgmni has been set to 239
alg: No test for stdrng (krng)
io scheduler noop registered
io scheduler anticipatory registered (default)
io scheduler deadline registered
io scheduler cfq registered
probe ftgpio010.0 OK!!, at c8858000
probe ftgpio010.1 OK!!, at c885c000
probe ftgpio010.2 OK!!, at c8860000
Serial: 8250/16550 driver 4 ports, IRQ sharing disabled
serial8250: ttyS0 at I/O 0xf9830000 (irq = 9) is a 16550A
serial8250: ttyS1 at I/O 0xf9840000 (irq = 10) is a 16550A
serial8250: ttyS3 at I/O 0xf9880000 (irq = 21) is a 16550A
brd: module loaded
loop: module loaded
PPP generic driver version 2.4.2
PPP Deflate Compression module registered
PPP BSD Compression module registered
PPP MPPE Compression module registered
NET: Registered protocol family 24
PPPoL2TP kernel driver, V1.0
tun: Universal TUN/TAP device driver, 1.6
tun: (C) 1999-2004 Max Krasnyansky
Linux video capture interface: v2.00
Driver 'sd' needs updating - please use bus_type methods
Driver 'sr' needs updating - please use bus_type methods
Creating 6 MTD partitions on "wb_spi_flash":
0x000d0000-0x005ff000 : "Linux Section"
0x00600000-0x01000000 : "User Section"
0x00001000-0x00010000 : "Loader Section"
0x00010000-0x000b0000 : "BurnIn Section"
0x000b0000-0x000ce000 : "UBoot Section"
0x000ce000-0x000d0000 : "CFG Section"
Probe FTSSP010 SPI Controller at 0x98200000 (irq 6)
usbmon: debugfs is not available
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
AMBA bus_register ok
Enter Device A
temp = 340
Drive Vbus because of ID pin shows Device A
otg2xx device_register ok
AMBA_bus_match(...) Found Driver FOTG2XX_DRV
AMBA_bus_match(...) Found Driver FOTG2XX_DRV
FOTG2XX_DRV fotg2xx_dev: GM USB2.0 Host Controller
FOTG2XX_DRV fotg2xx_dev: new USB bus registered, assigned bus number 1
FOTG2XX_DRV fotg2xx_dev: irq 4, io mem 0xf9220000
FOTG2XX_DRV fotg2xx_dev: USB 2.0 started, EHCI 1.00
usb usb1: configuration #1 chosen from 1 choice
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 1 port detected
FOTG200 Controller Initialization
fotg200 int enable = 1f30
Initializing USB Mass Storage driver...
usbcore: registered new interface driver usb-storage
USB Mass Storage support registered.
i2c /dev entries driver
ftiic010 ftiic010.0: irq 18, mapped at c886c000
Advanced Linux Sound Architecture Driver Version 1.0.18rc3.
ALSA device list:
No soundcards found.
TCP cubic registered
NET: Registered protocol family 17
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
ieee80211: 802.11 data/management/control stack, git-1.1.13
ieee80211: Copyright (C) 2004-2005 Intel Corporation
Freeing init memory: 2984K
usb 1-1: new high speed USB device using FOTG2XX_DRV and address 2
port status 10009
2nd port status 10009
***************************************
Busybox starts to run
***************************************

Unfortunately, the device does not start a serial console with a shell by default. The serial console is only used to log additional information that is not visible in the system log that can be accessed via the web interface of the camera.

Booting into U-Boot

The boot sequence of the GM8126 platform is somewhat strange. It boots into a bootloader of its own. This bootloader is able to start Linux directly (which is the default), but may also start U-Boot. One just needs to send Escape all the time while powering up the device.

This looks like this:

MP SPI-NOR Bootstrap v0.2
Boot image offset: 0x10000. Booting Image .....
0567Will set the following freq...
PLL1: 800 MHz, PLL2: 540 MHz, CPU freq: 540 MHz, AHB freq: 270 MHz, DDR freq: 800 MHz
go...

*********************************************
Please input Space to run Linux
Please input ESC to run UBOOT
Please input . to run burn-in
Otherwise, system will run Linux after 1 sec
*********************************************
Load image from SPI-NOR offset 0xb0000 to sdram 0x4000000
Jump 0x4000000

U-Boot 2008.10 (Aug 9 2012 - 13:27:23)

I2C: ready
DRAM: 128 MB
Manufacturer ID : 0018
Device ID : 009F
Device Code 2 : 0018
Flash: 0 kB
#SF: Got idcode ef 40 18
##crc data not match, calc = b694bf29, env field = 8d9f7217
*** Warning - bad CRC, using default environment

In: serial
Out: serial
Err: serial
Net: FTMAC110#0
Hit any key to stop autoboot: 0
=>

Let’s print the default environment:

=> print
bootargs=
bootcmd=sf probe 0:0;sf read 0x4000000 0xd6100 0x800000;go 0x4000000
bootdelay=1
baudrate=38400
ethaddr=00:34:72:23:78:FE
ipaddr=10.0.1.52
serverip=10.0.1.51
gatewayip=10.0.1.51
netmask=255.0.0.0
ethact=FTMAC110#0
ver=U-Boot 2008.10 (Aug 9 2012 - 13:27:23)

Environment size: 268/8188 bytes
=>

Backup the Flash Memory

I think it is a good idea to make a backup of the SPI flash first. I have only found an indirect way to do so: Load the contents of the entire flash into RAM, dump the RAM via the md command and convert the hexdump back into binary form.

NOTE: This „backup“ is only of limited use because you need U-Boot to reflash it. If the initial boot loader or U-Boot is corrupted, you won’t get to this point. However, you could use this backup to reflash the Linux and User parts.

First, initialize the SPI flash:

=> sf probe 0:0
#SF: Got idcode ef 40 18
16384 KiB W25Q128BV at 0:0 is now current device

The camera seems to have 16MB of flash. Load the entire contents into RAM:

=> sf read 0x4000000 0x0 0x1000000
#################################################################################################################################=>

and begin to dump it (do not forget to capture the output into a file):

=> md.b 0x4000000 0x1000000
04000000: 47 4d 38 31 32 36 00 00 00 00 01 00 00 00 01 00 GM8126..........
04000010: 00 00 0b 00 00 00 0d 00 00 00 00 00 00 00 00 00 ................
04000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
...

At 38400 Baud, this will take ages (6 hours or so)…

I hacked together a small Python script to convert the memory dump to a binary image file.

Download: uboot_mdb_to_image.py (GitHub repository is at gmbnomis/uboot-mdb-dump)

Remove everything but the memdump lines (i.e. the lines starting from „04000000“ until „04fffff0“) from the serial capture file and convert it like this on a Linux box:

# python3 uboot_mdb_to_image.py < wansview_mem_dump_complete.cap > Wansview_NCM625W_flash.img

Structure of the Flash image

The MTD partitions displayed while booting the Linux kernel (see above) shows the structure of the 16MB flash:

Creating 6 MTD partitions on "wb_spi_flash":
0x000d0000-0x005ff000 : "Linux Section"
0x00600000-0x01000000 : "User Section"
0x00001000-0x00010000 : "Loader Section"
0x00010000-0x000b0000 : "BurnIn Section"
0x000b0000-0x000ce000 : "UBoot Section"
0x000ce000-0x000d0000 : "CFG Section"

  • „Linux Section“: Linux Kernel zImage with an embedded initial ramdisk. There is a 256 byte header in front of the zImage. This header is probably used by the initial boot loader.
  • „User Section“: JFFS2 file system containing the camera software and the configuration.
  • „Loader Section“: This is probably the initial boot loader, which is able to start Linux, U-Boot, and Burn-in
  • „BurnIn Section“: No idea what this actually does, I did not dare to start it via the initial boot loader
  • „UBoot Section“: U-Boot
  • „CFG Section“: Not sure. This might be the area designated for U-Boot configuration data. The area is empty in my case (filled with 0xff). I did not dare to try to write the environment back to flash in U-Boot. If that does not work correctly, this may overwrite vital parts needed for booting.

Extracting the Linux Image

Extract the Linux section from the obtained image according to the MTD table given above, e.g. like this (in a totally inefficient way):

# dd if=Wansview_NCM625W_flash.img of=Wansview_NCM625W_flash_Linux.img bs=1 skip=851968 count=5435392

The resulting file should have a size of 5435392 bytes; the SHA256 of my image is 93007640c6a4a45cdd2d9bce8d04d71a2215124d2c0097bfcb66158f917acf01 (I don’t know whether this is constant, though. It may contain per device data like MAC addresses or some artifacts from flashing. According to the web interface, the software version of the camera is „V0.1.2.30“)

As said, the Linux image is not a plain zImage, but has a 256 byte header in front. The extracted image should start with the string „MGZ“. At byte 16, there should be the string „mbootpImage“. The start of the actual zImage at 0x100 looks like this:

00000100: 00 00 a0 e1 00 00 a0 e1 00 00 a0 e1 00 00 a0 e1

Booting the Original Kernel via U-Boot

The bootcmd in U-Boot’s default environment does not work (it assumes a different location for the Linux kernel in the flash. Perhaps WansView changed the layout without adapting U-Boot.)

As explained above, the zImage starts at 0xd0100, thus we need to use the following instead on the U-Boot console:

=> sf probe 0:0;sf read 0x4000000 0xd0100 0x800000;go 0x4000000

The camera should start up as usual after this command.

Important: Do not try to load (via tftp) and boot a kernel for another GM8126 platform (unless you know exactly what you are doing). Since it may contain an initial ramdisk as well, it may try to mount a JFFS2 user file system using a different MTD layout. This may result in data corruption and a system that does not boot anymore.

Now we can boot the kernel via U-Boot, but due to the, again, very peculiar way of booting the kernel, we can’t change the kernel command line. Still no shell…

Make an uImage

U-Boot supports kernel command line parameters when booting an uImage using the bootm command (the kernel command line is taken from the bootargs environment variable).

Thus, let’s make an uImage out of the linux kernel image extracted from our backup (you need to have U-Boot tools installed for this). The entry point will be 0x4000000. To account for the header, the load address is set to 0x4000000-0x100:

# mkimage -A arm -O linux -T kernel -C none -a 0x3ffff00 -e 0x4000000 -n "Linux kernel" -d Wansview_NCM625W_flash_Linux.img uImage

U-Boot supports the Ethernet port. This will allow to load the image quickly (in contrast to transfer it using the serial port). Make the uImage file available on an tftp server (I used dnsmasq for this).

Booting the uImage with a Kernel Command Line in U-Boot

First, boot into the U-Boot prompt as described above. Set the environment variables for the kernel parameters and the IP addresses to use for the tftp transfer. The kernel command is the one from the kernel boot log above with an additional rdinit=/bin/sh. We need to use rdinit instead of init here, because the boot process stays in the ramdisk environment.

=> setenv bootargs mem=128M console=uart,shift,2,io,0xF9830000,38400 rdinit=/bin/sh
=> setenv ipaddr 192.168.1.74
=> setenv serverip 192.168.1.23

Load the uImage:

=> tftp 0x5000000 uImage
Using eth0 device
TFTP from server 192.168.1.23; our IP address is 192.168.1.74
Filename 'uImage'.
Load address: 0x5000000
Loading: t RD_REQ, file: uImage
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
##############################################
done
Bytes transferred = 5435456 (52f040 hex)

And start it:

=> bootm 0x5000000
## Booting kernel from Legacy Image at 05000000 ...
Image Name: Linux kernel
Created: 2015-04-02 20:11:29 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 5435392 Bytes = 5.2 MB
Load Address: 03ffff00
Entry Point: 04000000
Verifying Checksum ... OK
Loading Kernel Image ... OK
OK

Starting kernel ...

Uncompressing Linux........................................................................................................................................................................................................................ done, booting the kernel.
Linux version 2.6.28 (root@gm8126.localdomain) (gcc version 4.4.0 (Faraday C/C++ Compiler Release 20100325) ) #175 PREEMPT Wed Jul 24 10:05:05 HKT 2013
CPU: FA626TE [66056261] revision 1 (ARMv5TE), cr=0000797f
CPU: VIPT aliasing data cache, VIPT aliasing instruction cache
...
Freeing init memory: 2984K
/bin/sh: can't access tty; job control turned off
/ # usb 1-1: new high speed USB device using FOTG2XX_DRV and address 2
port status 10009
2nd port status 10009

/ # usb 1-1: configuration #1 chosen from 1 choice
ls
bin etc init mnt root sys usr
dev home lib proc sbin tmp var
/ # ls -l
drwxr-xr-x 2 root root 0 Jul 24 2013 bin
drwxrwxrwx 3 root root 0 Jul 24 2013 dev
drwxrwxrwx 4 root root 0 Jul 24 2013 etc
drwxrwxrwx 2 root root 0 Jul 24 2013 home
-rwxrw-rw- 1 root root 278 Apr 24 2013 init
drwxrwxrwx 3 root root 0 Jul 24 2013 lib
drwxrwxrwx 4 root root 0 Jul 24 2013 mnt
drwxrwxrwx 2 root root 0 Jul 24 2013 proc
drwxrwxrwx 2 root root 0 Jul 24 2013 root
drwxr-xr-x 2 root root 0 Jul 24 2013 sbin
drwxrwxrwx 2 root root 0 Jul 24 2013 sys
drwxrwxrwx 2 root root 0 Jul 24 2013 tmp
drwxr-xr-x 4 root root 0 Jul 24 2013 usr
drwxrwxrwx 3 root root 0 Jul 24 2013 var

Voilà, feel free to look around…

8 Gedanken zu „Serial Console on WansView M-Series NCM625W Camera

  1. Hallo
    Ich habe eine Wansview NCM629W und habe den Flash komplett gelöscht. Komme nur noch ins u-boot.
    Da für die NCM Serie eine einheitlich Firmware angeboten wird, habe ich die Hoffnung, mit einem Flash dump Deiner Kamera (soweit noch vorhanden), meine Kamera wieder zu beleben. Hast Du noch ein Flash Image. Es scheint so, als hätte ich den Kernel (linux section) gelöscht, aber auch die user section. Wenn Du noch die Dumps hast, währest Du so nett, sie mir zu schicken.
    Vielen Dank
    René

  2. Hi Simon,

    I am trying to fix the firmware of my camera NCM625W. Your article „Serial Console on WansView M-Series NCM625W Camera“ was super helpful, but I still can’t find a proper kernel image. Would you mind sending over Wansview_NCM625W_flash.img you mentioned in your article?

    Look forward to your reply. Thanks again for all your work!

    Andrey

    1. Sorry, I understand your situation, but I can’t do that.

      For one, the camera was already configured when I did the dump. Thus, the dump contains my WiFi key somewhere, for example. Additionally, there may be proprietary software in this dump. While I think it is ok to make a backup copy for myself under my legislation, I don’t have the right to distribute the copy in any way.

      As much as I would like to help, I simply can’t provide my dump.

  3. Hi Simon,
    thanks for this great guide.
    I tried the same thing on an Apexis H803.
    The partition layout is a bit different:
    0x000d6000-0x009ff000 : „Linux Section“
    0x00a00000-0x01000000 : „User Section“
    0x00001000-0x00006000 : „Loader Section“
    0x00006000-0x000a6000 : „BurnIn Section“
    0x000a6000-0x000d4000 : „UBoot Section“
    0x000d4000-0x000d6000 : „CFG Section“

    I calculated these dd parameters:
    dd if=complete-image.img of=apexis-linux.img bs=1 skip=876544 count=9605120
    Then I made the uImage with the command from your guide.
    Info: The default bootcmd from the H803 is:
    bootcmd=sf probe 0:0;sf read 0x4000000 0xd6100 0x800000;go 0x4000000

    I did the setenv things and copied the uImage to 0x5000000 with tftp.
    But when I tried to start the image, it hangs after „Starting kernel:
    Bytes transferred = 9605184 (929040 hex)
    => bootm 0x5000000

    ## Booting kernel from Legacy Image at 05000000 …
    Image Name: Linux kernel
    Created: 2016-11-20 19:42:55 UTC
    Image Type: ARM Linux Kernel Image (uncompressed)
    Data Size: 9605120 Bytes = 9.2 MB
    Load Address: 03ffff00
    Entry Point: 04000000
    Verifying Checksum … OK
    Loading Kernel Image … OK
    OK

    Starting kernel …

    The cursor stopped blinking in GtkTerm and I disconnected power from the camera.
    How long should I wait or did something went wrong?
    It starts normal when I reconnect the power cable.
    Can you help me?

    Dominik
    (from Germany)

    1. I have root access now!
      (But I didn’t manage to do it in u-Boot…)

      I found out that you just have to press Ctrl+C a few times during the startup of the camera. (I think two times per second is enough.)
      You can then get the credentials for root with:
      cat /etc/passwd
      cat /etc/shadow
      Copy the lines with „root“ of both files to files called apexis-passwd and apexis-shadow on your linux machine.
      Install „john“ (John the Ripper password cracker) on your machine.
      Combine the two files from above with the command:
      unshadow apexis-passwd apexis-shadow > apexis-root
      That creates a new file called apexis-root which contains the hashed password.
      Use john to reveal the password:
      john apexis-root
      It can take up to 30 minutes until you see the password.
      (4 lower case letters in my case, maybe more on other models)
      You can then login to your Apexis H803 IP camera using telnet with root and the password.
      After a successful login It shows a screen with a „faraday“ logo:
      A320D login: root
      Password:
      login: can’t chdir to home directory ‚/root‘
      … faraday logo an some text …
      [root@A320D]#

      You now have root access using telnet.
      Maybe it works on other IP cams too.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.