UP | HOME

blog

Universal print macro   debug c kernel linux

[2021-01-20 Wed]

No matter all the fancy debugging facilities in the Linux Kernel: kdb, kgdb, kprobes, etc (the list seems almost endless), I always end up printk'ing my way out of a problem as a first resort. However when the problem is connected to input supplied from user space through a syscall, you might want to debug both sides of the equation. Having different macros handle this is a true pain in the neck, so this is a quick macro test I came up with. Simply write this into its own header file and include it anywhere.

#ifndef _MYDBG_H_
#define _MYDBG_H_

#if !defined(__KERNEL__) && defined(MY_DEBUG)
#include <stdio.h>
#define mydbg(fmt, ...) printf("mydbg (%s:%d): "fmt, __func__, __LINE__, ##__VA_ARGS__)
#elif defined(__KERNEL__) && defined(MY_DEBUG)
#define mydbg(fmt, ...) pr_err("mydbg (%s:%d): "fmt, __func__, __LINE__, ##__VA_ARGS__)
#else
#define mydbg(fmt, ...)
#endif

#endif  /* _MYDBG_H_ */

Enable or disable it with

#define MY_DEBUG 1

Chinese input in emacs   emacs chinese im

[2021-01-20 Wed]

I often find myself reading or translating chinese texts on emacs, because of the quick and comfy access to translation functions through one of its many user-contributed packages. You can interface with Youdao, Google DeepL translators in a single keystroke. However, input method support is a bit of a messy business to get round to, so I thought I might outline what I did to get fcitx to run on Emacs through a Bash script.

#!/usr/bin/bash

# sane defaults
set -e              # exit if non-zero status
set -x              # show commands about to be executed
set -o pipefail     # pipe will return non zero if it fails
set -u              # treat unset variables as an error

SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"

emacscfgdir=~/usr/src/emacs/emacscfg/

export LC_CTYPE=zh_CN.utf8
export QT_IM_MODULE=fcitx
export GTK_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx

# emacs client isn't enough, we need to run a whole instance

cd $emacscfgdir
/usr/bin/emacs -q -l init.el --eval "(progn (load-theme 'cyberpunk t) (telega))" &

This should be enough for running an Emacs session with fcitx IM support, and also picking a customised skin and running Telega right after booting, so that I can tell it apart from other emacs sessions where I'm not interested in Chinese input.

One thing I've noticed though is that some keystrokes do not properly work when set up this way, something perhaps worth mentioning in the emacs-devel mailing list.

Relocating the Interrupt Vector on an RBP   rbp baremetal devicedrivers

[2021-01-18 Mon]

A lot of otherwise excellent baremetal tutorials and repositories for the Raspberrypi suggest the ghastly idea of loading the binaries onto the board by manually writing them into the sdcard for the boot sequence to pick them up as the default kern7.img file. This is an awful way for two reasons: sdcards have a limited number of writes, and also you'll end up hating it. Any time you make a tiny modification to the code, you have to pull out the sdcard, mount it locally on your development machine, copy the file, unmount, insert it back into the rbp, rinse, repeat and lose your patience.

The proper way to do this is using U-Boot as the default bootloader, then loading the binary over the serial line or preferably Ethernet with a TFTP server listening on your development machine. This is all fine until you decide you want to tinker about with RBP Interrupts. The actual reason is U-Boot code is changing the default location of the Interrupt Vector, so one of the very first things we must do in our startup code is moving it back to memory location 0x00:

/* Change location of IVT back to 0x00 */
orr r3, r3, #CPSR_MODE_SVC | CPSR_MODE_IRQ_DISABLE | CPSR_MODE_FIQ_DISABLE
msr cpsr_c, r3          /* Set the control (mode) bits */
mov r3, #0x00
mcr p15, 0, r3, c12, c0, 0

After this we can confidently install the IRQ table starting from 0x00 in our boilerplate code before jumping to the first C source function.

Sharing self-hosted pictures on IRC   irc sh convenience

[2021-01-18 Mon]

I've been using Telegram for quite sometime but I'm reluctant to give up on IRC altogether. However one of the features I miss most dearly is the ability to quickly share pictures and videos with other users. Telegram accomplishes this by inlining them in the chat window, and storing them on their cloud servers. This not good, though. As a quick throw-in replacement, I wrote a bash script that takes an image filename as an argument, copies it over ssh to a public folder on my personal web server's htdocs with a randomly generated temporary filename, and finally saves the matching URL into my clipboard so that I can readily share it with other people in an IRC channel.

Here's the beast:

cpw () {
    shrmnt= # share mount point
    imgdir=${shrmnt} # your htdocs
    filename="${1}"
    filename=$(basename "${filename}")

    if [[ ! -e $filename ]]; then
        echo "File does not exist"
        return 1
    fi

    # check mountpoint exists before copying the file
    if ! mount | grep -q "${shrmnt}"; then
        echo "Pi mount point isn't enabled"
        return 1
    fi

    tmppath=$(mktemp)
    tmpfile=$(basename "${tmppath}")
    rm "${tmppath}"             # remove just created temp file
    tmpfilename=${tmpfile##*.}

    cp "${filename}" "${imgdir}"/"${tmpfilename}.jpg"

    url="https://www.yourdomain.whatever/share/${tmpfilename}.jpg"

    echo ${url} | xclip
}