Skip to content

NBD8032 Digital Video Recorder

J. Neuschäfer edited this page Mar 7, 2026 · 2 revisions
photo of the PCB

NBD8032RA is a digital video recorder (DVR) board.

Ports

  • 12V DC input
  • 2x USB
  • Ethernet
  • HDMI out
  • VGA out
  • headphone jack
  • 2x SATA

Chips

  • Novatek SoC
  • 1 GiB RAM

UART

CN1 carries the UART RX/TX signals:

RX   TX   GND
[1]  (2)  (3)
Boot log
NPD>T
UNZOK!PCK[120]

DRAM1_DDR3_2133_32B ini_ver: 0x00220206

ETH trim = 000012F4

zq_trim[c], ldo_trim[10]

CPU1000 DONE

>RPA

ddr init done

HVYOK
UNZOK!
Loader Start ...
LD_VER 03.01.02

332_DRAM1_1066_4096Mb_4096Mb 07/08/2024 18:52:33

SPI NOR MID=00000020,TYPE=00000040,SIZE=00000018=>01000000
SPI NOR
E:blk_size 0x00010000
Dual_read 
E:tmp_size  0x00008000
inbuf 0x08010008
outbuf 0x08000000
in_len 0x00008000
tmp_addr 0x08000000
LdCtrl2 0x00000000
l_bl31
bl31_addr 0x01F00000
bl31_size 0x00007120
l_uboot
Dual_read 
uboot_addr 0x1E000000
Dual_read 
compress header 0x0000005D
inbuf 0x08000000
outbuf 0x1E000000
in_len 0x00040000
E:.E:.E:.E:.E:.E:.E:.E:.E:.E:.E:.E:.uboot_size 0x00069D18
core_cnt= 0x00000002
smp(bl31)
fdt 0x00100000
shm 0x00A00000
        core2_jump 0x00200000
  code2JumpCodelen 0x00000010
      core2_entry2 0x00010000
       core2_entry 0x00200010
 code2EntryCodelen 0x00000188
      core2_entry2 0x00010000
bl_core2_reset
$64wfi64core2_jump_program 0x00204DDF
64code2JumpCodelen 0x0000018C
warm reset core0
jump_entry 0x01F00000
ARC64warmrst*21#NOTICE:  BL31: v2.2(release):
NOTICE:  BL31: Built : 09:24:15, Apr 13 2023
NOTICE:  BL31: Found DTB
NOTICE:  TZASC config:
NOTICE:  
	0x00100000@0x01f00000 	(RW/N)	Ree
INFO:    ARM GICv2 driver initialized
INFO:    BL31: Platform setup done
INFO:    BL31: Initializing runtime services
INFO:    BL31: Preparing for EL3 exit to normal world
INFO:    Entry point address = 0x1e000000
INFO:    SPSR = 0x3c9


U-Boot 2019.04 (Jul 08 2024 - 18:52:49 +0800)

