Ryzen 系列 Ryzen 5000 代号 用途 核显 插槽 微架构 型号 Vermeer 桌面 无 AM4 Zen 3 5950X/5900(X)/5800(X(3D))/5700X/5600(X) Chagall 工作站 无 sWRX8 Zen 3 5995WX/5975WX/5965WX/5955WX/5945WX Cezanne 桌面 GCN5 AM4 Zen 3 5750G/5700G(E)/5650G/5600G(E)/5500/5300G(E) Cezanne 笔记本 GCN5 FP6 Zen 3 5980HX/5980HS/5900HX/5900HS/5800H(S)/5800U/5600H(S)/5600U/5560U/5400U Barceló 笔记本 GCN5 FP6 Zen 3 5825U/5825C/5625U/5625C/5425U/5425C/5125C Lucienne 笔记本 GCN5 FP6 Zen 2 5700U/5500U/5300U 注:Ryzen 5 5500 虽然代号是 Cezanne,但是去掉了核显。 Ryzen 6000 代号 用途 核显 插槽 微架构 型号 Rembrandt 笔记本 RDNA2 FP7 Zen 3+ 6980HX/6980HS/6900HX/6900HS/6800H(S)/6800U/6600H(S)/6600U Ryzen 7000 代号 用途 核显 插槽 微架构 型号 Raphael 桌面 RDNA2 AM5 Zen 4 7950X(3D)/7900(X(3D))/7800X3D/7700(X)/7600(X) Dragon Range 笔记本 RDNA2 FL1 Zen 4 7945HX/7845HX/7745HX/7645HX Phoenix 笔记本 RDNA3 FP7/FP7r2/FP8 Zen 4 7940HS/7840HS/7640HS Rembrandt R 笔记本 RDNA2 FP7 Zen 3+ 7735HS/7535HS/7736U/7735U/7535U/7335U Barcelo R 笔记本 GCN5?
PCIe Bifurcation
本文的内容已经整合到知识库中。 背景 最近看到两篇关于 PCIe Bifurcation 的文章: intel 部分桌面级 CPU 的 pcie 通道拆分另类低成本实现 Intel Alder Lake 12 代酷睿 CPU PCIe 拆分实现方法 文章讲的是如何在 CPU 上进行跳线,从而实现 PCIe Bifurcation 的配置。正好借此机会来研究一下 PCIe Bifurcation。 PCIe Bifurcation PCIe Bifurcation 的目的是让 PCIe 有更好的灵活性。从 CPU 出来的几路 PCIe,它的宽度一般是确定的,比如有一个 x16,但是实际使用的时候,想要接多个设备,例如把 x16 当成两个 x8 来用,这就是 PCIe Bifurcation。这需要 PCIe 两端的支持,CPU 端需要可配置 PCIe Bifurcation,不然只能从一个 x16 降级到一个 x8,剩下的 8x 就没法利用了;设备端需要拆分卡,把 x16 的信号分成两路,然后提供两个 PCIe 插槽以及使用 Clock Buffer 来提供下游设备的时钟,有时则是主板设计时就做了拆分,不需要额外的拆分卡。 那么怎么配置 CPU 端的 PCIe Bifurcation 呢?其实就是上面两篇文章提到的办法:CPU 根据 CFG 信号来决定 PCIe Bifurcation 配置,例如要选择 1x16,2x8 还是 1x8+2x4 等等。简单总结一下实现思路都是:
ACPI 学习笔记
标准 ACPI 标准可以从官网下载。 ACPI 的表现形式为一颗树加若干个表,表的结构比较规整,里面每个字段都有固定的含义。树的结点可能是属性,或者是一些函数。操作系统可以操作上面的属性,调用 ACPI 中的函数,来进行一些硬件相关的操作。ACPI 一般与主板密切相关,主板厂家配置好 ACPI 后,操作系统就不需要给每个主板都写一遍代码了。 ASL 为了开发 ACPI,需要使用 ACPI Source Language(ASL) 来进行编程,使用 iasl 编译成 ACPI 表以后,由操作系统进行解释执行。推荐阅读一个比较好的 ASL 教程:ACPI Source Language (ASL) Tutorial。 简单来说,ASL 中的变量类型: Integer: int32_t/int64_t String: char * Buffer: uint8_t [] Package: object [] Object Reference: object & Method ACPI 需要访问硬件,一般是通过 MMIO 或者 IO Port 来进行访问。在内核开发的时候,MMIO 一般是用一系列 volatile 指针来对应硬件的寄存器定义。ASL 中也可以做类似的事情,分为两步:OperationRegion 和 Field。 OperationRegion 就是声明了一片地址空间,以及对应的类型,常见的类型有 SystemMemory、SystemIO、PCI_Config、SMBus 等等。当 ACPI 中的代码要访问 OperationRegion 中的数据的时候,内核按照类型去进行实际的访问。 有了地址空间以后,还需要根据寄存器的定义,给各个字段起个名字,这就是 Field。Field 给 OperationRegion 中的字段起名,与硬件的定义想对应,这就像在内核中定义一个结构体,保证结构体的成员的偏移和硬件是一致的。这样就可以通过成员来访问,而不是每次都去计算一次偏移。
InfiniBand 学习笔记
本文的内容已经整合到知识库中。 参考文献 Infiniband Architecture Overview InfiniBand Architecture Specification Volume 1 Release 1.2.1 InfiniBand Architecture Specification Volume 2 Release 1.4 An Introduction to the InfiniBand Architecture InfiniBand Network Architecture - MindShare ArchWiki - InfiniBand 概览 InfiniBand 的网络分为两层,第一层是由 End Node 和 Switch 组成的 Subnet,第二层是由 Router 连接起来的若干个 Subnet。有点类似以太网以及 IP 的关系,同一个二层内通过 MAC 地址转发,三层间通过 IP 地址转发。 在 IB 网络中,End Node 一般是插在结点上的 IB 卡(Host Channel Adapter,HCA)或者是存储结点上的 Target Channel Adapter。End Node 之间通过 Switch 连接成一个 Subnet,由 Subnet Manager 给每个 Node 和 Switch 分配 Local ID,同一个 Subnet 中通过 LID(Local ID)来路由。但是 LID 位数有限,为了进一步扩展,可以用 Router 连接多个 Subnet,此时要通过 GID(Global ID)来路由。
升级 Mellanox 网卡固件
背景 最近发现有一台机器,插上 ConnectX-4 IB 网卡后,内核模块可以识别到设备,但是无法使用,现象是 ibstat 等命令都看不到设备。降级 OFED 从 5.8 到 5.4 以后问题消失,所以认为可能是新的 OFED 与比较旧的固件版本有兼容性问题,所以尝试升级网卡固件。升级以后,问题就消失了。 安装 MFT 首先,在 https://network.nvidia.com/products/adapter-software/firmware-tools/ 下载 MFT,按照指示解压,安装后,启动 mst 服务,就可以使用 mlxfwmanager 得到网卡的型号以及固件版本: Device Type: ConnectX4 Description: Mellanox ConnectX-4 Single Port EDR PCIE Adapter LP PSID: DEL2180110032 Versions: Current FW 12.20.1820 升级固件 从 PSID 可以看到,这是 DELL OEM 版本的网卡,可以在 https://network.nvidia.com/support/firmware/dell/ 处寻找最新固件,注意需要保证 PSID 一致,可以找到这个 PSID 的 DELL 固件地址:https://www.mellanox.com/downloads/firmware/fw-ConnectX4-rel-12_28_4512-06W1HY_0JJN39_Ax-FlexBoot-3.6.203.bin.zip。 下载以后,解压,然后就可以升级固件: mlxfwmanager -u -i fw-ConnectX4-rel-12_28_4512-06W1HY_0JJN39_Ax-FlexBoot-3.6.203.bin 升级以后重启就工作了。 考虑到类似的情况之后还可能发生,顺便还升级了其他几台机器的网卡,下面是一个例子: Device Type: ConnectX4 Description: ConnectX-4 VPI adapter card; FDR IB (56Gb/s) and 40GbE; dual-port QSFP28; PCIe3.
CXL 学习笔记
本文的内容已经整合到知识库中。 背景 前段时间学习了 PCIe,趁此机会,进一步学习一下密切相关的 CXL。 CXL 的标准是公开下载的:https://www.computeexpresslink.org/download-the-specification,我目前参考的是 2022 年 8 月 1 日的 CXL 3.0 版本。 CXL 设备类型 CXL 对 PCIe 的重要的扩展,一是在于让设备可以和 CPU 实现缓存一致性(CXL.cache),二是可以做远程的内存(CXL.mem)。 具体下来,CXL 标准主要定义了三类设备: CXL Type 1: 设备带有与 CPU 一致的缓存,实现 CXL.io 和 CXL.cache CXL Type 2: 设备带有自己的内存和与 CPU 一致的缓存,实现 CXL.io,CXL.cache 和 CXL.mem CXL Type 3: 设备带有自己的内存,实现 CXL.io 和 CXL.mem CXL 传输层 CXL.io CXL.io 基本上就是 PCIe 协议: CXL.io provides a non-coherent load/store interface for I/O devices. Figure 3-1 shows where the CXL.
PCIe 学习笔记
本文的内容已经整合到知识库中。 背景 最近在知乎上看到 LogicJitterGibbs 的 资料整理:可以学习 1W 小时的 PCIe,我跟着资料学习了一下,然后在这里记录一些我学习 PCIe 的笔记。 下面的图片主要来自 PCIe 3.0 标准以及 MindShare 的 PCIe 3.0 书本。 分层 PCIe 定义了三个层:Transaction Layer,Data Link Layer,Physical Layer,和 TCP/IP 四层模型很像。PCIe 也是基于 Packet 传输的。 Transaction Layer Transaction Layer 的核心是 Transaction Layer Packet(TLP)。TLP 格式: 即可选的若干个 Prefix,一个 Header,可选的 Data Payload,可选的 Digest。 Prefix 和 Header 开头的一个字节是 Fmt[2:0] 和 Type[4:0] 字段。Fmt 决定了 header 的长度,有无数据,或者这是一个 Prefix。 它支持几类 Packet: Memory: MMIO Read Request(MRd)/Completion(CplD) Write Request(MWr): 注意只有 Request,没有 Completion AtomicOp Request(FetchAdd/Swap/CAS)/Completion(CplD) Locked Memory Read(MRdLk)/Completion(CplDLk): Legacy IO: Legacy Read Request(IORd)/Completion(CplD) Write Request(IOWr)/Completion(Cpl) Configuration: 访问配置空间 Read Request(CfgRd0/CfgRd1)/Completion(CplD) Write Request(CfgWr0/CfgWr1)/Completion(Cpl) Message: 传输 event Request(Msg/MsgD) 括号里的是 TLP Type,对应了它 Fmt 和 Type 字段的取值。如果 Completion 失败了,原来应该是 CplD/CplDLk 的 Completion 会变成不带数据的 Cpl/CplLk。
在 ppc64le Linux 上运行 Nix
背景 之前尝试过在 ppc64le 的机器上运行 Nix,当时的尝试是把代码克隆下来编译,我还写了一个 Docker 脚本: # Based on https://github.com/NixOS/nix/issues/6048 # Build nixos/nix from source FROM ubuntu:20.04 RUN sed -i 's/ports.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list RUN apt-get update RUN DEBIAN_FRONTEND=noninteractive apt-get install -y \ autoconf-archive autoconf automake pkg-config build-essential git gcc g++ jq libboost-all-dev libcrypto++-dev libcurl4-openssl-dev \ libssh-dev libarchive-dev libsqlite3-dev libbz2-dev wget liblzma-dev libbrotli-dev libseccomp-dev bison flex libsodium-dev libgc-dev \ libgtest-dev libgmock-dev cmake unzip # Install editline - newer version required WORKDIR /root RUN wget https://github.
在 GNURadio Companion 中收听 FM 广播
背景 以前买过 RTL-SDR,用 Gqrx 做过收音机,当时还给 Homebrew 尝试提交过几个 sdr 相关的 pr,但是限于知识的缺乏,后来就没有再继续尝试了。 前两天,@OceanS2000 讲了一次 Tunight: 高级收音机使用入门,又勾起了我的兴趣,所以我来尝试一下在 GNURadio Companion 中收听 FM 广播电台。 我没有上过无线电相关课程,所以下面有一些内容可能不正确或者不准确。 安装 我的实验环境是 NixOS,所以是用下面的配置来安装 gnuradio 的: # SDR # https://github.com/NixOS/nixpkgs/pull/170253 (gnuradio.override { extraMakeWrapperArgs = [ "--prefix" "SOAPY_SDR_PLUGIN_PATH" ":" (soapyrtlsdr + "/lib/SoapySDR/modules0.8/") ]; }) soapysdr-with-plugins 其中 gnuradio 的 override 是为了让它可以找到 soapyrtlsdr 的库,否则它会找不到设备;soapysdr-with-plugins 是为了提供 SoapySDRUtil 命令,来确认它可以找到 RTL-SDR 设备: $ SoapySDRUtil --probe ---------------------------------------------------- -- Device identification ---------------------------------------------------- driver=RTLSDR hardware=R820T origin=https://github.com/pothosware/SoapyRTLSDR rtl=0 ---------------------------------------------------- -- Peripheral summary ---------------------------------------------------- Channels: 1 Rx, 0 Tx Timestamps: NO Other Settings: * Direct Sampling - RTL-SDR Direct Sampling Mode [key=direct_samp, default=0, type=string, options=(0, 1, 2)] * Offset Tune - RTL-SDR Offset Tuning Mode [key=offset_tune, default=false, type=bool] * I/Q Swap - RTL-SDR I/Q Swap Mode [key=iq_swap, default=false, type=bool] * Digital AGC - RTL-SDR digital AGC Mode [key=digital_agc, default=false, type=bool] ---------------------------------------------------- -- RX Channel 0 ---------------------------------------------------- Full-duplex: NO Supports AGC: YES Stream formats: CS8, CS16, CF32 Native format: CS8 [full-scale=128] Stream args: * Buffer Size - Number of bytes per buffer, multiples of 512 only.
ESXi 配置 LACP 链路聚合
背景 给 ESXi 接了两路 10Gbps 的以太网,需要用 LACP 来聚合。ESXi 自己不能配置 LACP,需要配合 vCenter Server 的 Distributed Switch 来配置。 步骤 参考文档:LACP Support on a vSphere Distributed Switch 第一步是创建一个 Distributed Switch。找到 Cluster,点击 ACTIONS,在 Distributed Switch 里面选择 New Distributed Switch。里面的选项都可以用默认的,按需修改。 第二步,找到刚刚创建的 Distributed Switch,点击 Configure,在 Settings 下点击 LACP,点击 NEW,选项可以用默认的,按需修改。 第三步,找到 Distributed Switch,点击 ACTIONS,点击 Add and Manage Hosts,找到要配置的主机,在 Manage physical adapters 这一步,找到要加入到链路聚合的 vmnic,每个要聚合的 vmnic 都在右边的 Assign uplink 处选择刚刚创建的 LAG 下的 Uplink,按顺序,一一对应。其余选项可以使用默认的。这一步配置好以后,在交换机上应该就可以看到 LACP 正常运转。 第四步,如果要把虚拟机连到链路聚合的网络上,找到虚拟机,点击 ACTIONS,点击 Edit Settings,新建一个网卡,Network adapter 处选择刚刚创建的 Distributed Port Group。这一步是让虚拟机多一个网卡,可以连接到 Distributed Switch 上。这一步配置好以后,虚拟机就可以收到来自其他物理机的网络流量,但是发送不出去。