Welcome to My Blog

欢迎光临!文章不定期更新,希望能对您有帮助 :)

2ascii:GIF 转 ASCII 动画

几个月前,我决定把自己的 github 主页换成 ascii 动画。最初我以为很简单,但找了半天也没找到合适的脚本或网站,所以就自己手搓了个并不通用的脚本,调整了很久终于有了一个比较满意的结果。 最近我想,为什么不把这个做成一个网页呢?如果有可视化的话,总比那时候慢慢调整更方便一点。所以就有了 2ascii 这个仓库。 这只是一组静态页面,所以可以在任何地方访问。不过为了方便,我在这里托管了一个页面。 我对 JS 并不熟悉,但是 LLM Agent 很好的弥补了这一点。作为一个小品级项目,LLM 还是够用的。

六月 25, 2026 · 1 分钟 · 16 字 · Wokron

io_uring Internals

最近做的一份幻灯片,介绍了 io_uring 的一些内部实现。 点击上方幻灯片以控制播放,或点此直接打开。

六月 25, 2026 · 1 分钟 · 4 字 · Wokron

Condy 性能实测:零开销抽象全面释放 io_uring 性能

Condy 是一款基于 io_uring 的零开销、高性能协程运行时,专为 Linux 系统设计。它持续跟进内核 io_uring 的最新特性,充分发挥底层异步 IO 的极致性能。Condy 采用 C++20 协程,提供直观易用的异步编程体验,无需回调,代码更简洁、可读性更强。我们已将 Condy 与 libaio、liburing、epoll 等底层接口,以及 Asio、Monoio、Compio 等主流异步框架进行了全面性能对比。展现了 Condy 的性能优势。 基准测试源码见 condy-bench。 测试环境: CPU:AMD Ryzen 9 7945HX with Radeon Graphics × 16 存储:SK Hynix HFS001TEJ9X115N(NVMe SSD,1TB,PCIe 4.0 x4) 编译器:clang 18.1.3 操作系统:Linux Mint 22 Cinnamon 内核:6.8.0-90-generic 基线框架: libaio:Linux 上 io_uring 之前的异步文件 IO 框架。 liburing:io_uring 本身,未与协程封装,使用上略不便。 Asio:C++ 流行的 IO 框架。 Monoio:基于 io_uring 的 Rust 协程框架(GitHub 星数高于 liburing)。 Compio:另一个基于 io_uring 的 Rust 协程框架。 顺序文件读取 我们测试了 Condy 在 8GB 文件上进行 64KB 顺序读取的性能,收集吞吐量数据,并与 libaio 和 liburing 等的基线实现进行对比。...

二月 6, 2026 · 2 分钟 · 259 字 · Wokron

构建最简 Linux 文件系统

上回说到了我们如何用 QEMU 搭建一个包含最新内核的开发环境。但试过一段时间后,我却感觉这样并不方便。 更多时候,我只需要运行单个程序(比如,单元测试)即可,而上文中所构建的完整环境却让这个过程便复杂了。本文介绍了一个更简单的方法。只需要一个简单的脚本即可构建完整运行环境。 initrd 上一篇文章中已经提到了使用 initrd 启动操作系统的方法。initrd 是一个只读文件系统镜像,内核启动时,会将镜像内容加载到内存中。程序可以像普通文件系统一样访问。 加载文件系统之后,内核会从其中寻找可用的 init 程序。因此我们只要编写合理的 init 程序,将其打包到一个 initrd 中即可。 busybox 在这种从零开始构建文件系统的场景下,使用动态库太过繁琐。因此我们直接用宿主机上的 busybox 来提供基本的程序。 准备阶段 首先创建一个 WORK_DIR 目录。此路径下的文件会被打包成文件系统镜像。 WORK_DIR=$(mktemp -d) trap "rm -rf $WORK_DIR" EXIT 之后寻找宿主机上的 busybox,将其复制到 $WORK_DIR/bin/busybox。 mkdir -p "$WORK_DIR/bin" # Copy busybox into the work directory BUSYBOX_PATH=$(which busybox) if [ -z "$BUSYBOX_PATH" ]; then echo "Error: busybox not found in PATH." exit 1 fi cp "$BUSYBOX_PATH" "$WORK_DIR/bin/busybox" 创建 $WORK_DIR/init 脚本,赋予其可执行权限。内核在启动中会识别并执行该脚本。 # Create init script cat << 'EOF' > "$WORK_DIR/init" #!...

一月 22, 2026 · 2 分钟 · 287 字 · Wokron

在 QEMU 上运行最新内核

