The Cleanup Variable Attribute in GCC

C++ has a powerful idiom called RAII (Resource Acquisition Is Initialization)[^1], although the name might leave something to be desired. The fundamental idea is to represent a resource by a local object, tying the resource’s lifecycle to the lifecycle of the local object’ lifecycle. In other words, we could say the local object is the owner of the resource (Hmm, I smell something rusty here). The local object is responsible for releasing the resource in its destructor.

Linux Syscall Table Generator

This weekend, I worked on a script that scans through the Linux source tree and generates syscall tables for both x86 and x64 architectures. If you are interested, you can check it out in this repo. I’d like to share some notes about it. The generated tables are here: Linux x64 syscall table Linux x86 syscall table In Linux, syscalls are identified by numbers, and their parameters are in machine word size, either 32-bit or 64-bit.

传奇程序员 Andreas Kling 和他的 SerenityOS

我们今天故事的主角,是一个叫做Andreas Kling的瑞典程序员。 这个月的 9 月 12 日,Andreas 在他的个人网站上刊出了一篇文章来介绍他的Ladybird浏览器项目。浏览器大概是这个星球上最为庞大的软件项目,从零开始写出一个即便只是玩票性质的浏览器也是一项惊人困难的任务。如果你对它的难度没有直观认识的话,不妨猜一猜 Firefox 浏览器总共有多少行代码?答案是2100万行!数量庞杂(并且仍在爆炸式增加)的各种web标准使得编写浏览器几乎成了只有互联网寡头才能组织起人力和资源来完成的事情。所以,Andreas 的这个几乎以一己之力做出来的浏览器完全值得让人拍手称奇。 Figure 1: Ladybird 浏览器以满分的成绩通过了Acid3测试 事实上,在 Ladybird 项目之前,Andreas 已经完成了多项壮举,比如一个叫做SerenityOS的操作系统和一门叫做Jakt的系统级编程语言。用他自己的话说,他的目标是“从头编写一个完整的操作系统”。这些项目,不论单独拎出来哪一个,都显得过于庞大。如果这些项目的代码不是实实在在摆在大家的面前的话,我一定觉得这个人是痴人说梦。 而所有这些项目的起点,都可以追溯到 Andreas 下定决心戒除毒瘾的那个秋天。 没错,Andreas 曾经沾染毒瘾,是一名瘾君子。2018 年 10 月份,在结束了 3 个月的戒断治疗后,为了打发漫长难遣的时间,他开始疯狂地写起了代码。一开始,他完成了一个可执行文件的解析器。渐渐地,他又陆续写出来一个文件系统浏览器和一个图形界面框架。这时候 Andreas 惊奇地发现,一个简易的操作系统其实已经呼之欲出了。于是他将这若干个基础部件组合成一个操作系统,并称之为 SerenityOS。 Figure 2: 这是一款吸收了 90 年代美学理念的类 Unix 系统 这个由 Andreas 在 2018 年单枪匹马创建的项目,到现在已经蔚为大观。不同于浏览器,从头开始写出一个简单的操作系统并非难事,难的是聚拢各路牛人,形成真正有活力的社区。截至今日,该项目已经斩获了两万一千多颗 Github 星标,共有超过 700 位开发者向该项目贡献了代码。在我看来,Andreas 的这个操作系统谈不上有什么实际的用途,最多只是一个稍具规模的玩具而已。不过,不少重量级的软件都是“玩”出来的,难道不是吗?比如 Linux,这个在今天已经无处不在的操作系统(你甚至在火星上也能发现它的存在),Linux Torvalds 最初发布它的时候可没有想到有一天它竟会大放异采。 Figure 3: 图片来源:NASA 时至今日,Andreas 依然耕耘不辍,几乎全年无休。我们就以他的 Github 状态墙的截图结束本文吧,希望他能在写代码的道路上继续快乐地走下去。

TTY、终端和控制台:历史、用途和区别

