Skip to content
April 30, 2017 / ftth

Installing Ubuntu 16.04 alone on a 2006 MacBook

This aging device has an unsupported OS, and you can’t even upgrade your web browser anymore, which means that Linux is the last breath for it. I didn’t expect it to be so difficult, but it eventually panned out.

Current Linux distros USB sticks won’t be detected by the bootloader (hold the alt key after power) of the venerable 2006 MacBook (A1181 ref, CPU is a Core 2 T7200). The reason seems to be that, regardless of CPU 64 bit support, the EFI implementation of these early mactels is 32-bit only, not to mention many other apple-specific quircks which prevent compatibility. In the past, Ubuntu did have a mac-specific release, which vanished in the meantime.

In other terms, your USB stick will only be listed by the mac bootloader if a /efi/boot/bootIA32.efi file is found on a FAT32 partition; i did try copying an Arch install media on a FAT32 stick, and it kind of works thanks to the presence of /efi/boot/bootIA32.efi (listed as bootable !) but it freezes when trying to boot the kernel. One of the ways to succeed booting is to use a pretty much obscure, apparently grub-based EFI loader, “ISO-2-USB EFI-Booter for Mac”, obtainable here (zip contains bootIA32.efi and bootX64.efi files), and to copy the iso and efi files onto a FAT32 USB stick as follows. It will enable loading a boot.iso file located next to it.

Using e.g. gparted, create a new msdos (mbr) partition table, with a single FAT32 partition; on it, create the files below (that is the entire USB drive file tree, yes, only these two files):

  • efi/boot/bootIA32.efi (copied from ISO-2-USB EFI-Booter for Mac)
  • efi/boot/boot.iso (copied from the 32 bits lubuntu iso file, renamed)

This should allow to boot the Ubuntu live USB (tested with lubuntu 16.04.2 32 bits) — remember to select the Macintosh keyboard variant during install. However, grub installation will fail; it wouldn’t boot anyway because the mac firmware expects the EFI partition (/dev/sda1) to be a specially “blessed” HFS+ partition (instead of modern/standard UEFI which expects a EF00 type FAT32 first partition); it also expects some hardcoded files to be present. This can unfortunately not be fixed using a chroot (i tried, but grub-install fails, complaining that efibootmgr is not present), so you must reboot, and manually boot. You should arrive at a failing grub console; follow the instructions here thorougly: http://heeris.id.au/2014/ubuntu-plus-mac-pure-efi-boot/#manual-boot

Once booted (that was probably a bit painful if you are not using a qwerty), continue following the instructions (reformatting /dev/sda1 to HFS+, installing grub and blessing the HFS+ partition) but replace these 2 commands to target 32 bit EFI (where the original guide targets 64 bits — also note that the vmlinuz file was not ending with .efi.signed, but that did work for me).

sudo apt-get install mactel-boot hfsprogs gdisk grub-efi-ia32
grub-install –target i386-efi –boot-directory=/boot –efi-directory=/boot/efi –bootloader-id=”$(lsb_release -ds)”
update-grub # not present in the original guide

Reboot, and you should finally boot straight to Ubuntu — albeit under a 32 bits OS. But that’s a miracle already.

All credit goes to:

February 17, 2017 / ftth

Changing mysql nice priority on Ubuntu 16.04

I wanted to prioritize mysqld, and the only sources i could find were all referring to the nice parameter to mysqld_safe in /etc/mysql/my.cnf or hacking the /etc/init/mysql.conf. None of these worked for Ubuntu 16.04.

Systemd is now the init daemon for Ubuntu, so that’s the one who is launching it now:

root@easycast-myserver:~/bench# service mysql status
● mysql.service - MySQL Community Server
 Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled)
 Drop-In: /etc/systemd/system/mysql.service.d
 └─override.conf
 Active: active (running) since Fri 2017-02-17 10:40:04 CET; 5min ago
 Process: 8665 ExecStartPost=/usr/share/mysql/mysql-systemd-start post (code=exited, status=0/SUCCESS)
 Process: 8655 ExecStartPre=/usr/share/mysql/mysql-systemd-start pre (code=exited, status=0/SUCCESS)
 Main PID: 8664 (mysqld)
 CGroup: /system.slice/mysql.service
 └─8664 /usr/sbin/mysqld