最近,我的业余时间都花在了一个和系统编程有关的项目上。不久之后我遇到了一个问题:想要使用最新版本内核的特性并不是一件十分容易的事。发行版大多滞后于最新的内核版本,而我又不是那样激进的人,想要冒险在自己唯一的这台 Linux 电脑上升级内核(使用 installkernel 命令)。所以我需要一个办法,在保证我的系统安全的情况下,搭建一个具有新版本内核的开发环境。 这种情况容器帮不了我,虚拟机则是一个好选择。 我曾经写过一个简单的 QEMU 介绍。但实际上我对 QEMU 的了解也仅限于那篇文章的内容了。探索本文的内容花了我一些时间。在这个过程中,我也发现网上的相关内容要么包含了未充分说明的脚本,要么存在许多冗余选项。我觉得在此处以一个简单、充分解释的方式记录这一过程似乎是有意义的。 当然,从编译内核开始 如果你只需要一个能在虚拟机里运行的内核,不需要深度定制的话,那么编译内核其实很简单。这里有一个简单的教程,不过我们接下来要做的还要更简单。 首先,你要下载内核源码。如果不需要修改源码的话,从 kernel.org 下载是最方便的。这里下载了编写本文时的 stable 版本(6.17.9)。 wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.17.9.tar.xz tar -xf linux-6.17.9.tar.xz cd ./linux-6.17.9 之后,配置编译选项。这将创建编译配置文件 .config make defconfig make kvm_guest.config 前一条命令选择使用默认编译配置。第二条命令在默认配置基础上设置编译选项,使编译后的镜像可以作为 kvm 上的虚拟机运行。如果有其他需求,可以在此基础上继续配置。 之后直接编译即可。由于只包含了作为虚拟机运行的最小配置,不需要编译驱动程序,这一过程应该很快。在我的笔记本上只用了一分钟。 make -j $(nproc) 编译后的内核镜像位于 arch/x86/boot/bzImage。当然,是 x86 架构。 file arch/x86/boot/bzImage # arch/x86/boot/bzImage: Linux kernel x86 boot executable bzImage, version 6.17.9 (wokron@wokron-navi) #2 SMP PREEMPT_DYNAMIC Sun Nov 30 12:34:56 CST 2025, RO-rootFS, swap_dev 0XD, Normal VGA 准备根文件系统 简易根文件系统 这一点和我之前有关容器的文章中的内容类似。如果不考虑实际可用性,我们现在就可以运行一个内核了。...

十一月 29, 2025 · 4 分钟 · 655 字 · Wokron

用 Namespace 手搓一个容器

容器技术由 Linux 下三项技术构成。这三项技术分别是 Namespace、Cgroups 和 Unionfs。他们分别实现了系统逻辑资源的隔离、物理资源的限制以及容器的文件系统。 在这之中最为关键的是 Namespace。因为 Namespace 实现了虚拟化中最重要的隔离的功能。在 Namespace 之外即使不使用 Cgroups,用其他文件系统替代 Unionfs,依然能够实现一个容器的许多功能。 所以本文我们尝试用 Namespace 构建一个简单的容器。让我们首先想想,一个容器中的环境究竟需要与 host 隔离哪些资源。(请把容器想象成 host 之外的另一台机器。) 文件系统:容器中的进程不能访问 host 的文件系统。这意味着挂载点的隔离 – Mount Namespace 进程空间:容器中的进程无法查看容器外的进程信息。这意味着进程号的隔离 – PID Namespace 网络接口:容器中的进程拥有自己的网络接口,不使用 host 上的网络接口。这意味着网络的隔离 – Network Namespace 用户:容器中的用户和容器外的用户无关,例如容器内的 root 和容器外的 root 并不相同。这意味着用户的隔离 – User Namespace 物理资源:容器能够看到和管理的物理资源和容器外的资源不同。这意味着 Cgroups 视图的隔离 – Cgroups Namespace 时间:容器中的时间系统和容器外的时间不一定相同 – Time Namespace 主机名:容器中的主机名和容器外的主机名不一定相同 – UTS Namespace IPC:IPC,例如 Posix 消息队列,使用类似文件名的标识符,但是又并不真正存在于文件系统中。容器中的这些标识符和容器外的相同标识无关 – IPC Namespace 虽然种类很多,但是想要形成虚拟化的错觉只需要用到其中的一部分即可。为了构建我们的容器,我们选择只使用 Mount、PID 和 User。 隔离文件系统 容器化最重要的是隔离文件系统。所谓的程序运行环境,本质上就是文件系统中的各类库和应用程序。同一主机上的不同发行版的容器都运行在相同的内核上,他们只是在库和应用程序上存在不同。...

十月 13, 2025 · 6 分钟 · 1074 字 · Wokron