跳转至

博客

把博客生成器从 Hugo 迁移到 Mkdocs

距离上一次 Jekyll 迁移到 Hugo 已经过去了四年,这次正好 mkdocs-material 发了新的 beta 版本,加入了对博客的支持,所以就当小白鼠,把博客迁移到了 Mkdocs + Mkdocs-Material。

这次迁移比较顺利,除了 tag 和 category 少了一些页面以外,原来的文章的链接都是正常的。为什么要迁移呢,主要是最近写各种文档,Mkdocs 用的比较多,但是 Mkdocs 的 Markdown 很多地方和 Hugo 不太一样,下面列一些最难以忍受的 Hugo 的问题:

  1. 数学公式:Hugo 的 \ 需要转义,导致很多地方写数学公式都很麻烦,然后因为我经常要在 Hugo 和 Mkdocs 之间复制 Markdown,此时就需要很多手动工作。
  2. 资源路径:Hugo 的资源路径默认都是绝对路径,要引用其他文章的话,要么用啰嗦的 relref,要么就写绝对路径,比较头疼。Mkdocs 就很好,自动检测,帮我计算出实际的地址。

迁移的时候有很多细节上的不同,不过基本靠 VSCode 的正则表达式替换解决了。

不过,Mkdocs 又出现了 Jekyll 的老问题,就是性能比较差。当然了,不一定是 Mkdocs 本身的问题,也可能是 Mkdocs-Material 加各种插件的问题,目前还有待观察。无论如何,Python 调起来总归是比 Ruby 要容易。希望不要在未来的某一天,由从 Mkdocs 迁移回 Hugo。

ECDSA

ECDSA 是一个基于椭圆曲线的签名算法,使用时需要确定一个椭圆曲线,以及它的 base point \(G\),且 \(G\) 的阶是素数 \(n\)。ECDSA 支持如下的操作:

  1. 生成签名
  2. 验证签名
  3. 从签名和明文推导出公钥

生成树协议

本文的内容已经整合到知识库中。

Spanning Tree Protocol

STP(Spanning Tree Protocol)可以在 802.1D-1998 第 8 章中找到。STP 协议工作在交换机上,需要根据交换机连接的拓扑,自动计算出一个生成树,并且把不在生成树上的边禁用,这样即使连接的拓扑有环路,禁用以后就没有环了。有了 STP 以后,连接交换机的时候就可以刻意连成环,从而提供冗余。

从 libvirtd 迁移到 Proxmox VE

背景

之前用 libvirtd + virt-manager 做 Linux 上的虚拟化,好处是比较轻量级,但是远程控制起来比较麻烦,要么通过 RDP 访问 virt-manager 的 UI,要么就用 cockpit 在网页里去配置虚拟机。此时就会比较怀念 VMware ESXi 的网页,但是 ESXi 装完以后,宿主机就很不自由了,很多东西没法自定义。最后就想到在 Debian 上装一个 Proxmox VE,希望得到一个比较好的中间态。

LoongArch 初尝试

背景

最近应龙芯要求把监控程序移植到了 LoongArch 32 Reduced 架构上,趁此机会体验了一下 LoongArch 相关的软件和系统。

Tar 文件格式

本文的内容已经整合到知识库中。

背景

最近在解压 tar.gz 文件的时候,发现如果用 unar 解压,就会出现文件名截断到 100 个字节的问题,而如果用 gnu tar 解压,文件名就是正常的,因此深入研究了一下 Tar 的文件格式。实际上,这是因为早期 tar 格式设计的时候,就设定了路径最长 100 字节的限制,后来的扩展解决了这个问题,但是 unar 没能正确地识别扩展,导致解压路径出错。

使用 Docker 部署 OpenLDAP

OpenLDAP 是一个开源的用户系统实现,主要支持 LDAP 协议,可以给其他系统提供用户认证。下面讨论了如何在 Docker 中部署 OpenLDAP。

链接器的工作原理

背景

