Category Archives: Hardware

Casting to your ChromeCast in Chromium

I have a Google ChromeCast, it is an extremely convenient gadget to stream all sorts of audio and video to your television, regardless of its make or brand.
Today I learnt something new, so let me tell you about that. But an introduction first.

I have a media collection at home, stored on a big disk in my server, and I have a Universal Media Server (UMS) running on my Slackware LAN server to get access to my audio and video files.

Usually from my Android Smartphone (I have always only bought HTC phones and currently it’s a HTC 10) I connect to my movies using BubbleUPnP, a cool application for which I actually bought a license. BubbleUPnP is a UPnP controller, meaning it does not necessarily play video by itself, but it is able to connect a media source (the UMS server) and a media renderer (like a television) and control the playback as a ‘man in the middle’.
For this to work, your television must understand UPnP and be able to announce itself as such on your network, and act as a media renderer. Many of the ‘smart’ televisions sold today have this capability, but many older televisions need a bit of help.
Enter the ChromeCast, a smart Linux-powered device with a wireless network card which connects to your television’s HDMI port. Once connected to your Wi-Fi network, it acts as a UPnP media renderer which means you can stream audio and video to it. However dumb, your television receives the HDMI input from the ChromeCast and will ‘just’ play back what it receives.
The BubbleUPnP app on my phone manages this with great success, and other apps will suddenly also have an extra button on-screen. Such as your phone’s Netflix and Youtube apps, which allows you to watch Netflix or Youtube on a big tv-screen instead of your puny little phone screen.

Now on a laptop or desktop computer, it is a bit of a different story. Your application must be able to act as a UPnP client to allow it to find a ChromeCast and stream media to it. On Linux, I could not find many applications that will cast media to a UPnP renderer. VLC is one good example. Chromium is another good example.

Or so I thought, but I was unable to get Chromium to find my ChromeCast… I tried from time to time, and when it would not work, I would simply take my phone and stream from there. But today, I thought ‘I need to fix this’. So, some searching around on the Internet and I found the fix.

All that’s needed is to enable “chrome://flags/#load-media-router-component-extension“… just copy and paste that bold text into your Chromium URL entry field and you get this:

The default setting called “Default” obviously is not sufficient, so I set the value to “Enabled” and voila! My Chromium browser finds the ChromeCast and I can watch fullscreen movies from a browser tab.

I hope someone sometime searches for and finds this piece of information and benefits from it.

Eric

Using your Slackware to control your Android

Linux and Android

No worries, even though this article is a side-step into the Android ecosystem, it is still on-topic for Slackware users.
I recently bought a Huawei Watch 2, when it was in a sale on Amazon. It’s the 4G version and long ago I had made a deal with myself that if a smartwatch with GPS and room for a SIM card would go below 300 euros, I was going to buy it. And so it happened, and the watch is a lot of fun. It’s incredibly light-weight and fits comfortably. Despite grumpy reviews it is a solid design and does not feel like cheap junk at all. I still need to find a provider who will allow me to use a second SIM card for my mobile subscription, so for the moment this watch is SIM-less. It talks to my phone over Wi-Fi and Bluetooth so nothing’s lost and I have full connectivity on the watch. The idea is to have a SIM in the watch so I can go outdoors for a long run without having to take my phone with me.

An Android Wear watch will pair with only one single phone. It’s quite picky about its friends. Therefore, if you switch phones and want to pair the watch to your new phone, it will wipe and reset itself to factory defaults. That was not what I wanted when I traded my four years old HTC One M8 for a HTC 10 phone. Yes, that too was a bargain sale – I got it for 272 euros which is roughly 65% of the regular price around here.

So I went searching for ways around my dilemma, and as it turns out: it is quite easy to de-couple an Android watch from its pal the phone, and let it pair with a new phone, while keeping its current settings and content. I am going to document that process here, because much of it is generic enough that you can use it to manage the internals of any Android device, like your phone.

The singularly important tool for interacting with Android devices is the Android Debug Bridge, or “adb” for short. It’s a program or rather a suite of tools that run on Linux, Windows and OS/X and allow you to execute commands remotely on the Android device. Commonly the bridge is used over a USB connection between Computer and Android device, but in this article I will show you that you can just as easily use a Wireless connection.

Installing Android Debug Bridge

First, let’s setup the Linux computer. In our case, that will of course be a Slackware computer, right? 🙂