CPU:   Novatek NT @ 999 MHz
DRAM:  1 GiB
Relocation to 0x1fd9e000, Offset is 0x01d9e000 sp at 1fa7d180
otp_init[1.00.001]
120MHz
otp_timing_reg= 0xff6050
Read power trim = 0x00000000(NULL)
remap_data(duty) 9
Unknown command 'power_ctl' - try 'help'
Loading Environment from SPI Flash... NOR version: 1.0.20
nvt_spinor_reset: spi flash pinmux 0x11
331 SPI NAND TSLCH need >= 0x3, force config as 0x3
@nvt_spinor_probe_slave(): sr1: 0x0, sr2: 0x2
nor chip_sel = <0>
id =  0x20 0x40 0x18 0x20 0x00
eFlashType: 22.
Flash Name: XM_XM25QH128C{0x204018), 0x1000000.
@nvt_spinor_validate_params(), XmSpiNor_ProtMgr_probe(): OK.
STDR128FW with page size 256 Bytes, erase size 64 KiB, total 16 MiB
CONFIG_CLOSE_SPI_8PIN_4IO = n.
all blocks is unlocked.
SRx val: {[1, 0x0], [1, 0x2], [1, 0x20], [0, 0x0]}, SrVal: 0x700000000200200.
nvt spinor 1-bit mode @ 12000000 Hz, read_opcode: 0x3B, program_opcode: 0x2.
(331) single/dual mode: WP/HOLD force output high
OK
NOR version: 1.0.20
nvt_spinor_reset: spi flash pinmux 0x11
331 SPI NAND TSLCH need >= 0x3, force config as 0x3
@nvt_spinor_probe_slave(): sr1: 0x0, sr2: 0x2
nor chip_sel = <0>
id =  0x20 0x40 0x18 0x20 0x00
eFlashType: 22.
Flash Name: XM_XM25QH128C{0x204018), 0x1000000.
@nvt_spinor_validate_params(), XmSpiNor_ProtMgr_probe(): OK.
STDR128FW with page size 256 Bytes, erase size 64 KiB, total 16 MiB
CONFIG_CLOSE_SPI_8PIN_4IO = n.
all blocks is unlocked.
SRx val: {[1, 0x0], [1, 0x2], [1, 0x20], [0, 0x0]}, SrVal: 0x700000000200200.
nvt spinor 1-bit mode @ 12000000 Hz, read_opcode: 0x3B, program_opcode: 0x2.
(331) single/dual mode: WP/HOLD force output high
@do_spi_flash_probe() flash->erase_size: 65536, flash->sector_size: 65536
DTS find cpu freq clock 1150MHz
Set CPU clk 1150MHz
no apb clock dtsi
Net:   na51103_eth_initialize 1.0.0.4
na51103_eth_initialize: dtb node /eth0@2,f0440000 found
eqos_initialize 0x2f0440000
eth_parse_phy_intf: get IO MEM 0x2f0440000
DTS /eth0@2,f0440000 found
eth_parse_phy_intf: ref-clk-out 1
eth_parse_phy_intf: pinmux detect RGMII 0x701
val 4f51e91b
na51103_eth_initialize(2316) nodeoffset < 0
na51103_eth_initialize: path /eth1@2,f0450000 not found
eth0 [PRIME]
Warning: eth0 MAC addresses don't match:
Address in SROM is         00:0b:3f:00:00:01
Address in environment is  00:13:00:6c:c7:86

USB0:   0x2f0480000 ver 1.00.03
nvtim_init_usbhc_dm 573: controller 0
is found [1][5][USB] = 0x0009
        => 12K_resistor[0x0009]
USB EHCI 1.00
USB1:   0x2f0490000 ver 1.00.03
nvtim_init_usbhc_dm 547: controller 1
is found [1][5][USB] = 0x0009
        => 12K_resistor[0x0009]
no power gpio found
USB EHCI 1.00
scanning bus 0 for devices... 1 USB Device(s) found
scanning bus 1 for devices... 1 USB Device(s) found
0 Storage Device(s) found
i:0, No usb storage device found!
Hit X to stop autoboot:  0 
NOR version: 1.0.20
nvt_spinor_reset: spi flash pinmux 0x11
331 SPI NAND TSLCH need >= 0x3, force config as 0x3
@nvt_spinor_probe_slave(): sr1: 0x0, sr2: 0x2
nor chip_sel = <0>
id =  0x20 0x40 0x18 0x20 0x00
eFlashType: 22.
Flash Name: XM_XM25QH128C{0x204018), 0x1000000.
@nvt_spinor_validate_params(), XmSpiNor_ProtMgr_probe(): OK.
STDR128FW with page size 256 Bytes, erase size 64 KiB, total 16 MiB
CONFIG_CLOSE_SPI_8PIN_4IO = n.
all blocks is unlocked.
SRx val: {[1, 0x0], [1, 0x2], [1, 0x20], [0, 0x0]}, SrVal: 0x700000000200200.
nvt spinor 1-bit mode @ 12000000 Hz, read_opcode: 0x3B, program_opcode: 0x2.
(331) single/dual mode: WP/HOLD force output high
@do_spi_flash_probe() flash->erase_size: 65536, flash->sector_size: 65536
device 0 offset 0xf60000, size 0x20000
SF: 131072 bytes @ 0xf60000 Read: OK
at do_logoload pType: squashfs.
srcAddr 0x4000000, dstAddr 0x4500000
created_inode 0x1fabae60
find_squashfs_file: name h264dvr.jpg, start_block 0, offset 0, type 2
read inode: name h264dvr.jpg, sb 0, of 0, type 2
write_file: regular file, blocks 15
len 59577
### FS load complete: 59577 bytes loaded to 0x4500000
jpeg decoding ...
<<imgwidth=800, imgheight=600, linebytes=1600>>
decode success!!!!
decode jpeg success. 
lcd_frame_base = 0x3dd00000
flcd_main, output:4096 in_fmt:3
!lcd idx = 0
cg_write_reg: offset: 0x2f0020020, val: 0x101200
CG setting in LCD300 0
cg_write_reg: offset: 0x2f0020070, val: 0xd01103f
cg_write_reg: offset: 0x2f0020074, val: 0x3002480
cg_write_reg: offset: 0x2f0020094, val: 0xffffffff
cg_write_reg: offset: 0x2f0020098, val: 0xffffffff
cg_write_reg: offset: 0x2f00200e0, val: 0xffffffff
cg_write_reg: offset: 0x2f00200e0, val: 0xffffffff
LCD300:0 chooses PLL10:297000000 with div=4 (drv:1.1.8)
cg_write_reg: offset: 0x2f002004c, val: 0x301
cg_write_reg: offset: 0x2f0020020, val: 0x101200
LCD300_0 iobase=0x2f0800000
hdmi_if_init, apply new vid:4 setting. 
is found [1][3][HDMI]= 0x0000146e->0x000082eb
  	=> HDMI_resistor[0x000e]
  	=>  HDMI_LANE_VL[0x02a3]