最近和同学讨论一些比较复杂的链接问题,遇到一些比较复杂的情况,因此复习一遍链接器的工作原理,在这里总结工作原理和常见的问题。

How a Linux 6.2.13 BUG stops Vivado from recognizing FPGA

中文版本

TLDR

In short, the commit introduced by Linux 6.2.13:

commit 0d30989fe9a176565d360376d4bc2ea1c61cbbac
Author: Liam R. Howlett <Liam.Howlett@oracle.com>
Date:   Fri Apr 14 14:59:19 2023 -0400

    mm/mmap: regression fix for unmapped_area{_topdown}

    commit 58c5d0d6d522112577c7eeb71d382ea642ed7be4 upstream.

    The maple tree limits the gap returned to a window that specifically fits
    what was asked.  This may not be optimal in the case of switching search
    directions or a gap that does not satisfy the requested space for other
    reasons.  Fix the search by retrying the operation and limiting the search
    window in the rare occasion that a conflict occurs.

    Link: https://lkml.kernel.org/r/20230414185919.4175572-1-Liam.Howlett@oracle.com
    Fixes: 3499a13168da ("mm/mmap: use maple tree for unmapped_area{_topdown}")
    Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
    Reported-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

While fixing a BUG, a new BUG is introduced, causing MAP_32BIT to fail to work sometimes, and Xilinx's Digilent driver uses this parameter, causing mmap to fail and unable to recognize the FPGA.

The new BUG has been fixed in [PATCH v2] maple_tree: Make maple state reusable after mas_empty_area().

Linux 6.2.13 引入的 BUG 导致 Vivado 无法识别 FPGA

English version

TLDR

简单来说,Linux 6.2.13 引入的 commit:

commit 0d30989fe9a176565d360376d4bc2ea1c61cbbac
Author: Liam R. Howlett <Liam.Howlett@oracle.com>
Date:   Fri Apr 14 14:59:19 2023 -0400

    mm/mmap: regression fix for unmapped_area{_topdown}

    commit 58c5d0d6d522112577c7eeb71d382ea642ed7be4 upstream.

    The maple tree limits the gap returned to a window that specifically fits
    what was asked.  This may not be optimal in the case of switching search
    directions or a gap that does not satisfy the requested space for other
    reasons.  Fix the search by retrying the operation and limiting the search
    window in the rare occasion that a conflict occurs.

    Link: https://lkml.kernel.org/r/20230414185919.4175572-1-Liam.Howlett@oracle.com
    Fixes: 3499a13168da ("mm/mmap: use maple tree for unmapped_area{_topdown}")
    Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
    Reported-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

修复了 BUG 的同时,引入了新的 BUG,导致 MAP_32BIT 有时无法工作,而 Xilinx 的 Digilent 下载器代码使用了这个参数,导致 mmap 失败,无法识别 FPGA。

新 BUG 在 [PATCH v2] maple_tree: Make maple state reusable after mas_empty_area() 中被修复。

I2C 协议

本文的内容已经整合到知识库中。

背景

最近数设课上,同学们开始购买外设,其中就涉及到 I2C 协议,因此顺带写一下 I2C 协议的教程,帮助同学们进行理解。

接口

I2C 协议涉及到两个信号:

  • SCL: 时钟信号,Master -> Slave
  • SDA:数据信号,Master <-> Slave

SPI 协议

本文的内容已经整合到知识库中。

背景

最近数设课上,同学们开始购买外设,其中就涉及到 SPI 协议,因此顺带写一下 SPI 协议的教程,帮助同学们进行理解。

接口

SPI 协议涉及到四个信号:

  • SCLK: 时钟信号,Master -> Slave
  • MOSI:数据信号,Master -> Slave
  • MISO:数据信号,Slave -> Master
  • CS:芯片使能,一般是低有效

在 LiteX 中使用 UART over JTAG

背景

在给 Alinx AX7021 适配 LiteX 的时候,遇到一个问题:PL 上没有连接串口,只有 PS 连接了串口,如果用 RISC-V 软核的话,就会面临无串口可用的情况,除非在扩展 IO 上自己定义一个串口。