ADB is a small part of the “Android SDK Platform-Tools” and in the past, this meant you had to install the complete SDK in order to gain access to adb and fastboot. Recently, Google has started making adb and friends available as a separate, much smaller (around 5 MB) ZIP download. The URL is static but the content will be refreshed from time to time.

  • Download the ZIP containing the platform-tools for Linux:
    wget https://dl.google.com/android/repository/platform-tools-latest-linux.zip
  • Extract the ZIP file to /usr/local (you need to be root):
    unzip -d /usr/local platform-tools-latest-linux.zip
    That leads to a directory /usr/local/platform-tools/ with a lot of stuff in it.
  • Create two wrapper scripts for the ‘adb’ and ‘fastboot’ binaries inside the extracted directory. This way, typing “adb” or “fastboot” will work in any directory:
    cat << EOT > /usr/local/bin/adb
    #!/bin/bash
    /usr/local/platform-tools/adb “$@”
    EOT
    chmod 755 /usr/local/bin/adbcat << EOT > /usr/local/bin/fastboot
    #!/bin/bash
    /usr/local/platform-tools/fastboot “$@”
    EOT
    chmod 755 /usr/local/bin/fastboot
  • Download and install a UDEV rules file which identifies most if not all known Android devices and makes udev create device-files for them when the Android connects (strictly speaking, his is only relevant for remote debugging over USB… if you connect over wireless then device-files are not used). The file is community-maintained and part of a git repository for Ubuntu. After installing the UDEV rules, you need to reload udevd’s cached rules:
    wget -O /etc/udev/rules.d/51-android.rules https://raw.githubusercontent.com/NicolasBernaerts/ubuntu-scripts/master/android/51-android.rules
    chmod 644 /etc/udev/rules.d/51-android.rules
    /etc/rc.d/rc.udev reload

You’re all set now to connect to your Android device and interact with it. Thanks to the UDEV rules you’ve installed, you won’t have to be root to use ‘adb‘ and ‘fastboot‘ as long as your user account is a member of the “plugdev” group.

Tip: if you have a USB stick with the Slackware Live Edition, you can repeat the above with one change: instead of installing the debugger tools to /usr/local , the wrapper scripts to /usr/local/bin and the UDEV rules to /etc/udev/rules.d/ you (i.e. with “/” as the root) you install the lot to the /rootcopy/ directory of the USB stick, keeping the same directory structure and thus ending with /rootcopy/usr/local/bin/ and /rootcopy/etc/udev/rules.d/ . That will make your Slackware Live a powerful tool to manage Android devices.

Enable remote adb debugging

Android devices do not allow remote debugging by default and it is not immediately visible how to enable this capability. You will have to enable developer options on your Android. This takes the form of a secret ritual… and enables several new menus and options in your Settings.
First, generic Android instructions:

  • Open the “Settings” on your Android.
  • Scroll down to “About phone” (or “About Tablet”)
  • Find the entry which shows the “Build number”.
  • Repeatedly, tap the “Build number” line. After a couple of taps, a popup message tells you that you are an “X amount” of clicks away from becoming a Developer. As you keep tapping the number “X” will decrease to zero which completes the process.

Android Wear instructions:

  • Swipe down from the top of the screen.
  • Tap the “Settings” icon (gear icon).
  • Scroll down and tap “System”.
  • Scroll down and tap “About”.
  • Then scroll down and tap “Build Number” repeatedly.
  • Keep tapping until you get the message “You’re now a developer”.
  • Swipe to the right twice.
  • Scroll down and you’ll see new “Developer Options”.

In the new Developer Options menu you will find “ADB debugging” which you have to enable. For the Android Wear device, it makes sense to also enable “Debug over Wi-Fi” since at least my watch does not have a micro-USB connector.

If you look at the screenshot you’ll notice that the watch’s IP address is shown in the “Debug over Wi-Fi” section. We will need that IP address soon.

Connect to Android using adb

Connecting to a device which is connected through USB is simple. You request an overview of detected devices and if your device (phone or tablet) is detected, it will be listed and you can control it remotely:

adb devices

With a smartwatch, you first need to connect to its IP addres over the port number shown in the screenshot above:

adb connect 192.168.1.100:5555

You do not need to be root to do this.
Any of the above two commands will start the adb daemon if it is not yet running. In case of connecting to a smartwatch, you will have to accept the incoming connection on the watch-side.

You can now start sending commands to be executed on the Android device. For phones, this is usually part of the rooting process followed by installing a custom ROM. That is beyond the scope of this article.