So dropping the following systemd Nice option on the /etc/systemd/system/mysql.service.d/override.conf file did work:

[Service]
Nice=-1

 

Just restart the services:

systemctl daemon-reload && service mysql restart

 

October 14, 2016 / ftth

Building nvenc on Ubuntu 16.04

Took me a while to figure out, here’s a guide on building nvenc on Ubuntu 16.04:

  • apt-get install nvidia-cuda-dev nvidia-361 git pkg-config bison flex
  • apt-get build-deps gstreamer1.0-plugins-base gstreamer1.0-plugins-bad
  • download the 6.0 version of the nvidia video codec sdk (the Ubuntu 16.04 most recent driver is currently too old for the 7.0 version), unzip the sdk, copy the headers to /usr/local/include (sudo cp nvidia_video_sdk_6.0.1/Samples/common/inc/* /usr/local/include)
  • build a gst-uninstalled environment (see arun’s guide for instance), compiling gstreamer, gst-plugins-base should suffice
  • compile gst-plugins-bad with:
LDFLAGS="-L/usr/lib/nvidia-361/" ./configure --disable-gtk-doc --with-cuda-prefix="/usr"

Check that it’s working:

gst-launch-1.0 videotestsrc ! nvh264enc ! fakesink

Remember that the GPU must be Maxwell or Kepler (Fermi only supports decoding).

Many thanks to ystreet for his help on getting this right !

The theoretical proper way is the following, but it does not compile (see #772688) :

NVENCODE_CFLAGS="-I/home/user/src/nvidia_video_sdk_6.0.1/Samples/common/inc" NVENCODE_LIBS="-L/usr/lib/nvidia-361/" ./autogen.sh --disable-gtk-doc --with-cuda-prefix="/usr" && make

 

October 6, 2016 / ftth

Tegra TK1 not booting after flashing from Arch Linux

I upgraded an Nvidia Jetson TK1 board to the 21.5 release, and it just never booted anymore. Accessing the RS232 using

sudo screen /dev/ttyUSB0 115200

indicated that the bootloader was not finding the internal sdcard.

The “solution” was to flash from Ubuntu 16.04 LTS and not Arch…

 

September 9, 2016 / ftth

Installing archlinux the EFI/systemd-boot way

I installed a fresh Arch system on an EFI enabled machine, and wanted to use the systemd bootloader (systemd-boot). While the Arch install guide is pretty much consise, it took me a few loops to make it work with UEFI/systemd.

The trick was to

  1. select the UEFI boot mode of the USB install drive (if not, /sys/firmware/efi/efivars is not mounted)
    uefi
  2. create the partitions, ensuring that a big enough EFI  System Partition was present on the root drive (/dev/sda1) — by big enough, i mean that it should be at least 80 or 100 MB big because we’ll store the kernels here
  3. mount /dev/sda2 to /mnt and then mount /dev/sd1 to /mnt/boot before pacstrap
  4. after arch-chroot, install systemd-boot into /boot and create a boot entry

With a little more details:

#2 Create the EFI System Partition

  • gdisk
    • o (create new GPT table)
    • n (create new partition, keep it the first partition and 100 MB big, select EF00 hex code)
    • n (create the other partitions as usual)
    • w (write)
  • format it: mkfs.vfat -F32 /dev/sda1

If you run into the “WARNING: Not enough clusters for a 32 bit FAT!” error, even with the -s2 and -s1 arguments, reboot the system and try again (it worked for me).

#3 Mount /dev/sda2 onto /mnt/boot after mounting /dev/sda1) and run pacstrap; that way, /boot files are already on the UEFI boot partition

mount /dev/sda2 /mnt
mkdir /mnt/boot
mount /dev/sda1 /mnt/boot
pacstrap /mnt base
genfstab -U /mnt >> /mnt/etc/fstab
arch-chroot /mnt

#4 After chroot, install boot loader and create the boot entry

  • install bootloader
bootctl --path=/boot install
  • identify the root partition (not /boot) uuid using ls -l /dev/disk/by-partuuid/
  • create /boot/loader/entries/arch.conf as follows (and update /boot/loader/loader.conf to default to “arch”)
title Arch Linux
linux /vmlinuz-linux
initrd /intel-ucode.img
initrd /initramfs-linux.img
options root=PARTUUID=4f66ed9b-f72d-62c1-89a6-7e2f1979a8f6 rootfstype=ext4 add_efi_memmap

The painful part was to copy-paste the partition uuid in the cmdline environment (you can’t use systemd to run sshd until the installation is complete and you rebooted the system — or i missed something here).

NB: the instructions above are for the archlinux-2016.09.03-dual.iso release.

 

 

March 7, 2016 / ftth

Properly cancelling a gobject action

When you use glib’s timeout_add or idle_add (examples below are for python), you can cancel the action before it is run by executing source_remove.

def action():
 return False
tid = gobject.timeout_add(1000, action)
gobject.source_remove(tid)

However, if the action was already run, the source_remove will trigger the following warnings in the terminal output:

GLib-CRITICAL **: Source ID XXX was not found when attempting to remove it

The documentation states that “It is a programmer error to attempt to remove a non-existent source.” because “source IDs can be reissued after a source has been destroyed”

If you use gobject to schedule a large number of actions, it means that upon cancelling the actions batch, you will end up with tons of warnings on the terminal for each action that has already been run.

I encountered this issue while developing a python benchmarking script that uses gobject to schedule the execution of simulated users. Before running the mainloop, gobject.timeout_add is used for one-time execution of adding simulated users during the test duration. Every source id is stored inside a list so that upon cancelling, we can batch-cancel them; however, there is no way to tell if a particular action id is still valid, so batch-cancelling is done on all actions (regardless if they have been executed already or not).

A way to fix this (thanks to matplotlib‘s zeroSteiner for the tip) is to get the gobject mainloop context, and check if the gobject action source id is still in the execution queue:

context = ml.get_context()
action = context.find_source_by_id(tid)
if action and not action.is_destroyed():
    gobject.source_remove(tid)

However, the documentation states that “It is a programmer error to attempt to lookup a non-existent source.”, so maybe that’s not the cleanest way. If you know a better one, please let me know.

 

January 9, 2016 / ftth

Benchmarking gstreamer OpenGL performance on raspberrypi

After a lot of tinkering (videotestsrc, using temporary gdp files in /tmp), i finally found the optimal way to benchmark the pi gl display performance (of course blocksize needs to be adjusted to a raw buffer size).

gst-launch-1.0 filesrc num-buffers=100 location=/dev/zero blocksize=8294400 ! videoparse format=rgba width=1920 height=1080 ! glimagesink sync=false ... Execution ended after 0:00:09.687275649

Then divide the number of buffers (100) by the execution time (9.69), giving 100/9.69 = ~10 fps.

videotestsrc was quite slow, gdpdepay was killing performance (inducing additional copying), and working with raw files in /tmp was a little bit slower (but still the best way to test pre-rendered samples, e.g. for encoder benchmarking). Using /dev/zero allows to generate completely zeroes buffers very cheaply (meaning completely black and transparent images).

numbers

Note that Gstreamer 1.4 (raspbian) and 1.6.2 (arch) have the same performance, and results seem to be the same on Pi B+ and 2.

Just uploading raw 1080p video to the GLES context (without displaying) runs at 23 fps, representing the actual memory speed bottleneck (= 1.5 Gbits/s !)

gst-launch-1.0 filesrc num-buffers=100 location=/dev/zero blocksize=8294400 ! videoparse format=rgba width=1920 height=1080 ! glupload ! fakesink
Execution ended after 0:00:04.234214792

Unfortunately, this means that the RaspberryPi isn’t usable for any project requiring 30 frames per second HD display performance using Gstreamer.

graph