因此研究了一下 LiteX 自带的 UART over JTAG 功能,在 Alinx AX7021 中调试出来了。

DRAM 的拓扑和训练

本文的内容已经整合到知识库中。

DRAM Training

DRAM 一直有一个比较麻烦的初始化过程,就是 DRAM Training,其中很重要的一步就是计算出各个数据线相对于时钟的偏移(skew)。这个偏移是怎么来的呢?

我们知道,对于 SRAM,如果想要更多的位宽,只需要把地址线和控制信号连接到多个 SRAM 上,然后把 SRAM 的数据信号并行连接到 FPGA 上就可以了,但是前提是要尽量保证等长,否则一样有偏移的问题。DRAM 也是采用类似的方法进行扩展的,但是 DRAM 通常需要并行连接很多个芯片,例如 8 个 x8 的芯片的合并成一个 64 位的 DDR SDRAM。此时数据线依然是并行连接,但是地址线和控制信号就出现了走线困难:很难在那么小的空间里,等长地把地址和控制信号分布到各个芯片上,而且还有信号完整性的问题。

C/C++ 数参数个数的特别方法

背景

群友上个月提了一个未知来源问题:

实现一个你自己的 printf(int, ...) 函数,该函数包含可变参数。为简便期间,假设所有参数均为 int 类型。

  1. 第一个参数是一个普通参数,不表示后续可变参数的数目
  2. 在 printf 中逐个输出所有传入的整数值(可使用系统自带的 kprintf 实现输出)
  3. 思考如何判定参数结束,是否有副作用

UnixWare 7.1.4 虚拟机安装

安装过程

https://www.sco.com/support/update/download/product.php?pfid=1&prid=6 可以看到 UnixWare 7.1.4 的相关下载,其中首先要下载 UnixWare 的安装 ISO:https://www.sco.com/support/update/download/release.php?rid=346,尝试过用 QEMU 启动,会遇到找不到 CD-ROM 的问题,虽然通过设置 ATAPI_DMA_DISABLE=YES 解决了,但是又遇到了找不到硬盘的问题。

最后换成了 VirtualBox 7.0.6。用 VirtualBox 创建虚拟机的时候,不要给太多内存,4GB 就会无法启动,2GB 可以,硬盘也不要给太多,4GB 就足够。

AIX 7.2 虚拟机安装

安装过程

宿主机环境是 Debian bookworm,不需要像其他教程那样自己编译 qemu,直接 apt install 即可。

通过 google 可以搜索到 AIX 7.2 的 ISO,下载第一个 ISO 到本地,然后在 QEMU 中启动安装镜像:

RAM 读写冲突

背景

在 FPGA 或者 ASIC 中,通常都需要使用 RAM,通过读口、写口或者读写口来进行访问。常见的配置有单读写口(1RW),一读一写(1R1W)等等,读口通常有 1 个周期的延时。那么,如果在同一个周期内,读口和写口访问了同一个地址,会发生什么呢?可能会想到几种情况:

  1. 读和写都失败,读出的数据未定义,数据没写进去
  2. 数据写进去了,读出的数据未定义
  3. 数据写进去了,读出了写之前的旧数据
  4. 数据写进去了,读出了同一个周期写入的新数据

firtool 尝试

背景

Chisel 3.6 很快就要发布了(目前最新版本是 3.6.0-RC2),这个大版本的主要更新内容就是引入了 CIRCT 的 firtool 作为 FIRRTL 到 Verilog 的转换流程:

The primary change in Chisel v3.6.0 is the transition from the Scala FIRRTL
Compiler to the new MLIR FIRRTL Compiler. This will have a minimal impact on
typical Chisel user APIs but a large impact on custom compiler flows. For
more information, please see the ROADMAP.

因此提前测试一下 firtool,看看其和 Scala FIRRTL Compiler 有哪些区别,是否有更好的输出。