DKRed

Illustration

While I use OSH Park most of the time, I always like to look at different services, especially if they’re US-based. So, of course I took a note of DigiKey’s DKRed. Unfortunately, review will be really short as I didn’t end up using it.

On surface it looks good. Board requirements are reasonable. If you want to use DKRed service you need to have your design fit 5/5 mil minimum - more than sufficient for all I do. While more detailed specifications are available for other PCB vendors on their platform (albeit Royal Circuits has a bad link), there’s nothing about DKRed itself. Yes, I know DKRed might use any of manufacturer’s behind the scene but I would think collating minimum requirements acros all of them should be done by DigiKey and not left to a customer.

And not all limitations are even listed on that page - for example, fact that internal cutouts are not supported is visible only in FAQ and whether slots are supported is left as a complete secret. Compare this to OSH Park’s specification and you’ll see what I mean.

But ok, I went to upload one small board just to test it. And I was greeted by error that length is shorter than 1 inch. As I love making mini boards smaller than 1", I guess I’m out of luck. But specification page did correctly state that fact so I cannot be (too) angry. Never mind - I’ll try a slightly bigger board. Nope - it has to be more than 4 square inches in area. Something that I didn’t find listed anywhere.

Well, I had need for one board 65x72 mm in size - that one would work. And yes, DKRed finds that board OK. But cost is $43.52. OSH Park charges $36.25 for the same board. And yes, DKRed gives 4 boards ($10.88 per board) while OSH Park only provides 3 ($12.08 per board) so it’s slightly cheaper if you really need all 4 boards. If you’re hobbyist requiring only 1 board like me, you’re gonna pay more.

And this is where I stopped my attempts. Breaking deal for me was the minimum size as this makes it a no-go for most of my boards. And cost for just a prototyping is just too high. Mind you, it might be a good deal for people regularly working with bigger boards at a small quantity. But it’s not for me.

Web Server Certificate From a File

If you’re dealing with HTTPS on .NET 5, you might have seen the following message: Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found or is out of date. Recommendation to solve this is also clear To generate a developer certificate run 'dotnet dev-certs https'. To trust the certificate (Windows and macOS only) run 'dotnet dev-certs https --trust' And you’re pointed toward Microsoft docs for more information.

What’s not clear is that you can also load certificate from file and skip the whole system configuration - really useful if you don’t have the full system access. For that just configure your builder appropriately:

Builder = Host.CreateDefaultBuilder()
    .ConfigureWebHostDefaults(webBuilder => {
        webBuilder.ConfigureKestrel(options => {
        var cert = GetCertificate();
        options.Listen(IPAddress.Any, 443, listenOptions => {
            listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
            listenOptions.UseHttps(cert);
        });
    });
})
.Build();

In example code above, loading the certificate is done from GetCertificate function; something like this:

private static X509Certificate2 GetCertificate() {
    return new X509Certificate2("mycertificate.pfx", "");
}

Case of the Incorrect USB VID

While manually executing script to reflash Sierra EM7455 (since automated steps didn’t work), I accidentally skipped a command - one to change USB VID. For those not familiar with USB, there are two numbers - VID and PID - combination of which allows for system to recognize your device. If you change one and not the other, your system will not recognize device anymore.

In my case, I have created a device 413c:9070. It was a monster with VID belonging to Dell and PID of a generic Sierra device. Combination that’s definitely not recognized. And I couldn’t correct it because that would require serial connection to the device. Serial connection I didn’t have due to the device not being recognized. In Windows you’re officially screwed. But Ubuntu comes to rescue.

In Linux it’s trivial to convince system your “hybrid” device is a valid one. Just load option module and tell your serial driver there’s a new kid in town. In my case, this looked something like this:

sudo modprobe option
echo 413c 9071 | sudo tee /sys/bus/usb-serial/drivers/option1/new_id

With this I got my device’s connection back at ttyUSB2 and could use minicom to manually change VID:

sudo minicom -b 115200 -D /dev/ttyUSB2
 AT!USBVID=1199

Lenovo P70 Fingerprint Reader Under Ubuntu

Fingerprint support under Linux is spotty at best. For many laptops one will never be able to use it. Fortunately, somebody went through the effort to make drivers for VFS7500 Touch Fingerprint Sensor used on P70.