Pair your watch with a new phone

Now that the pre-requisites have been taken care of, let’s go through the steps to pair the Android Wear watch with a new phone. You do not need to be root to do this.

  • Disable Bluetooth on your old (if you have it still) and new phone.
  • Open an adb shell – basically a remote shell on the watch. You’ll notice the prompt (sawshark:/ $), sawshark is the Android codename for my Huawei Watch 2 Sport:
    adb shell
    sawshark:/ $
  • Execute the command that instructs Package Manager to clear stored data & cache (“pm clear”) of the Google Play Services (“com.google.android.gms”) and reboot the watch:
    pm clear com.google.android.gms && reboot

    This clears the pairing information including the keys to communicate securely with the paired phone, but does not trigger a factory reset which happens if you un-pair the phone via the watch settings menu.

  • Make sure you have installed the Android Wear app on your new phone but do not enable Bluetooth on the phone yet.
  • From the computer, connect to your watch again over Wi-Fi (accept the incoming connection request on your watch) using the “adb connect” command shown earlier. Start a new “adb shell”.
  • At the remote prompt enter the command to make the watch visible for Bluetooth discovery by telling Activity Manager to start an Activity specified by the intent “android.bluetooth.adapter.action.REQUEST_DISCOVERABLE” (and make sure you accept the ‘OK’ prompt on your watch):
    am start -a android.bluetooth.adapter.action.REQUEST_DISCOVERABLE
  • Now is the time to start Android Wear on your new phone, allow the app to turn on Bluetooth and start scanning for a Android Wear watch to pair with. When the phone finds your watch, an accept request will show on both. Once you have accepted both prompts, new pairing keys will be generated and stored in the watch’s Google Play Services app. You can synchronize the watch data to your phone and manage it from there.

Good luck! Eric

Build box: step 1, install Slackware

The new computer with its Ryzen CPU created some issues for me. To start with… I had not considered the possibility that a Ryzen CPU would not have an embedded GPU and so I did not order a graphics card. Bad idea!
I ended up ripping a GPU from one of my other computers (the only PCI-express card I could find) and plugging that into the new computer. That gave me a working video instead of a monitor that kept falling asleep.

Next came Slackware. When I booted the Slackware 14.2 installer, it did not give me a network connection. The Slackware Live Edition (based on slackware-current) worked properly on the other hand. But the graphics card I plugged into the computer did not work too well with the nouveau driver – whenever I started Chromium, it was inevitable that the computer would lock up after some time. Initially I blamed this on the computer hardware and feared that I bought a dead duck, but once I stopped running Chromium in the graphical desktop of Slackware Live, the system would remain operational. Since it is not going to be used as a desktop system and I will access it only remotely, that buggy nouveau driver is not a big issue and I could still install the binary Nvidia blob if needed.

So, the question became: I want to run a stable Slackware release on my new build server, but how am I going to install it? I was facing two major issues:

  1. The installer of Slackware 14.2 does not support NVMe boot devices (the new type of SSD hard drives with a M.2 PCI-express interface)
  2. The Slackware 14.2 installer lacks network capability on this new hardware, so I would have to perform a local install

I could spend a USB stick, putting the Slackware 14.2 DVD ISO on it, but then I still would have to patch the installer and I would not have a network connection after reboot. Considering the fact that slackware-current’s kernel works much better and NVMe support was added to the -current installer recently, I decided on a different approach.

I used a slackware-current based liveslak to setup the computer with Slackware 14.2 and then added a 4.9 kernel using the configfile for this kernel as found in slackware-current.

