It’s been a while since the last Status Update on November 2020 so I thought it would be good to have a catch-up post. Be prepared, this is going to be a long one. After all, I haven’t done one of these in 120 days.

Development environment

There has been one small change to my development environment. I’ve gotten a CLion license. I’m planning to play around with it for a while to see if it improves my C++ workflow.

DSP / Radio

There has been some good progress on signal processing and radio-related projects since the last status update.

Frequency-hopping spread spectrum (FHSS)

I made a modulator for a frequency-hopping signal, and wrote receiver plugins for SDR Sharp and GQRX. The modulator changes the frequency of transmission based on the hash of the current time, and hops frequencies 10 times a second. It is able to be received and demodulated without problems.

It is possible to share the same frequencies between multiple transmitters, as their collisions are not very common. This modulation is good at avoiding narrowband noise, but it provides no processing gain to the signal as there is no correlation done. All I’ve done is transmit a narrowband FM signal with a hopping frequency.

APT image encoder fixes

There has been some improvements to my APT image modulator apt-encoder. Previously, the images created by GIMP needed to be manually edited to get rid of comments. Now the program knows how to ignore comments in image files.

Spectrogram drawing

I wrote a modulator that can transmit image files using the HackRF One. It can draw simple pictures on the spectrogram. The height and width of the transmitted image, which translate to the transmission speed and the bandwidth, can be configured.

I have written an article about it here.

Signal correlation

I started learning how to do signal correlation in order to get processing gain from spread-spectrum signals. I haven’t written a full modulator/demodulator yet, but I have tested locally with Python and things are looking promising.

Kernel / OSDev

There has been some kernel development in February. Below are the main points. As always, the kernel source code can be found in gkbrk/kernel.

Threading improvements

From the first days of multi-processing in the kernel, it was not possible to pass any data when spawning threads. You could pass a function pointer and communicate with the thread using shared memory. Thanks to some changes in the Task class, it is now possible to push and pop arbitrary objects to the stack of the process.

The first thing I did after implementing this is to make the music player fork to another process so it can play in the background while you are dropped back in the command prompt.

Improved PS/2 driver

One of the first drivers we implemented was a polling keyboard reader. We now replaced this with a proper PS/2 driver that handles keyboard and mouse events. Yes, we also support PS/2 mouse now.

A driver for the “mouse integration” that is common in VM emulation software was also implemented, so we can seamlessly use the mouse in the kernel now.

RNG and entropy pool

The only method of generating random numbers in the kernel was a simple LCG PRNG. This made the random number quality bad, and (most importantly) not suitable for anything that needs to be secure.

We now have a system that can collect and extract entropy from kernel events and CPU interrupts. This means anything that depends on external input, such as keyboard and mouse events, and hard drive access patterns, now contribute to a “system entropy pool”.

For now, the only output is the occasional line on the debug console with a random byte. In the future, I am planning to add a sponge function that will collect entropy and produce arbitrary amounts of randomness.

Build system

We were using Ninja as the build system for some time, but recently I switched the ./configure script to emit Makefile syntax again. This was mostly done to integrate better with tooling and to get rid of a build dependency.

We also hash the output file names and put them all in a flat build directory. This makes it easier to clean the project, and allows us to reuse file names without having a nested build folder.

When using the ./mach command to build, all the subcommands still work the same so there are no changes.

Blog comments

I used to have a comment system that used CGI scripts to collect, process, filter and display comments. It required JavaScript for fetching and displaying the comments. At some point, I migrated servers and never bothered to set up comments again.

I decided to fix that, so now we have comments again. And guess what, they even work without JavaScript now. I am using Paul Graham’s spam filtering algorithm, which seems to be doing a great job so far.

Android application template

I wrote a small template for an Android application that displays a web page in a webview while exposing some useful APIs over the JavaScript bridge. It can be compiled and packaged entirely from the command-line, avoiding the Android Studio bloat.

Small utilities

bencode2json

I wrote a small utility called bencode2json to convert bencoded data to JSON. This is useful to me because I end up using bencode a lot when prototyping network protocols, but I don’t feel like rewriting jq for bencode.

Since I wanted to use this utility for external data from the network, I wanted to make sure it wouldn’t be able to do anything bad to my system. To this end, I learned about how to use seccomp to sandbox a Linux process. For better security and for a small challenge, I used the strict mode which only lets the process call read, write, exit and sigreturn. This pretty much eliminates almost all attack vectors.

LZ77 Compression / Decompression utility

In order to understand compression algorithms better, I decided to write a worse version of a common compression algorithm called LZ77.

The version I wrote keeps a 255-byte window in order to use only a single byte for the length values. Due to the very small window size, it is only able to achieve a 90% compression ratio on plaintext.

I am planning to play around with different algorithms and larger window sizes in the future.

Container runtime script

In order have more reproducible build without messing around with build environments and configurations, I wrote a shell script that uses systemd-nspawn to start and interact with temporary Linux containers. I decided to call this script runcontainer.sh, you can find it on my github.