Unfortunately instructions to install it on Ubuntu 20.04 are not really complete so I here is what worked for me. Newer Ubuntu steps should be reasonably similar if not same but I haven’t checked them from scratch.

First I installed a few packages. Since drivers use combination of snap and python, we obviously need them. GMP library is needed to as it’s dependency of pyfast library.

sudo apt-get install --yes snapd python3-pip libgmp-dev
sudo pip install pyusb pycrypto pyfast

Then we can follow original install procedure:

sudo snap install validity-sensors-tools
sudo snap connect validity-sensors-tools:raw-usb
sudo snap connect validity-sensors-tools:hardware-observe

With all in place we can finally initialize reader:

sudo validity-sensors-tools.initializer

Lastly, install libfprint TOD driver.

sudo add-apt-repository -u ppa:3v1n0/libfprint-vfs0090
sudo apt-get install --yes libfprint-2-tod-vfs0090

Now you should see Fingerprint Login in system’s Users applet. Once you enroll your one or more finger, you should be able to use it for login.

Manually Installing Ubuntu 21.04 on Surface Go

Now, one can install Ubuntu perfectly well onto Surface Go without any shenanigans. Just follow a guide on how to boot install USB and you’re golden. But I like my installations to be a bit special. :)

After booting into Ubuntu desktop installation one needs a root prompt. All further commands are going to need root credentials anyhow.

$ sudo -i

The very first step should be setting up a few variables - disk, host, and user name. This way we can use them going forward and avoid accidental mistakes. Just make sure to replace these values with ones appropriate for your system.

DISK=/dev/disk/by-id/^^ata_disk^^
HOST=^^desktop^^
USER=^^user^^

Disk setup is really minimal. Please note you can actually reduce size of boot partition but that might get you in trouble if you start playing with low latency kernel. Some extra space will help here.

blkdiscard $DISK

sgdisk --zap-all                       $DISK
sgdisk -n1:1M:+47M -t1:EF00 -c1:EFI    $DISK
sgdisk -n2:0:+720M -t2:8300 -c2:Boot   $DISK
sgdisk -n3:0:0     -t3:8309 -c3:Ubuntu $DISK

sgdisk --print                         $DISK

I usually encrypt just the root partition as having boot partition unencrypted does offer advantages and having standard kernels exposed is not much of a security issue.

cryptsetup luksFormat -q --cipher aes-xts-plain64 --key-size 256 \
    --pbkdf pbkdf2 --hash sha256 $DISK-part3

Since crypt device name is displayed on every startup, for Surface Go I like to use host name here.

cryptsetup luksOpen $DISK-part3 ${HOST^}

Now we can prepare all needed partitions.

yes | mkfs.ext4 /dev/mapper/${HOST^}
mkdir /mnt/install
mount /dev/mapper/${HOST^} /mnt/install/

yes | mkfs.ext4 $DISK-part2
mkdir /mnt/install/boot
mount $DISK-part2 /mnt/install/boot/

mkfs.msdos -F 32 -n EFI $DISK-part1
mkdir /mnt/install/boot/efi
mount $DISK-part1 /mnt/install/boot/efi

To start the fun we need debootstrap package.

apt update ; apt install --yes debootstrap

And then we can get basic OS on the disk. This will take a while.

debootstrap $(basename `ls -d /cdrom/dists/*/ | head -1`) /mnt/install/

Our newly copied system is lacking a few files and we should make sure they exist before proceeding.