Steps taken:

  • Obtain a recent ISO of the Slackware Live Edition which is based on slackware-current (for instance, the 2.7 GB bleeding edge version or else the 700 MB XFCE based edition)
  • Write the ISO to a USB stick and boot liveslak. Now you have a proper graphical environment where you can query Google/DuckDuckGo and download anything you need.
  • We can not use the “setup2hd” of liveslak because that will install slackware-current and I want 14.2. So, download the smallest installer we can get:  slackware64-current-mini-install.iso which contains just the kernel and the installer (no packages) and is slightly more than 100 MB in size:
    # wget http://bear.alienbase.nl/mirrors/slackware/slackware64-current-iso/slackware64-current-mini-install.iso
  • Download my “extract_initramfs.sh” script which makes it easier to extract the initrd.gz file containing the installer:
    # wget http://www.slackware.com/~alien/tools/extract_initramfs.sh
  • Partition the SSD drive. The M.2 interface results in a character device /dev/nvme0 and a namespace block device /dev/nvme0n1. The first partition on this device will be called /dev/nvme0n1p1. The installer in Slackware 14.2 can not handle this new namespacing format. The one in -current can.
    This is a UEFI computer, and I want Slackware to use this. That requires a FAT partition which will be used as the EFI system partition. Slackware will mount this partition at /boot/efi. I created a 100 MB partition of type EF00 (EFI system) and formatted this with:
    # mkdosfs -F32 -s 2 -n “EFI” /dev/nvme0n1p1
    The remainder of the disk is partitioned with swap (yes even with 64 GB of RAM it is still a good idea to add some swap space), and additional partitions are created for /, /boot, /var, /tmp and /home .
  • Extract the installer from this mini ISO into a new directory “/root/initrd64-current“:
    # mount -o loop slackware64-current-mini-install.iso /mnt/tmp
    # sh extract_initramfs.sh /mnt/tmp/isolinux/initrd.img /root/initrd64-current
  • Get the installer running in the terminal while we are still in a liveslak graphical Desktop Environment:
    # mount -o bind /dev /root/initrd64-current/dev
    # mount -o bind /proc /root/initrd64-current/proc
    # mount -o bind /sys /root/initrd64-current/sys
    # chroot /root/initrd64-current
  • Inside this chroot-ed installer environment, run the ‘setup‘ command and proceed as usual with the installation of Slackware64 14.2 from a network server. The liveslak has already taken care of the network connectivity. I have NFS and HTTP servers at home, providing package trees but I pick NFS because that is much faster. I pointed the installer to a Slackware64-14.2 package source and did a full install (first time ever that I installed the Emacs package, go figure).
  • At the end of the installation, do note yet exit! Instead, run “chroot /mnt” to enter the freshly installed system. Configure slackpkg with a suitable mirror, then run:
    # slackpkg upgrade-all
    This will install all the latest patches including the latest kernel.
  • Finally, blacklist the kernel-generic and kernel-modules so that slackpkg will never replace our kernel accidentally.
  • Create an initrd (the /usr/share/mkinitrd/mkinitrd_command_generator.sh script will help you finding the correct parameters) and copy the generic kernel and this initrd to the EFI partition. This is the elilo.conf file I ended up with:
    # cat /boot/efi/EFI/Slackware/elilo.conf
    chooser=simple
    delay=50
    timeout=50
    default=slackware142
    image=vmlinuz
        label=huge142
        read-only
        append="root=/dev/nvme0n1p7 vga=normal ro"
    image=vmlinuz-generic-4.4.75
        label=slackware142
        initrd=initrd_4.4.75.gz
        read-only
        append="root=/dev/nvme0n1p7 vga=normal ro"
  • Now that the Slackware 14.2 installation is complete we have to ensure that we add a working kernel to it. I want to use the kernel as found in slackware-current because I know the 4.9.x series is good (liveslak proved that) and because slackware-current contains a kernel config that I can just re-use. Download the kernel source, and the kernel packaging scripts so that we can compile a kernel and its modules manually but still can wrap the results in package format and install those. Warning – when you try this at home, the actual kernel version may have moved beyond the “4.9.44” which I use in the example below. Just substitute the actual version instead:
    # CWD=$(pwd)
    # lftp -c “open http://slackware.osuosl.org/slackware64-current/source; mirror k”
    # cd k/
    # tar -C /usr/src -xf linux-4.9.44.tar.xz
    # cp config-x86_64/config-generic-4.9.44.x64 /usr/src/linux-4.9.44/.config
    Now we can compile that kernel (yes I compile kernels as root):
    # cd /usr/src/linux-4.9.44
    # make oldconfig
    # make -j 15 all
    # make install
    Now that the kernel is installed as /boot/bzimage and the modules as /lib/modules/4.9.44 we use the Slackware packaging scripts to create two packages:
    # cd $CWD/k/packaging-x86_64/kernel-generic
    # ./kernel-generic.SlackBuild
    # cd $CWD/k/packaging-x86_64/kernel-modules
    # ./kernel-modules.SlackBuild
    The two packages in /tmp can then be installed using “installpkg”. Do not use “upgradepkg” with your kernels – you will want to keep at least one previous kernel. The kernel-modules package will essentialy overwrite what’s in /lib/modules/4.9.44 but now with a package, we can control it through the package manager if needed. The kernel-generic package will have installed the new kernel as /boot/vmlinuz-generic-4.9.44. Copy that kernel to the EFI partition, and create a new initrd in the same location to match the kernel:
    # cp /boot/vmlinuz-generic-4.9.44 /boot/efi/EFI/Slackware/
    #  $(/usr/share/mkinitrd/mkinitrd_command_generator.sh -k 4.9.44 -r -a “-o /boot/efi/EFI/Slackware/initrd_4.9.44.gz”)
    Add a section for the new kernel to elilo.conf. You can just copy the existing section for “label=slackware142” and change the version numbers. Make sure that the “default” keyword has this new label as its value. We want the new kernel to boot by default.
  • Exit the installed system’s chroot:
    # exit
  • Then exit the installer’s chroot:
    # exit
  • We are almost done. Unfortunately the eliloconfig of Slackware 14.2 did not add a Slackware entry to the computer’s EFI boot menu. So now that we are back in liveslak we need to fix this omission using the eliloconfig of slackware-current which is part of our liveslak:
    # eliloconfig /setup2hd /dev/nvme0n1p7
    This assumes the installed system is mounted under /setup2hd and the root partition is /dev/nvme0n1p7 . Change the parameters to match your situation. This time you will see that the Slackware entry is being created.
  • Reboot the system.
  • Have fun!

