Building my own Tivo replacement

The Tivo service is coming to an end in my part of the world, so I’m trying to create an equally wife/child-friendly option for recording free-to-air, over-the-air TV and playing it back.

I already have Raspberry Pi’s connected to the various TVs in the house, and I know that Kodi has good support for tvheadend, so I figured I’d give that a go.

I bought a Hauppauge dual tuner USB stick as I thought that it is a good brand, with good Linux support, and I was keen to run the whole thing on an old Raspberry Pi (model B+, 1st generation) if I could.

Good idea, but a bit tricky in the end, because while Raspbian (and LibreElec) detected the card just fine, they would only detect one tuner on the card.

The fine people over in the LibreElec forums helped me out with patching the kernel to allow for dual tuner support.  To do this, I set up a virtual machine running Ubuntu 16.04 and got it ready to act as a cross-compiler for Raspberry Pi.  The instructions to do so are here – just make sure that you remember what kind of Raspberry Pi you are building for!

The summary of steps I took:

  1. I got the toolchain and copied the right (64-bit) bin path into my .bashrc (specifically :/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin)
  2. I then downloaded the 4.9 kernel with git clone --depth 1 -b rpi-4.9.y
  3. I then got patch from a user called Puffin Chunks and followed their instructions
  4. I applied the patch as per instructions (i.e. patch -p1 < ../hauppage_winTV_dualHD_DVB_PuffinChunks_4.9.y.diff)
  5. I then followed the rest of the Raspberry Pi instructions for cross-compiling, paying attention to when to use sudo and when not to!
  6. Because my VM (Hyper-V) won’t do USB pass-through, I put the SD card in a USB card reader and plugged it into another Linux machine on my network. I then mounted it using sshfs, specifically:
    On the machine with the USB card plugged in:
    mount /dev/sdc1 /mnt/fat32/ -o umask=000
    mount /dev/sdc2 /mnt/ext4-2
    bindfs -u -g users /mnt/ext4-2/ /mnt/ext4

    (That last bindfs was due to the fact that ext4 partitions don’t mount with read/write permissions properly.)Then, on the cross-compiling machine:
    sudo sshfs @:/mnt/ext4 mnt/ext4
    sudo sshfs @:/mnt/fat32 mnt/fat32

    This was all in the linux/ folder that I was working within.)
  7. After doing this, the modules install line worked fine:
    sudo make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=mnt/ext4 modules_install
  8. Then, making sure that I had put KERNEL=kernel, I copied the kernel across:
    sudo cp mnt/fat32/$KERNEL.img mnt/fat32/$KERNEL-backup.img
    sudo cp arch/arm/boot/zImage mnt/fat32/$KERNEL.img
    sudo cp arch/arm/boot/dts/*.dtb mnt/fat32/
    sudo cp arch/arm/boot/dts/overlays/*.dtb* mnt/fat32/overlays/
    sudo cp arch/arm/boot/dts/overlays/README mnt/fat32/overlays/
    sudo umount mnt/fat32
    sudo umount mnt/ext4
    I actually called the kernel a new name and then added kernel=.img in /boot/config.txt.
  9. Put the card in, booted it up and we were away to the races!  I was now able to boot the RPi, run raspi-config to get things set up, then SSH on and load all the firmwares from the forum into the /lib/firmware/ folder.
  10. Installing tvheadend was pretty simple – instructions are here, but apt-get worked for me after adding deb jessie main to /etc/apt/sources.list