echo $HOST > /mnt/install/etc/hostname
sed "s/ubuntu/$HOST/" /etc/hosts > /mnt/install/etc/hosts
sed '/cdrom/d' /etc/apt/sources.list > /mnt/install/etc/apt/sources.list
cp /etc/netplan/*.yaml /mnt/install/etc/netplan/

If you are installing via WiFi, you might as well copy your wireless credentials:

mkdir -p /mnt/install/etc/NetworkManager/system-connections/
cp /etc/NetworkManager/system-connections/* /mnt/install/etc/NetworkManager/system-connections/

Finally we’re ready to “chroot” into our new system.

mount --rbind /dev  /mnt/install/dev
mount --rbind /proc /mnt/install/proc
mount --rbind /sys  /mnt/install/sys
chroot /mnt/install \
    /usr/bin/env DISK=$DISK HOST=$HOST USER=$USER \
    bash --login

Let’s not forget to setup locale and time zone.

locale-gen --purge "en_US.UTF-8"
update-locale LANG=en_US.UTF-8 LANGUAGE=en_US
dpkg-reconfigure --frontend noninteractive locales

dpkg-reconfigure tzdata

Now we’re ready to onboard the latest Linux image.

apt update
apt install --yes --no-install-recommends linux-image-generic linux-headers-generic

Followed by boot environment packages.

apt install --yes initramfs-tools cryptsetup keyutils grub-efi-amd64-signed shim-signed tasksel

Since we’re dealing with encrypted data, we should auto mount it via crypttab. If there are multiple encrypted drives or partitions, keyscript really comes in handy to open them all with the same password. As it doesn’t have negative consequences, I just add it even for a single disk setup.

echo "${HOST^} UUID=$(blkid -s UUID -o value $DISK-part3)  none \
    luks,discard,initramfs,keyscript=decrypt_keyctl" >> /etc/crypttab
cat /etc/crypttab

To mount boot and EFI partition, we need to do some fstab setup too:

echo "UUID=$(blkid -s UUID -o value /dev/mapper/${HOST^}) \
    / ext4 noatime,nofail,x-systemd.device-timeout=5s 0 1" >> /etc/fstab
echo "PARTUUID=$(blkid -s PARTUUID -o value $DISK-part2) \
    /boot ext4 noatime,nofail,x-systemd.device-timeout=5s 0 1" >> /etc/fstab
echo "PARTUUID=$(blkid -s PARTUUID -o value $DISK-part1) \
    /boot/efi vfat noatime,nofail,x-systemd.device-timeout=5s 0 1" >> /etc/fstab
cat /etc/fstab

Now we update our boot environment.

KERNEL=`ls /usr/lib/modules/ | cut -d/ -f1 | sed 's/linux-image-//'`
update-initramfs -u -k $KERNEL

Grub update is what makes EFI tick.

sed -i "s/^GRUB_CMDLINE_LINUX_DEFAULT.*/GRUB_CMDLINE_LINUX_DEFAULT=\"quiet splash \
    mem_sleep_default=deep\"/" /etc/default/grub
update-grub
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=Ubuntu \
    --recheck --no-floppy

Finally we install out GUI environment. I personally like ubuntu-desktop-minimal but you can opt for ubuntu-desktop. In any case, it’ll take a considerable amount of time.

tasksel install ubuntu-desktop-minimal

Short package upgrade will not hurt.

add-apt-repository universe
apt update ; apt dist-upgrade --yes

The only remaining task before restart is to create the user, assign a few extra groups to it, and make sure its home has correct owner.

adduser --disabled-password --gecos '' $USER
usermod -a -G adm,cdrom,dip,lpadmin,plugdev,sudo $USER
echo "$USER ALL=NOPASSWD:ALL" > /etc/sudoers.d/$USER
passwd $USER

Before finishing it up, I like to install Surface Go WiFi and backlight tracer packages. This will allow for usage of wireless once we boot into installed system and for remembering light level between plugged/unplugged states.

wget -O /tmp/surface-go-wifi_amd64.deb \
    https://www.medo64.com/download/surface-go-wifi_0.0.5_amd64.deb
apt install --yes /tmp/surface-go-wifi_amd64.deb

wget -O /tmp/backlight-tracer_amd64.deb \
    https://www.medo64.com/download/backlight-tracer_0.1.1_all.deb
apt install --yes /tmp/backlight-tracer_amd64.deb

As install is ready, we can exit our chroot environment.

exit

And unmount our disk:

umount /mnt/install/boot/efi
umount /mnt/install/boot
mount | tac | awk '/\/mnt/ {print $3}' | xargs -i{} umount -lf {}

After the reboot you should be able to enjoy your installation.

reboot

Once booted I like to setup suspend to react on power button and and to disable automatic brightness changes.

gsettings set org.gnome.settings-daemon.plugins.power button-power 'suspend'
gsettings set org.gnome.settings-daemon.plugins.power power-button-action 'suspend'
gsettings set org.gnome.settings-daemon.plugins.power ambient-enabled 'false'
gsettings set org.gnome.mutter experimental-features "['x11-randr-fractional-scaling']"

My preferred scale factor is 150% (instead of default 200%) but you’ll need to change that in settings manually.