If I have omitted anything or steps are unclear, let me know. Now that I have Slackware on it, I can start thinking of how to add a virtualization solution. Either use my old scripts that wrap qemu and are very convenient and versatile, or go for qemu with libvirt and manage my virtual machines with virt-manager. The possibilities are endless. But first I need to get on with virtualizing my current server’s OS… its LAN services must stay operational but then in a VM on the new hardware.

New server arrived in the post

The hardware I ordered for the new build server arrived today – all components assembled and tested.

I am too tired to connect and boot the thing, so all I provide today is a pic of the package.

Then I have a lot of installation and configuration work to do the next couple of days… so I should hope that the downtime maintenance weekend at the office is going to be canceled.

New build server was ordered

OK, so I got frustrated too many times when waiting for packages that were compiling. My current build machine with its AMD ‘Athlon II X4 640’ CPU and 8 GB of RAM, is now 5 years old and obviously no longer quite fit for the tasks I need it to perform. Compiling Chromium for 64bit Slackware in a virtual machine took more than 24 hours last week (yes, for a single package). Basically, that convinced me to empty my stash of donated funds (thanks to all of you Slackware supporters) and order the most powerful midi tower I could buy for that money. What else is that money for, after all. Well, beer perhaps 🙂
Because the computer’s location will be the attic of my own house, its components (Seasonic PSU, Scythe CPU cooler, and the ‘be quiet Silent Base’ case itself) are chosen to minimize noise – it’s actually going to be sitting next to a bedroom wall.
The CPU I chose with the help of a friend, and after some consultation of my hardware store, is an AMD Ryzen 1700 at 3,0 GHz, along with 64GB of Corsair RAM (DDR4 at 3,0 GHz) but I am going to slightly overclock both. I added a 500GB Samsung 960 EVO SSD (NVMe) as well as a 4 TB Western Digital Red SATA disk.

With that machine I will be able to parallellize my build efforts and that means, I can give you more updates and still spend more time with my family. The whole hardware order costs slightly more than 1700 Euros which sounds like a lot (Robby pointed me to Ebay discard servers for a couple of 100 dollar) … while rackmount servers are cheap, you can not put them in your home because of the noise.
But it’s going to be worth it. And I will still have money left in my donations account to keep paying the rent for the ‘bear‘ server for at least another year. And then it’s rock bottom.

I will give more information when I actually get the hardware, install Slackware on it and create a virtual machine environment. I am not yet sure if I will keep using my own custom scripts to create ‘on-demand’ virtual machines or that I will switch to using virt-manager.
And I can finally also consider another “TODO” project that has been on the horizon for a long time: using Jenkins CI for ‘continuous build’ of my own (and Slackware’s) packages.
I will try to document as much of it as I can. I am sure that more people consider using virtualization to fence off processes, or create predictable (Slackware) OS environments using VM snapshots, or produce predictable builds. It’ll probably take months to get that point though… I am not in a hurry.

Again, thanks for all the donations during the past years that enabled me to do this purchase. You will hopefully benefit from it. Return on investment so-to-speak.

Eric