Well, I decided to see what comments I would attract with another 'how to unbrick' on the Huisun topic.
For various forum members I've fixed 6 or 7 'bricked' Huisun Mini PTZ V2 cameras, some hands-on, some via back and forth instructions.
And 5 of those have had the same fault - part of the contents of the flash segment known as mtdblock2 have been erased.
This is a vital part of the flash, as it holds the flash partition table ptb, the 'dtb' data structure which defines to the kernel how to address the hardware, and less importantly the Amboot environment variables, and other stuff.
When it's gone, the camera just can't boot. But the bootloader Amboot runs, and provides the way in to fix up problems.
But before I go on to the boring technical stuff, I'd like to mention that it was the great generosity of forum member @pozzello who last year in a friendly gesture sent me his 'bricked' Mini PTZ V2 to investigate, maybe fix, analyse, and post about. Which I did. And this as a spinoff has benefited other forum members who have had problems with these very functional but troublesome cameras.
Unfortunately, dealing with a low-level problem where only the bootloader is operating requires making a connection to the 'serial console' for communications. It's fiddly if you've not done it before. Not as easy as Hikvision where there is a socket to plug in to. And I've also done quite a few of those recently, experimenting and unbricking has been a theme all round.
Here is a summary transcript of the most recent board I fixed up, which is now heading home again across 'the pond'.
The first action was to interrupt Amboot and dive straight in with a 'show ptb' command.
Normally this would list the active partitions, but in this case, nothing, blank.
Some netboot environment variables still existed, so mtdblock2 wasn't entirely trashed. But trashed enough to not allow bootup.
But how to replace the missing 'dtb' hardware definition data structure? It's not too difficult, with a copy from a working camera.
I'd previously disassembled Amboot, and also studied the published source code, and noticed that it used a fixed location memory buffer to hold the contents of mtdblock2 as read from flash to support the various commands that list or change data in it.
And it didn't reload those contents after each command, so opening the possibility of modifying in-memory and hopefully writing it back.
There is too much detail (about 32KB) to realistically do this manually with memory modification commands, but usefully both the 'tftp' (over the LAN) and the 'fs read' (from an SD card) commands have the ability to load data into an arbitrary segment of memory.
The 'tftp' command doesn't work on all versions of the bootloader though, as it needs to have done a 'GPIO init' to activate the ethernet interface before the command prompt is presented. Not all do this.
But if the board has a built-in or add-in SD card the 'fs read' (file system read) command can be used, though the 32KB dtb data needs to be split into 2 16KB sections as 'fs read' is limited to 16KB chunks.
So here is how it's done. The commands overwritten by the progress bar below are:
fs read dtb_part1 0x3ac00 0
fs read dtb_part2 0x3ec00 0
Then comes the slightly sneaky bit.
How to get Amboot to write the modified data back to flash?
When an Amboot environment variable is modified, there is an implicit 'write to flash', and it writes the whole of the mtdblock2 data in the RAM buffer.
So a dummy 'setenv somevariable somevalue' command does the trick! Neat.
And that's it. The camera now boots up normally. None of the other flash segments was damaged.
It's strange that this appears to be a common cause of these cameras 'bricking', when it's not been the original PoE board problem.
Whether there is a hardware root cause, or a firmware bug is impossible to tell.
But I'd plump for the latter.
Thanks for reading this far!
I'd like to think this may be of interest, or maybe even of use, to other members.
Constructive comments welcome.
For various forum members I've fixed 6 or 7 'bricked' Huisun Mini PTZ V2 cameras, some hands-on, some via back and forth instructions.
And 5 of those have had the same fault - part of the contents of the flash segment known as mtdblock2 have been erased.
This is a vital part of the flash, as it holds the flash partition table ptb, the 'dtb' data structure which defines to the kernel how to address the hardware, and less importantly the Amboot environment variables, and other stuff.
When it's gone, the camera just can't boot. But the bootloader Amboot runs, and provides the way in to fix up problems.
But before I go on to the boring technical stuff, I'd like to mention that it was the great generosity of forum member @pozzello who last year in a friendly gesture sent me his 'bricked' Mini PTZ V2 to investigate, maybe fix, analyse, and post about. Which I did. And this as a spinoff has benefited other forum members who have had problems with these very functional but troublesome cameras.
Unfortunately, dealing with a low-level problem where only the bootloader is operating requires making a connection to the 'serial console' for communications. It's fiddly if you've not done it before. Not as easy as Hikvision where there is a socket to plug in to. And I've also done quite a few of those recently, experimenting and unbricking has been a theme all round.
Here is a summary transcript of the most recent board I fixed up, which is now heading home again across 'the pond'.
The first action was to interrupt Amboot and dive straight in with a 'show ptb' command.
Normally this would list the active partitions, but in this case, nothing, blank.
Some netboot environment variables still existed, so mtdblock2 wasn't entirely trashed. But trashed enough to not allow bootup.
Code:
amboot>
amboot> show ptb
S/N:
usbdl_mode: 0
auto_boot: 1
amboot> show netboot
eth0_mac: 11:22:33:01:02:03
eth0_ip: 192.168.0.65
eth0_mask: 255.255.255.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: 1
tftpd: 192.168.0.103
pri_addr: 0x00208000
pri_file: hs_mtdblock3
pri_comp: 0
rmd_addr: 0x00800000
rmd_file: my_initrd.gz
rmd_comp: 0
dsp_addr: 0x00000000
dsp_file:
dsp_comp: 0
amboot> show poc
Boot From: SPI NOR
I'd previously disassembled Amboot, and also studied the published source code, and noticed that it used a fixed location memory buffer to hold the contents of mtdblock2 as read from flash to support the various commands that list or change data in it.
And it didn't reload those contents after each command, so opening the possibility of modifying in-memory and hopefully writing it back.
There is too much detail (about 32KB) to realistically do this manually with memory modification commands, but usefully both the 'tftp' (over the LAN) and the 'fs read' (from an SD card) commands have the ability to load data into an arbitrary segment of memory.
The 'tftp' command doesn't work on all versions of the bootloader though, as it needs to have done a 'GPIO init' to activate the ethernet interface before the command prompt is presented. Not all do this.
But if the board has a built-in or add-in SD card the 'fs read' (file system read) command can be used, though the 32KB dtb data needs to be split into 2 16KB sections as 'fs read' is limited to 16KB chunks.
So here is how it's done. The commands overwritten by the progress bar below are:
fs read dtb_part1 0x3ac00 0
fs read dtb_part2 0x3ec00 0
Code:
amboot> sd init 0
running SD test ...
press any key to terminate!
total_secs: 60751872
amboot> fs ls
dtb_part1
dtb_part2
dtb
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 read dtb_part1[====================================================================================================>]%100
[00004000]16384 bytes read success ...
amboot> fs read dtb_part2[====================================================================================================>]%100
[00004000]16384 bytes read success ...
How to get Amboot to write the modified data back to flash?
When an Amboot environment variable is modified, there is an implicit 'write to flash', and it writes the whole of the mtdblock2 data in the RAM buffer.
So a dummy 'setenv somevariable somevalue' command does the trick! Neat.
And that's it. The camera now boots up normally. None of the other flash segments was damaged.
It's strange that this appears to be a common cause of these cameras 'bricking', when it's not been the original PoE board problem.
Whether there is a hardware root cause, or a firmware bug is impossible to tell.
But I'd plump for the latter.
Thanks for reading this far!
I'd like to think this may be of interest, or maybe even of use, to other members.
Constructive comments welcome.
Code:
amboot> setenv dsp_file none
amboot> boot
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)
loading pri to 0x00208000
rmd image absent... skipping
Jumping to 0x00208000 ...
cpux_jump: 0x00000000
initrd2_start: 0x00000000 initrd2_size: 0x00000000
kernelp: 0x00200000 kernels: 0x07E00000
idspp: 0x08000000 idsps: 0x08000000
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.232349] Calibrating delay loop... 597.60 BogoMIPS (lpj=2988032)