I wrote recently about some of my experiences in trying to use BirdDog NDI encoders with OBS, specifically syncing issues. As part of that I took a deeper look into the devices themselves. I love disassembling and hacking stuff, unfortunately I have to balance that out with warranties haha. (Update 11 December 2020: turns out you can non-destructively disassemble both the 4K Flex In and Mini).
This is what the backside of a BirdDog Mini looks like inside:
And the other side of the board:
It’s a beautiful board. Black, copper and lots of classy white labels. I’d love to gain access to the serial console, but the selection of headers is a bit slim. There is a lonely header (J2) which appears to be 3.3V and GND. There are various test pins and also a ribbon cable connector labelled “BOT CT” but there’s no indication on the board that any of those pins/pads are the serial console. I suspect BirdDog uses the same PCB in the mini in their Studio product (the ports are in the same places) and that the BOT CT connector connects to the SDI and LED hardware.
BirdDog supplies firmware images for their devices and I was curious what might be inside those files. Looking at the log during a firmware update it looked suspiciously like the BirdDog encoders may be running Linux, which is a common approach to an embedded device like this. Enter binwalk.
We’re working with BirdDog_Flex_In_1.6.2.fw, available in an archive from their support site.
We’re going to ask binwalk to recursively scan and extract all archives in the fw update file:
binwalk will output a lot of info about what it finds and it will decompress many files that won’t be of interest, but these are the interesting bits:
0.tar birddog-platform-files birddog-update.sh external
birddog-platform-files is a linux rootfs, specifically the product of a Board Support Package, or BSP. The distribution is PetaLinux, which is largely a Xilinx thing.
aquarat@deskrat:~/Downloads/BirdDog teardown/_BirdDog_Flex_In_1.6.2.fw.extracted/_0.extracted$ ls birddog-platform-files/ bin boot etc lib srv usr
I probably can’t paste the contents of files here without incurring some sort of copyright theft, but in short, these are the files of interest:
- birddog-update.sh: Makes a note of the hardware ID, writes the QSPI, which I assume is the bootloader, applies the update package. When you update the firmware and see the log in the browser window, it’s this script’s output that you’re seeing.
- external/ : Filled with alsa and audio related .deb archives. Alsa seems to be used by the comms system.
aquarat@deskrat:~/Downloads/BirdDog teardown/_BirdDog_Flex_In_1.6.2.fw.extracted/_0.extracted/birddog-platform-files/bin$ ls bdg_headset_mic bdg_headset_speaker birddog-check-gpio birddog-runner BirdDogSrvr birddog-web-ui _birddog-web-ui.extracted ndi_src_find_app tiny_4k_enc_app ubuntu_ti3104_app
- most of these files are binary executable (bdg_headset_mic: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 2.6.32, BuildID[sha1]=8d883e48f7e4789d5fdec8db5e9be466cd843a24, with debug_info, not stripped)
- birddog-check-gpio: seems to check on startup if the reset button is being pressed. If it is it waits 5 seconds, checks again, resets the network config and the web ui password.
- birddog-web-ui is interestingly a Golang executable, which relies on template HTML files:
aquarat@deskrat:~/Downloads/BirdDog teardown/_BirdDog_Flex_In_1.6.2.fw.extracted/_0.extracted/birddog-platform-files/bin$ ls ../srv/birddog-web-ui/ birddog_flex_in.png birddog-mc-enable decoder-src.html libndi.so.3 login.html net-dhclient.tmpl network.html ptz.html settings.html static trailer.html update-progress.html video-param.html _birddog_flex_in.png.extracted dashboard.html header.html link.html ndi.html net-interfaces.tmpl operation-configuration.html reboot.html soft-reboot.html system-settings.html update.html video.html videoset.html
BirdDogSrvr is a folder containing Node files (JS), which drive the API portion of the system. It’s an express application with a couple of routes. There’s nothing particularly undocumented of interest.
aquarat@deskrat:~/Downloads/BirdDog teardown/_BirdDog_Flex_In_1.6.2.fw.extracted/_0.extracted/birddog-platform-files/bin/BirdDogSrvr$ ls AboutMe.json BashScript BirdDogCam.js BirdDog.js birddog_mdns_service.sh connect.json node_modules resetPreset.json restart.sh
I’ve sifted through these files and I haven’t found any way of turning on the installed telnet server or executing arbitrary commands :(. Good job to BirdDog for securing their devices, but meh for me.
aquarat@deskrat:~/Downloads/BirdDog teardown/_BirdDog_Flex_In_1.6.2.fw.extracted/_0.extracted/birddog-platform-files$ cat boot/uEnv.txt bootargs=console=ttyPS0,115200 root=/dev/mmcblk0p2 rw rootwait earlyprintk net.ifnames=0 mem=960M uio_pdrv_genirq.of_id=generic-uio bitstream_image=system.bit script_address=0x80000 script_name=boot.script.img load_script=source ${script_address} boot_script=load mmc 0:1 ${script_address} ${script_name} && source ${script_address} uenvcmd=run boot_script
What are the chances there’s an SD card in there? haha
aquarat@deskrat:~/Downloads/BirdDog teardown/_BirdDog_Flex_In_1.6.2.fw.extracted/_0.extracted/birddog-platform-files$ ls usr/bin node-v10.13.0-linux-armv7l.tar.xz _node-v10.13.0-linux-armv7l.tar.xz.extracted
rc.local appears to program the FPGA module and interacts with it through /dev/xdevcfg and /sys/devices/soc0/amba/f8007000.devcfg/prog_done.
rc.local also loads audio modules, extracts Node, sets some execute permissions on files and starts a BirdDog Central Server.
That was the 4K firmware, now let’s have a look at the Mini’s Firmware:
The Mini’s firmware is largely the same structure as the 4K Flex, but with a little more legacy stuff going on. I’m going to concentrate on what’s different and interesting:
- birddog-update.sh is different but largely does the same stuff. It’s set up for several older products.
- external/: is still alsa and sound related deb packages but there’s also another rootfs:
aquarat@deskrat:~/Downloads/BirdDog teardown/_BirdDog_Mini_NDI_4_V_3.6.3.fw.extracted/_0.extracted/external/_bdstum05r4cam7d27feb2020.bin.extracted/_petalinux-user-image-plnx_arm-20191217225041.rootfs.cpio.extracted/cpio-root$ ls bin boot dev etc home init lib media mnt proc run sbin sys tmp usr var aquarat@deskrat:~/Downloads/BirdDog teardown/_BirdDog_Mini_NDI_4_V_3.6.3.fw.extracted/_0.extracted/external/_bdstum05r4cam7d27feb2020.bin.extracted/_petalinux-user-image-plnx_arm-20191217225041.rootfs.cpio.extracted/cpio-root$ ls etc busybox.links.nosuid filesystems group- hostname init.d issue ld.so.conf login.defs mtab passwd profile rc1.d rc4.d rcS.d rpm-postinsts shadow skel syslog-startup.conf udev busybox.links.suid fstab gshadow hosts inittab issue.net limits logrotate-dmesg.conf network passwd- protocols rc2.d rc5.d rpc securetty shadow- syslog.conf syslog-startup.conf.busybox udhcpc.d default group host.conf inetd.conf iproute2 ld.so.cache login.access motd nsswitch.conf petalinux rc0.d rc3.d rc6.d rpm services shells syslog.conf.busybox timestamp version aquarat@deskrat:~/Downloads/BirdDog teardown/_BirdDog_Mini_NDI_4_V_3.6.3.fw.extracted/_0.extracted/external/_bdstum05r4cam7d27feb2020.bin.extracted/_petalinux-user-image-plnx_arm-20191217225041.rootfs.cpio.extracted/cpio-root$ cat etc/issue PetaLinux 2017.3 \n \l
- There is no ssh server in this rootfs, but there is a telnetd reference (via BusyBox).
- telnetd is not configured to run in any startup scripts/runlevels.
- etc/shadow contains a password for root, which is root (thanks John).
- a getty runs on ttyPS0, which is not the VISCA interface on the minijack port (that’s ttyPS1).
birddog-platform-files:
- bin: most files/utilities are the same, except for ndi_enc_dec_app, mini_dec and mini_enc.
- slightly different uEnv.txt:
aquarat@deskrat:~/Downloads/BirdDog teardown/_BirdDog_Mini_NDI_4_V_3.6.3.fw.extracted/_0.extracted/birddog-platform-files$ cat boot/uEnv.txt bootargs=console=ttyPS0,115200 root=/dev/mmcblk0p2 rw rootwait earlyprintk net.ifnames=0 mem=960M uio_pdrv_genirq.of_id=generic-uio bitstream_image=system.bit script_address=0x80000 script_name=boot.script.img load_script=source ${script_address} boot_script=load mmc 0:1 ${script_address} ${script_name} && source ${script_address} uenvcmd=run boot_script
Update 11 December 2020:
I thought I had to void my warranty by breaking a few things to get into the 4K Flex units I own… but I was wrong. They’re very easy to non-destructively open and they’re very cheaply constructed compared to the Mini. It’s obvious why they cost less despite doing double the resolution.
A few points I noticed:
- POE module is a separate board – I’ve seen these all over the web.
- The RAM, system flash and CPU/FPGA block are now more like a System-On-Module. The HDMI connectivity and power is handled by a host board.
- The BOT CT connector I saw on the Mini is present on this board, and like the Mini it is not connected to anything.
- It isn’t obvious from the photos but the SoM is connected to the host board via two ribbon cables (one of them may be a CSI cable maybe?), power and what I assume is the ethernet link (twisted DC-coloured cables).
- No obvious serial terminals.
Now would be a good time to note that I believe BirdDog is in violation of the GPL. The reason I say that is, as can be seen above, their firmware uses PetaLinux, the Linux kernel itself, the U-Boot bootloader, BusyBox and various other utilities, which are all GPL licensed. BirdDog doesn’t acknowledge the use of GPL software anywhere. They don’t ship their devices with the licence, they don’t release the source code. When asked about it via email they responded saying that they’re not in violation of the GPL. I’m not an expert but it seems dodgy.