hdmitx_init_phy, clock_rate:74250KHz
Init PHY END
Skip InitDDC
hdmi: audio stream enable. 
Bootlogo CVBS ON. 
cg_write_reg: offset: 0x2f0020070, val: 0xd09103f
cg_write_reg: offset: 0x2f0020094, val: 0xffffffff
cg_write_reg: offset: 0x2f00200e0, val: 0xffffffff
cg_write_reg: offset: 0x2f0020074, val: 0x3006480
cg_write_reg: offset: 0x2f0020098, val: 0xffffffff
LCD210: chooses PLL11:297000 with div=11
cg_write_reg: offset: 0x2f002004c, val: 0x30a
cg_write_reg: offset: 0x2f0020020, val: 0x101200
flcd_main, output:4096 in_fmt:3
!lcd idx = 0
LCD300_0 iobase=0x2f0800000
hdmi_if_init, apply new vid:4 setting. 
Bootlogo CVBS ON. 
cg_write_reg: offset: 0x2f0020070, val: 0xd09103f
cg_write_reg: offset: 0x2f0020094, val: 0xffffffff
cg_write_reg: offset: 0x2f00200e0, val: 0xffffffff
cg_write_reg: offset: 0x2f0020074, val: 0x3006480
cg_write_reg: offset: 0x2f0020098, val: 0xffffffff
LCD210: chooses PLL11:297000 with div=11
cg_write_reg: offset: 0x2f002004c, val: 0x30a
cg_write_reg: offset: 0x2f0020020, val: 0x101200
NOR version: 1.0.20
nvt_spinor_reset: spi flash pinmux 0x11
331 SPI NAND TSLCH need >= 0x3, force config as 0x3
@nvt_spinor_probe_slave(): sr1: 0x0, sr2: 0x2
nor chip_sel = <0>
id =  0x20 0x40 0x18 0x20 0x00
eFlashType: 22.
Flash Name: XM_XM25QH128C{0x204018), 0x1000000.
@nvt_spinor_validate_params(), XmSpiNor_ProtMgr_probe(): OK.
STDR128FW with page size 256 Bytes, erase size 64 KiB, total 16 MiB
CONFIG_CLOSE_SPI_8PIN_4IO = n.
all blocks is unlocked.
SRx val: {[1, 0x0], [1, 0x2], [1, 0x20], [0, 0x0]}, SrVal: 0x700000000200200.
nvt spinor 1-bit mode @ 12000000 Hz, read_opcode: 0x3B, program_opcode: 0x2.
(331) single/dual mode: WP/HOLD force output high
@do_spi_flash_probe() flash->erase_size: 65536, flash->sector_size: 65536
device 0 offset 0x60000, size 0x540000
SF: 5505024 bytes @ 0x60000 Read: OK
aSrcAddr[0]: 0x4000000, dstAddr: 0x1C700000, apFileName[0]: boot/uImage.
created_inode 0x1faa45d0
find_squashfs_file: name bin, start_block 0, offset 2396, type 1
find_squashfs_file: name boot, start_block 0, offset 2508, type 1
read inode: name boot, sb 0, of 2508, type 1
find_squashfs_file: name uImage, start_block 0, offset 2428, type 2
read inode: name uImage, sb 0, of 2428, type 2
write_file: regular file, blocks 12
len 2905789
### get_squashfs_file OK: loade 2905789 bytes to 0x1C700000
   Image Name:   Linux-4.19.148
   Image Type:   AArch64 Linux Kernel Image (uncompressed)
   Data Size:    2905725 Bytes = 2.8 MiB
   Load Address: 00080000
   Entry Point:  00080000
[33m Linux Image is at 1c700000, uboot fdt image is at 1fa8e4c0, loader tmp fdt address is at 100000 [0m
booti 1c700040 - 1fa8e4c0
kernel image compression type 3 size = 0x002c56bd address = 0x00000000
   Uncompressing Kernel Image
Boot Kernel from 0x1c700040 to 0x0
Copy Kernel to 0x0, size 0x7d7008
## Flattened Device Tree blob at 1fa8e4c0
   Booting using the fdt blob at 0x1fa8e4c0
   Loading Device Tree to 0000000015ded000, end 0000000015dffc47 ... OK
at xminfo_get() g_nXmBootSysIndex: 0, g_nXmRomfsIndex: 0.
at xminfo_get() pXmInfo: XmUart=1,XmAuto=1,Id=NULL,Mac0=[   redacted    ],Mac1=[    redacted   ],HwId=NULL,SysIndex=0,RomfsIndex=0,CorruptFlag=0x0,BackupCount=0.
osMemStart: 0x0, osMem: 0x15E00000.
@fdt_fixup_memory_banks(), ddrStart: 0x0, ddrAll: 0x40000000, hdalStart: 0x15E00000, hdalSize: 0x2A200000, size[0]: 0x15E00000.

Starting kernel ...

Interrupting the boot flow results in a password prompt.

Flash and firmware

Firmware is stored on a XM25QH128D flash (16 MiB). Reading the flash in-circuit (with CH341 + flashrom) seems to cause too much interference and the result is unusable.

Flash accesses can be traced somewhat non-intrusively with Glasgow's qspi-analyzer applet:

glasgow run qspi-analyzer -V3.3 spi2.bin   # --cs B0 --sck B1 --io B2,B3,B4,B5
glasgow tool memory-25x spi2.bin --data data

However, this doesn't work optimally. In practice, the board doesn't manage to boot all the way with a Glasgow attached for tracing.

U-Boot

U-Boot looks for a USB storage device, loads a file called auconfig.txt from it. Commands specified in the format cmd:<command> will be executed.

U-Boot environment
NID=0x0217
appCloudExAbility=w/tNDVnTeDs=
appSystemLanguage=English
appVideoStandard=NTSC
arch=arm64
baudrate=115200
board=nvt-na51103-a64
board_name=nvt-na51103-a64
bootargs=earlycon console=ttyS0,115200 init=linuxrc mem=${osmem} rootwait nprofile_irq_duration=on root=/dev/mtdblock2 rootfstype=squashfs mtdparts=spi_nor.0:0x20000(loader),0x40000(boot),0x540000(romfs),0x700000(usr),0x2C0000(custom),0x20000(logo),0x80000(mtd)
bootcmd=setenv setargs setenv bootargs ${bootargs};run setargs;run loadlogo;run loadromfs
bootdelay=0
cpu=armv8
da=mw.b 0x02000000 ff 0x1000000;tftpboot 0x02000000 u-boot.bin.img;sf probe 0;flwrite
dc=mw.b 0x02000000 ff 0x1000000;tftpboot 0x02000000 custom-x.squashfs.img;sf probe 0;flwrite
dd=mw.b 0x02000000 ff 0x1000000;tftpboot 0x02000000 mtd-x.jffs2.img;sf probe 0;flwrite
de=mw.b 0x02000000 ff 0x1000000;tftpboot 0x02000000 u-boot.env.img;sf probe 0;flwrite
df=mw.b 0x02000000 ff 100000;tftpboot 0x02000000 fdt.bin.img;flwrite
dl=mw.b 0x02000000 ff 0x1000000;tftpboot 0x02000000 logo-x.squashfs.img;sf probe 0;flwrite
dr=mw.b 0x02000000 ff 0x1000000;tftpboot 0x02000000 romfs-x.squashfs.img;sf probe 0;flwrite
du=mw.b 0x02000000 ff 0x1000000;tftpboot 0x02000000 user-x.squashfs.img;sf probe 0;flwrite
dw=mw.b 0x02000000 ff 0x1000000;tftpboot 0x02000000 web-x.squashfs.img;sf probe 0;flwrite
eth1addr=[   redacted    ]
ethact=eth0
ethaddr=[   redacted    ]
ethprime=eth0
fdt_high=0x04000000
fdtcontroladdr=1fa7d190
gatewayip=192.168.1.107
hostname=oaalnx
ipaddr=192.168.1.10
ld=mw.b 0x02000000 ff 100000;tftpboot 0x02000000 loader.bin.img;flwrite
loadlogo=sf probe 0;sf read 0x04000000 0xF60000 0x20000;logoload 0x04000000;decjpg 0;bootlogo
loadromfs=sf probe 0;sf read 0x04000000 0x60000 0x540000;squashfsload;nvt_boot
mtdids=nor0=spi_nor.0
mtdparts=mtdparts=spi_nor.0:0x20000@0x0(loader),0x40000@0x20000(boot),0x540000@0x60000(romfs),0x700000@0x5a0000(usr),0x2c0000@0xca0000(custom),0x20000@0xf60000(logo),0x80000@0xf80000(mtd)
netmask=255.255.255.0
osmem=0x15E00000
serverip=192.168.1.1
soc=nvt-na51103_a64
stderr=serial
stdin=serial
stdout=serial
tk=tftpboot 0x02000000 uImage;setenv setargs setenv bootargs ${bootargs};run setargs;nvt_boot 0x02000000
ua=mw.b 0x02000000 ff 0x1000000;tftpboot 0x02000000 upall_verify.img;sf probe 0;flwrite
up=mw.b 0x02000000 ff 0x1000000;tftpboot 0x02000000 update.img;sf probe 0;flwrite
vendor=novatek
ver=U-Boot 2016.07 (May 15 2019 - 21:34:56 +0800)
U-Boot commands
?         - alias for 'help'
base      - print or set address offset
bitwait   - bit compare and wait for equal
blkcache  - block cache diagnostics and control
booti     - boot arm64 Linux Image image from memory
bootlogo  - show lcd bootlogo [hdmi|cvbs]
bootp     - boot image via network using BOOTP/TFTP protocol
chpart    - change active partition
clearenv  - clear env partition.
cmp       - memory compare
cp        - memory copy
crc32     - checksum calculation
decjpg    - jpgd   - decode jpeg picture.

dispaddr  - display the value of 'addr'
dispenv   - display the value of 'env_var'
dispver   - display the uboot version
env       - environment handling commands
exit      - exit script
false     - do nothing, unsuccessfully
fatinfo   - print information about filesystem
fatload   - load binary file from a dos filesystem
fatls     - list files in a directory (default /)
fatmkdir  - create a directory
fatrm     - delete a file
fatsize   - determine a file's size
fatwrite  - write file into a dos filesystem
fdt       - flattened device tree utility commands
flwrite   - SPI flash sub-system
help      - print command description/usage
lload     - lload  - load logo file

logoload  - logoload  - load logo file from a squashfs or cramfs filesystem image for logo display

loop      - infinite loop on address range
md        - memory display
md5sum    - compute MD5 message digest
mm        - memory modify (auto-incrementing address)
mtdparts  - define flash/nand partitions
mw        - memory write (fill)
nm        - memory modify (constant address)
nvt_boot  - To do nvt platform boot init.
nvt_cpu_freq- change cpu freq
nvt_get_cpu_freq- get cpu freq
nvt_get_ddr_freq- get ddr freq/type

nvt_pwr_ctrl_test- Config PWM pwr ctrl(test only)
ping      - send ICMP ECHO_REQUEST to network host
printenv  - print environment variables
pwm       - nvt pwm operation
reset     - Perform RESET of the CPU
run       - run commands in an environment variable
saveenv   - save environment variables to persistent storage
setenv    - set environment variables
sf        - SPI flash sub-system
showvar   - print local hushshell variables
sq        - squashfsload  - load binary file from a squashfs image

squashfsload- squashfsload  - load binary file from a squashfs image

test      - minimal test like /bin/sh
tftp      - boot image via network using TFTP protocol
tftpboot  - boot image via network using TFTP protocol
true      - do nothing, successfully
version   - print monitor, compiler and linker version
waitus    - wait for n us

A few auconfig.txt tricks:

# Save U-Boot code (aarch64) to USB stick
cmd:fatwrite usb 0 0x1e000000 uboot-ram.bin 0x1000000

# Inject kernel parameters
cmd:setenv bootargs ${bootargs} init=/bin/sh

Linux

Injecting kernel command line parameters by setting bootargs in the U-Boot environment appears to work, but the Linux kernel doesn't print anything to the serial port.

References

Clone this wiki locally