在计算机的世界里,许多术语和概念是从早期的计算机技术中沿袭而来的,包括 TTY、终端和控制台。了解这三个术语的历史、用途以及区别对理解操作系统的终端和伪终端子系统很有帮助。 TTY(Teletype,中文一般翻译成电传打字机)的历史比计算机的历史更久远,可以追溯到电报机的时代。在电脑还没出现之前,人们通过这种设备进行远程信息传输1。随着时间的推进,TTY 在计算机领域中的含义演变成为一种能够在用户与计算机系统之间通过文本形式进行交互的接口。 (Hughes Telegraph,图片来源:Wikipedia) (Siemens t37h,图片来源:Wikipedia) 终端(Terminal)最初是指通过线路连接的物理设备,用户可以通过键盘输入并从屏幕读取信息。在大型机时代,计算机不仅昂贵,还显得庞大而笨重。计算机的使用者则借助“终端设备”来连接到主机,并以命令行的方式进行交互操作。最早被用作终端设备的是电传打字机与打字机的组合,电传打字机负责输入,而打印机则将输出结果打印在纸张上。不久之后,衍生出了专门的终端设备,将电传打字机和打印机的功能合二为一。 (The IBM 2741 Terminal,图片来源:IBM) 若干年后,电子显示屏逐渐取代了打印机成了新的输出设备。我们所熟知的”物理终端“的概念指的就是这一时期的终端设备,其中比较有代表性的是德州仪器的 VT100 系列终端设备。 (DEC VT100 terminal,图片来源:Wikipedia;这个网站包罗了关于该系列终端设备的详尽资料) 随着时间的推移,我们进入到了计算机时代。小型机的性能已经足够强大,使得人们无需再依赖专门的终端设备来分时使用大型机。虽然专用的终端设备被时代淘汰掉,但终端作为“使用文本进行人机交互的用户界面”的概念却延续了下来。在这个时代中,个人计算机不仅自身作为主机,同时也肩负起了终端设备的角色。 (AT&T UNIX PC 7300,图片来源:oldcomputers.net) 随着计算机技术的发展,终端的概念也开始扩展到软件,形成了模拟终端(Terminal Emulator),它在图形用户界面环境中模拟了物理终端的功能。我们今天广泛使用的 xterm,gnome-terminal 等软件,都属于模拟终端。 控制台(Console)是操作系统层面的抽象概念,它指的是用户用来控制操作系统行为的主接口。虽然控制台和终端这两个术语经常被互相替换使用,但它们的侧重点并不相同。更加令人困惑的是,在不同的场合,我们经常会看到各种不同的名称来指代控制台,比如终端、虚拟终端、虚拟控制台等。 我们可以把控制台理解为操作系统通向外部的桥梁:用户通过控制台向操作系统下达命令,而操作系统则会将命令的执行状态和结果反馈到控制台进行显示。在操作系统的另一边,也就是用户端,这个桥梁与一个终端设备相连,这个终端设备可以是物理设备,也可以是虚拟设备。又因为最早使用的终端设备是电传打字机,所以在 Unix 系统中的终端子系统又被称为 TTY 子系统。 以上就是 TTY、终端和控制台这三个术语的历史渊源及其概念性的差异。在后续的一篇文章中,我将深入探讨这三个术语在 Linux 语境下的具体含义和应用。 Royal Earl House Invents a Telegraph that Composes and Prints in Roman Characters Rather than in Code ↩︎

Setting Up a Development Machine

Just a few days ago, I completed a home server build. Today I decided to have a clean OS reinstallation on my development machine due to several reasons:

  • Firstly, the root partition on this machine is nearing full capacity (thank you, my past self).
  • Secondly, I’m consistently encountering __common_interrupt: 1.55 No irq handler for vector errors during system bootup. There’s a thread in the Arch Forum discussing this issue. Despite my efforts to resolve it through various ombinations of kernel parameters as suggested in the thread, I have not succeeded. It appears that the only viable solution is a BIOS firmware upgrade.
  • Finally, there exists a paradoxical issue: I cannot decrypt the root partition without using my bluetooth keyboard, yet I cannot use my bluetooth keyboard until the root partition is decrypted and mounted (because the bluetooth driver sits in the root partition). This presents a typical chicken and egg problem. My current hack around is to use a wired USB keyboard to decrypt the root parition. However, I desperately want to abandon this workaround.

/img/keyboard-not-found-press-any-key.png

Setting Up a Home Server

Recently, I came into possession of an old computer. Instead of letting it gather dust in the corner, I thought it would be a good idea to repurpose it as a home server. Primarily, I wanted a Samba Server, but I may go further to run other self-hosted services like NextCloud.

In this article I’ll walk through my home server setup process.

Smallest Root Filesystem for Linux

The Linux kernel works hand in hand with what is called the root filesystem. This is the filesystem which will be mounted to the root directory and where the user space applications are located. How tiny can a root filesystem be, while still remaining functional? By functional, I mean it is capable of letting the kernel finish its booting process and pass control to user space without causing a kernel panic.

A Terraform Module to List Google Cloud Service Agents

Google Cloud Platform presents two distinct types of service accounts: user-managed service accounts and Google-managed service accounts. The former is typically employed by user applications as an interface with Google Cloud, whereas the latter is utilized internally by Google Cloud. Within the realm of Google-managed service accounts, a specialized subset exists: Google Cloud Service Agents. These service agents are used by Google Cloud services to operate internal processes necessary to fulfill user-requested operations.

A service agent adhers to the following template:

service-PROJECT_NUMBER@SERVICE_NAME.iam.gserviceaccount.com

These service agents are easily identifiable within the IAM section of the Google Cloud Console.

/img/20200402-0012.png

During the management of IAM binding policies via Terraform, these service agents can often become obtrusive. For illustration, consider the following code snippet from one of our Terraform files (where xxxxx substitutes the actual project number).

Debugging the Linux Kernel with QEMU and GDB

In the previous article, we explored how to run a raw Linux kernel in QEMU. Another fascinating feature that QEMU provides is to initiate a GDB server. An external GDB debugger can then connect to it. This means that we can suspend the kernel running at any point of the kernel startup. By leveraging this feature, we can construct an efficient environment to debug system kernels and firmware. In this guide, we will explore the process of using this feature to debug the Linux kernel.

Publishing Subdirectory to Github Pages

I’m using Hugo + Github Pages as my personal blog platform. A Hugo site yields the following directory structure, where the public/ subdirectory stores the generated static pages:

├── archetypes/
├── config.toml
├── content/
├── data/
├── layouts/
├── public/
├── resources/
├── static/
└── themes/

How do I publish the public/ subdirectory, instead of the root directory, to Github Pages?