How to write this without including enough detail that it doesn't impinge on people's short attention spans - when I'm a person temperamentally inclined to do the detail?
Maybe try to summarise, and invite questions, and add more later.
There is a caveat emptor on the Huisun firmware update process, a bit like Hikvision's, where not enough checking is done to guard against bricking your camera if you inadvertently try the wrong version.
So, a few days back out of the blue I got a PM from @pozzello asking if I wanted to have a go at fixing a wrong-firmware-bricked Mini PTZ V2.
I can't think why he thought I'd be a candidate for such a task but I was intrigued enough to say yes. So he shipped the camera to me.
It arrived today, undamaged. Having a bit of time this evening, and half a bottle of vino rosso to finish, I decided to start looking at it.
The first check was to power it up and see what it did on the network. Nothing at all. The link light came on, but no network packets and no motor or other activity.
OK, so off with the case to take a look for the serial console connections that hopefully will yield something useful.
It's bound to have these, and they are going to be pretty accessible, probably used in manufacturing and certainly in fault-finding.
A look around and a couple of easily accessible candidates are seen. Exciting! Check out the pads marked TX1 and RX1 on this pic:
Sure enough - connecting to a USB to TTL serial adaptor and powering on gives this:
Where there is life, there is hope. And there is definitely life. Until it starts to load up the libs or apps and falls over.
OK, so what next?
It's an Amboot, so let's try the bootloader. Not as functional as U-boot, but should still have something useful:
OK - what next? The
"usbdl fwprog (Download firware and program it into flash)"
looks interesting - but before making any changes it's a good idea to extract everything that might be useful.
"spinor dump 0 16711680" can be used to dump the entire existing flash memory, and convert it into binary for disassembling.
That works OK - but a quick look suggests that the bootloader firmware update may be designed to use a special version of the firmware, as opposed to the zipped 'package.bin' firmware that Huisun distribute for the web GUI updater. That zip password is strong - I have not cracked it yet. But it will be in the firmware ...
How am I doing for boring everyone?
Maybe that's enough for now, time to sum up.
From what I can see from this single example, a Mini PTZ that's been 'bricked' by an incorrect firmware update should be able to be recovered, given access to the serial console. And suitable firmware files.
Whether it needs Huisun to supply a different version of firmware, or whether a working camera can simply be cloned remains to be seen.
I expect that changing the kernel commandline boot params should yield Linux root access, giving a lot of flexibility.
But that's for another day.
Comments welcome.
By the way - who all has a bricked Mini PTZ caused by a bad firmware update?
Maybe try to summarise, and invite questions, and add more later.
There is a caveat emptor on the Huisun firmware update process, a bit like Hikvision's, where not enough checking is done to guard against bricking your camera if you inadvertently try the wrong version.
So, a few days back out of the blue I got a PM from @pozzello asking if I wanted to have a go at fixing a wrong-firmware-bricked Mini PTZ V2.
I can't think why he thought I'd be a candidate for such a task but I was intrigued enough to say yes. So he shipped the camera to me.
It arrived today, undamaged. Having a bit of time this evening, and half a bottle of vino rosso to finish, I decided to start looking at it.
The first check was to power it up and see what it did on the network. Nothing at all. The link light came on, but no network packets and no motor or other activity.
OK, so off with the case to take a look for the serial console connections that hopefully will yield something useful.
It's bound to have these, and they are going to be pretty accessible, probably used in manufacturing and certainly in fault-finding.
A look around and a couple of easily accessible candidates are seen. Exciting! Check out the pads marked TX1 and RX1 on this pic:
Sure enough - connecting to a USB to TTL serial adaptor and powering on gives this:
Where there is life, there is hope. And there is definitely life. Until it starts to load up the libs or apps and falls over.
Code:
=~=~=~=~=~=~=~=~=~=~=~= PuTTY log 2016.07.16 17:38:06 =~=~=~=~=~=~=~=~=~=~=~=
#�##[4l
spinor flash ID is 0xC21820C2
###gpio init###
flspinor addr = 0x00200000, size = 0x00DF0000
flspinor addr = 0x00050000, size = 0x001B0000
flspinor addr = 0x00040000, size = 0x00010000
flspinor addr = 0x00010000, size = 0x00030000
flspinor addr = 0x00000000, size = 0x00010000
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Initializing cgroup subsys cpu
[ 0.000000] Linux version 3.10.73 (robot@dev-ubuntu-14) (gcc version 4.9.1 20140625 (prerelease) (crosstool-NG - Ambarella Linaro Multilib GCC [CortexA9 & ARMv6k] 2014.06) ) #6 PREEMPT Wed Nov 11 13:58:11 CST 2015
[ 0.000000] CPU: ARMv7 Processor [414fc091] revision 1 (ARMv7), cr=10c53c7d
[ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[ 0.000000] Machine: Ambarella S2L (Flattened Device Tree), model: Ambarella S2LM Kiwi Board
[ 0.000000] Memory policy: ECC disabled, Data cache writeback
[ 0.000000] Ambarella: AHB = 0xe0000000[0xe0000000],0x01000000 0
[ 0.000000] Ambarella: APB = 0xe8000000[0xe8000000],0x01000000 0
[ 0.000000] Ambarella: PPM = 0x00000000[0xdfe00000],0x00200000 9
[ 0.000000] Ambarella: AXI = 0xf0000000[0xf0000000],0x00030000 0
[ 0.000000] Ambarella: DRAMC = 0xdffe0000[0xef000000],0x00020000 0
[ 0.000000] Ambarella: DBGBUS = 0xec000000[0xec000000],0x00200000 0
[ 0.000000] Ambarella: DBGFMEM = 0xee000000[0xee000000],0x01000000 0
[ 0.000000] Ambarella: IAVMEM = 0x08000000[ ],0x08000000
[ 0.000000] CPU: All CPU(s) started in SVC mode.
[ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 32004
[ 0.000000] Kernel command line: console=ttyS0 root=/dev/mtdblock4 rw rootfstype=jffs2 init=/linuxrc
[ 0.000000] PID hash table entries: 512 (order: -1, 2048 bytes)
[ 0.000000] Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
[ 0.000000] Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
[ 0.000000] Memory: 126MB = 126MB total
[ 0.000000] Memory: 123484k/123484k available, 5540k reserved, 0K highmem
[ 0.000000] Virtual kernel memory layout:
[ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB)
[ 0.000000] fixmap : 0xfff00000 - 0xfffe0000 ( 896 kB)
[ 0.000000] vmalloc : 0x88000000 - 0xff000000 (1904 MB)
[ 0.000000] lowmem : 0x80000000 - 0x87e00000 ( 126 MB)
[ 0.000000] modules : 0x7f000000 - 0x80000000 ( 16 MB)
[ 0.000000] .text : 0x80008000 - 0x803cb20c (3853 kB)
[ 0.000000] .init : 0x803cc000 - 0x803ed94c ( 135 kB)
[ 0.000000] .data : 0x803ee000 - 0x80419688 ( 174 kB)
[ 0.000000] .bss : 0x80419688 - 0x80439434 ( 128 kB)
[ 0.000000] NR_IRQS:240
[ 0.000000] sched_clock: 32 bits at 54MHz, resolution 18ns, wraps every 79536ms
[ 0.000000] Console: colour dummy device 80x30
[ 0.000000] console [ttyS0] enabled
[ 0.232357] Calibrating delay loop... 597.60 BogoMIPS (lpj=2988032)
[ 0.292597] pid_max: default: 32768 minimum: 301
[ 0.297301] Mount-cache hash table entries: 512
[ 0.304425] CPU: Testing write buffer coherency: ok
[ 0.309585] Setting up static identity map for 0x802c66c0 - 0x802c6718
[ 0.318509] devtmpfs: initialized
[ 0.323246] pinctrl core: initialized pinctrl subsystem
[ 0.328706] NET: Registered protocol family 16
[ 0.333929] DMA: preallocated 256 KiB pool for atomic coherent allocations
[ 0.341348] L310 cache controller enabled
[ 0.345349] l2x0: 8 ways, CACHE_ID 0x410000c8, AUX_CTRL 0x32020000, Cache size: 131072 B
[ 0.355105] ambarella-pinctrl e8009000.pinctrl: Ambarella pinctrl driver registered
[ 0.363177] ambarella-gpio gpio.0: Ambarella GPIO driver registered
[ 0.373598] bio: create slab <bio-0> at 0
[ 0.378731] ambarella-dma e0005000.dma: Ambarella DMA Engine
[ 0.384908] ambarella-spi e0020000.spi: master is unqueued, this is deprecated
[ 0.393015] ambarella-spi e0020000.spi: ambarella SPI Controller 0 created
[ 0.401576] ambarella-i2c e8003000.i2c: Ambarella I2C adapter[0] probed!
[ 1.899962] ambarella-i2c e8007000.i2c: No ACK from address 0xe8, 0:0!
[ 1.906479] pca953x 2-0074: failed reading register
[ 1.911365] pca953x: probe of 2-0074 failed with error -16
[ 1.916843] ambarella-i2c e8007000.i2c: Ambarella I2C adapter[2] probed!
[ 1.924253] Switching to clocksource ambarella-cs-timer
[ 1.936662] ambarella-sd e0002000.sdmmc0: Slot0 use bounce buffer[0x87720000<->0x07920000]
[ 1.944960] ambarella-sd e0002000.sdmmc0: Slot0 req_size=0x00020000, segs=32, seg_size=0x00020000
[ 1.953828] ambarella-sd e0002000.sdmmc0: Slot0 use ADMA
[ 2.029583] ambarella-sd e0002000.sdmmc0: 1 slots @ 50000000Hz
[ 2.035567] NET: Registered protocol family 2
[ 2.040909] TCP established hash table entries: 1024 (order: 1, 8192 bytes)
[ 2.047876] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
[ 2.055352] TCP: Hash tables configured (established 1024 bind 1024)
[ 2.061772] TCP: reno registered
[ 2.064991] UDP hash table entries: 256 (order: 0, 4096 bytes)
[ 2.070834] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[ 2.077280] NET: Registered protocol family 1
[ 2.081956] RPC: Registered named UNIX socket transport module.
[ 2.087858] RPC: Registered udp transport module.
[ 2.092593] RPC: Registered tcp transport module.
[ 2.097276] RPC: Registered tcp NFSv4.1 backchannel transport module.
[ 2.104093] ambarella-adc e801d000.adc: Ambarella ADC driver init
[ 2.111849] jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
[ 2.118068] msgmni has been set to 241
[ 2.123140] NET: Registered protocol family 38
[ 2.127659] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253)
[ 2.135204] io scheduler noop registered
[ 2.139111] io scheduler deadline registered
[ 2.143426] io scheduler cfq registered (default)
[ 2.148453] e8005000.uart: ttyS0 at MMIO 0xe8005000 (irq = 9) is a ambuart
[ 2.156325] brd: module loaded
[ 2.162190] loop: module loaded
[ 2.165576] Ambarella read-only mtdblock
[ 2.169760] 5 ofpart partitions found on MTD device amba_spinor
[ 2.175659] Creating 5 MTD partitions on "amba_spinor":
[ 2.180896] 0x000000000000-0x000000010000 : "bst"
[ 2.186358] 0x000000010000-0x000000040000 : "bld"
[ 2.191795] 0x000000040000-0x000000050000 : "ptb"
[ 2.197172] 0x000000050000-0x000000200000 : "pri"
[ 2.202598] 0x000000200000-0x000000ff0000 : "lnx"
[ 2.207984] SPI NOR Controller probed
[ 2.269522] libphy: Ambarella MII Bus: probed
[ 2.273876] mdio_bus e000e000.etherne: /ahb@e0000000/ethernet@e000e000/phy@0 has invalid PHY address
[ 2.283008] mdio_bus e000e000.etherne: scan phy phy at address 0
[ 2.289562] mdio_bus e000e000.etherne: registered phy phy at address 0
[ 2.296079] ambarella-eth e000e000.ethernet: Ethernet PHY[0]: 0x00221513!
[ 2.303388] ambarella-eth e000e000.ethernet: MAC Address[f6:ab:71:89:6b:10].
[ 2.310882] ambarella-rtc e8015000.rtc: rtc core: registered rtc-ambarella as rtc0
[ 2.318576] i2c /dev entries driver
[ 2.322711] TCP: cubic registered
[ 2.326011] Initializing XFRM netlink socket
[ 2.330317] NET: Registered protocol family 17
[ 2.334818] VFP support v0.3: implementor 41 architecture 3 part 30 variant 9 rev 4
[ 2.342475] ThumbEE CPU extension supported.
[ 2.347520] ambarella-rtc e8015000.rtc: setting system clock to 2016-07-16 16:40:04 UTC (1468687204)
[ 3.615215] VFS: Mounted root (jffs2 filesystem) on device 31:4.
[ 3.621473] devtmpfs: mounted
[ 3.624624] Freeing unused kernel memory: 132K (803cc000 - 803ed000)
/etc/init.d/S12udev: /etc/ambarella.conf: line 1: export: not found
Populating s2lm_kiwi using udev: [ 5.210418] systemd-udevd[179]: starting version 215
Done
��^H^AQ^B^@\��^H^AQ^B^@\��^H^AQ^B^@\��^H^AQ^B^@\��^H^AQ^B^@\��^H^AQ^B^@\
OK, so what next?
It's an Amboot, so let's try the bootloader. Not as functional as U-boot, but should still have something useful:
Code:
=~=~=~=~=~=~=~=~=~=~=~= PuTTY log 2016.07.16 18:59:38 =~=~=~=~=~=~=~=~=~=~=~=
##[4l
spinor flash ID is 0xC21820C2
___ ___ _________ _
/ _ \ | \/ || ___ \ | |
/ /_\ \| . . || |_/ / ___ ___ | |_
| _ || |\/| || ___ \ / _ \ / _ \ | __|
| | | || | | || |_/ /| (_) || (_) || |_
\_| |_/\_| |_/\____/ \___/ \___/ \__|
----------------------------------------------------------
Amboot(R) Ambarella(R) Copyright (C) 2004-2014
Boot From: SPI NOR
SYS_CONFIG: 0x3000404B POC: 101
Cortex freq: 600000000
iDSP freq: 216000000
Dram freq: 528000000
Core freq: 216000000
AHB freq: 108000000
APB freq: 54000000
UART freq: 24000000
SD freq: 50000000
SDIO freq: 50000000
SDXC freq: 60000000
amboot>
amboot>
amboot>
amboot>
amboot>
amboot>
amboot>
amboot>
amboot>
amboot>
amboot>
amboot>
amboot>
amboot>
amboot>
amboot> help
The following commands are supported:
r32 w32 boot erase
help reboot setenv show
memtest fs fdt usbdl
gpio spinor tftp ping
sd
Use 'help' to get help on a specific command
amboot> help r32
Help for 'r32':
r32 [address]
Read a 32-bit data from an address
amboot> help w32
Help for 'w32':
w32 [address] [value]
Write a 32-bit data into an address
amboot> help boot
Help for 'boot':
boot <param>
Load images from flash to memory and boot
amboot> help setenv
Help for 'setenv':
setenv [param] [val]
sn - Serial number
auto_boot - Automatic boot
splash_id - splash logo id
[eth|wifi|usb] [0|1] [mac|ip|mask|gw]
- [device] [instances] [mac addr|IP addr|network mask|gateway]
auto_dl - Automatically try to boot over network
tftpd - TFTP server address
pri_addr - RTOS download address
pri_file - RTOS file name
pri_comp - RTOS compressed?
rmd_addr - Ramdisk download address
rmd_file - Ramdisk file name
rmd_comp - Ramdisk compressed?
dsp_addr - DSP download address
dsp_file - DSP file name
dsp_comp - DSP compressed?
amboot> help show
Help for 'show':
show ptb - flash partition table
show poc - power on config
show netboot - netboot parameters
show wifi - show wifi infomations
show usb_eth - show usb ethernet infomations
Display various system properties
amboot> show ptb
bst: 0x5DD75A8D 1.3 (2015/11/11) 0x00000000 0x00000001 (2048)
bld: 0xCC5CD51D 1.3 (2015/11/11) 0x00000000 0x00000000 (153144)
pri: 0x0CAB7C00 0.1 (2015/11/11) 0x00208000 0x00000000 (1587400)
lnx: 0x00A6FF5D 0.1 (2015/11/11) 0x00000000 0x00000001 (12910592)
S/N:
usbdl_mode: 0
auto_boot: 1
amboot> show poc
Boot From: SPI NOR
amboot> show netboot
eth0_mac: 00:00:00:00:00:00
eth0_ip: 0.0.0.0
eth0_mask: 0.0.0.0
eth0_gw: 0.0.0.0
eth1_mac: 00:00:00:00:00:00
eth1_ip: 0.0.0.0
eth1_mask: 0.0.0.0
eth1_gw: 0.0.0.0
auto_dl: 0
tftpd: 0.0.0.0
pri_addr: 0x00000000
pri_file:
pri_comp: 0
rmd_addr: 0x00000000
rmd_file:
rmd_comp: 0
dsp_addr: 0x00000000
dsp_file:
dsp_comp: 0
amboot> help fs
Help for 'fs':
fs ls
fs info
fs cd [dir]
fs read [file] [addr] [exec]
fs write [file] [addr] [size]
amboot> fs info
failed Read at 0 sector
DBR[sector]: 0x00000000
Total[sector]: 0x00000000
Data[sector]: 0x00000000
Fat addr[sector]: 0x00000000
Fat length[sector]: 0x00000000
Sector[byte]: 0x00000000
Cluster[sector]: 0x00000000
amboot> fs ls
failed Read at 0 sector
amboot> help fs info
Help for 'fs':
fs ls
fs info
fs cd [dir]
fs read [file] [addr] [exec]
fs write [file] [addr] [size]
amboot> help fdt
Help for 'fdt':
fdt utility commands
fdt header - show fdt header
fdt cmdline [cmdline] - set cmdline
fdt getnode [path] - get node path
fdt getprop [path] - get node path and property
fdt setprop [path] [prop] [TYPE] [value] - set property value
e.g.:
fdt setprop [path] [prop] bool 0|1
fdt setprop [path] [prop] hex 0x12345678
fdt setprop [path] [prop] byte 02 11 22 0xab
fdt setprop [path] [prop] str string
amboot> fdt header
magic: 0xD00DFEED
totalsize: 13709
off_dt_struct: 0x56
off_dt_strings: 0x11452
off_mem_rsvmap: 0x40
version: 17
last_comp_version: 16
size_dt_struct: 0x11396
number mem_rsv: 0x0
amboot> help gpio
Help for 'gpio':
gpio [set|clr|get|pup|pdown|poff] id - Basic GPIO function
gpio [hw] id func - Set HW mode
Test GPIO.
amboot> help tftp
Help for 'tftp':
tftp boot [cmdline]
tftp program [file_name] [addr] [exec]
Load images from TFTP server
amboot>
amboot> ping 192.168.1.21
link down ...
amboot> tftp
Help for 'tftp':
tftp boot [cmdline]
tftp program [file_name] [addr] [exec]
Load images from TFTP server
amboot> help usbdl
Help for 'usbdl':
The command execute actions over USB
usbdl (Perform actions controlled by Host)
usbdl ADDRESS exec (Download image to target address and execute it)
usbdl fwprog (Download firware and program it into flash)
usbdl ext (Turn on USB external clock)
usbdl kernel (Download kernel files and execute it)
usbdl upload (Upload data to Host by host's request)
usbdl test [download | pll] (Test download or dll power-on/off)
amboot>
OK - what next? The
"usbdl fwprog (Download firware and program it into flash)"
looks interesting - but before making any changes it's a good idea to extract everything that might be useful.
"spinor dump 0 16711680" can be used to dump the entire existing flash memory, and convert it into binary for disassembling.
That works OK - but a quick look suggests that the bootloader firmware update may be designed to use a special version of the firmware, as opposed to the zipped 'package.bin' firmware that Huisun distribute for the web GUI updater. That zip password is strong - I have not cracked it yet. But it will be in the firmware ...
Code:
=============================
USB download
Version 0.1
Built @
Nov 11 2015
13:58:18
Download 1 firmware programming file
firmware program is loaded
Download 4 kernel files
Prkernel is loaded
code is loaded
memd is loaded
default_bin is loaded
How am I doing for boring everyone?
Maybe that's enough for now, time to sum up.
From what I can see from this single example, a Mini PTZ that's been 'bricked' by an incorrect firmware update should be able to be recovered, given access to the serial console. And suitable firmware files.
Whether it needs Huisun to supply a different version of firmware, or whether a working camera can simply be cloned remains to be seen.
I expect that changing the kernel commandline boot params should yield Linux root access, giving a lot of flexibility.
But that's for another day.
Comments welcome.
By the way - who all has a bricked Mini PTZ caused by a bad firmware update?
Last edited by a moderator: