使用qemu模拟CXL.mem设备

CXL可以说是自PCIe技术诞生几十年以来最具变革性的新技术了。可以想象有了CXL以后机箱的边界将被彻底打破,服务器互相使用对方的内存,网卡,GPU 。整个机架甚至跨机架的超级资源池化成为可能,云计算也将进入一个新的时代。

当前Intel, AMD 目前最新CPU型号也都已经支持CXL接口,三星也有支持CXL的内存模组提供,但是普及性还是非常低,可能只有极个别的研究人员才能拿到真正的物理设备。作为不那么有实力的普通IT从业者如何才能体验这一最前沿的科技成果呢?使用模拟器便是最方便的选择。

本文包括两部分内容,
1)如何使用qemu搭建CXL模拟环境,列出关键的避坑点。这部分需要一定的软件开发基础。
2)从模拟器里看到的CXL设备什么样,这部分适合大多数IT从业者,看到就是体验到

一、搭建CXL qemu模拟器

搭建模拟环境需要三个软件:1)合适版本的qemu 2)合适版本的linux内核 3)合适版本的ndctl软件。 这里说“合适” 是想说并非随便抓个版本过来就可以使用,因为CXL正在飞速演进,软件生态也在不断迭代中,合适的版本才能配合到一起。

1) 编译qemu, 我使用的qemu代码库在:https://gitlab.com/jic23/qemu/-/tree/cxl-2023-04-19, commit ID: 8eb2a03258 

具体编译过程不是本文重点,这里省略,请大家自行解决。

2)使用qemu启动一个VM,我使用的是 CentOS8.4, 可以自己安装也可以从网上下载安装好了的qcow2文件。同样这个的具体操作步骤省略。

3)编译Linux内核,步骤2把VM起来后我们需要更新其内核。本文测试使用的是6.3.0版本内核,从https://gitee.com/mirrors/linux_old1.git 这个代码库克隆,commit ID: 457391b03803

编译内核时需要使能CXL支持,在.config文件里如下配置:

# grep CXL .config
CONFIG_CXL_BUS=m
CONFIG_CXL_PCI=m
CONFIG_CXL_MEM_RAW_COMMANDS=y
CONFIG_CXL_ACPI=m
CONFIG_CXL_PMEM=m
CONFIG_CXL_MEM=m
CONFIG_CXL_PORT=m
CONFIG_CXL_SUSPEND=y
CONFIG_CXL_REGION=y
CONFIG_CXL_REGION_INVALIDATION_TEST=y
CONFIG_DEV_DAX_CXL=m

4) ndctl工具,使用  https://github.com/pmem/ndctl.git , commit ID: 96bae09

这个工具需要在guest OS里面使用。也需要大家自行编译。

应该说上面这几个过程还是颇有些繁琐,光编译环境就要Host, guest搭两次,笔者也是折腾了好久。为了不影响本文主要目标,保持行文简洁只能忍痛省略。

二、启动qemu

启动qemu时添加CXL.mem设备,这里直接给出启动命令,大家看命令行就知道如何设置

/data/cxl/qemu/build/qemu-system-x86_64  -enable-kvm -cpu host -smp 8 \
   -machine type=q35,accel=kvm,nvdimm=on,cxl=on   \
   -drive if=ide,file=./centosx86.qcow2,cache=none  \
   -m 32G,slots=8,maxmem=64G -vnc :3 \
   -nic user,hostfwd=tcp::10023-:22 \
   -net nic,macaddr=12:34:56:78:9a:bc \
   -net tap,ifname=tap3 \
   -cdrom /data/CentOS-8.4.2105-x86_64-dvd1.iso \
   -object memory-backend-file,id=cxl-mem1,share=on,mem-path=/tmp/cxltest.raw,size=256M \
-object memory-backend-file,id=cxl-lsa1,share=on,mem-path=/tmp/lsa.raw,size=256M \
-device pxb-cxl,bus_nr=12,bus=pcie.0,id=cxl.1 \
-device cxl-rp,port=0,bus=cxl.1,id=root_port13,chassis=0,slot=2 \
-device cxl-type3,bus=root_port13,memdev=cxl-mem1,lsa=cxl-lsa1,id=cxl-pmem0 \
-M cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G

三、 CXL之初体验

1) 首先我们看系统里cxl设备出现在哪里:

# ls /dev/cxl/
mem0

没错,就是多出了这么个小小的设备文件。

2)再具体一点,使用刚才编译的ndctl工具,最新的版本里面带了一个叫cxl的工具,

还可以再具体一些,# cxl list -v 

# cxl list -v
[
  {
    "bus":"root0",
    "provider":"ACPI.CXL",
    "nr_dports":1,
    "dports":[
      {
        "dport":"pci0000:0c",
        "alias":"ACPI0016:00",
        "id":12
      }
    ],
    "ports:root0":[
      {
        "port":"port1",
        "host":"pci0000:0c",
        "depth":1,
        "nr_dports":1,
        "dports":[
          {
            "dport":"0000:0c:00.0",
            "id":0
          }
        ],
        "endpoints:port1":[
          {
            "endpoint":"endpoint2",
            "host":"mem0",
            "depth":2,
            "memdev":{
              "memdev":"mem0",
              "pmem_size":268435456,
              "serial":0,
              "host":"0000:0d:00.0",
              "partition_info":{
                "total_size":268435456,
                "volatile_only_size":0,
                "persistent_only_size":268435456,
                "partition_alignment_size":0
              }
},
            "decoders:endpoint2":[
              {
                "decoder":"decoder2.0",
                "interleave_ways":1,
                "state":"disabled"
              },
              {
                "decoder":"decoder2.1",
                "interleave_ways":1,
                "state":"disabled"
              },
              {
                "decoder":"decoder2.2",
                "interleave_ways":1,
                "state":"disabled"
              },
              {
                "decoder":"decoder2.3",
                "interleave_ways":1,
                "state":"disabled"
              }
            ]
          }
        ],
        "decoders:port1":[
          {
            "decoder":"decoder1.0",
            "interleave_ways":1,
            "state":"disabled",
            "nr_targets":1,
            "targets":[
              {
                "target":"0000:0c:00.0",
                "position":0,
                "id":0
              }
            ]
          }
        ]
      }
    ],
    "decoders:root0":[
      {
        "decoder":"decoder0.0",
        "resource":79725330432,
        "size":4294967296,
        "interleave_ways":1,
        "max_available_extent":4294967296,
        "pmem_capable":true,
        "volatile_capable":true,
        "accelmem_capable":true,
        "nr_targets":1,
        "targets":[
          {
            "target":"pci0000:0c",
            "alias":"ACPI0016:00",
            "position":0,
            "id":12
          }
        ]
      }
    ]
  }
]

3) 使用这个设备

当前我们模拟出来的是一个CXL接口的pmem设备,像AEP。

# cxl create-region -d decoder0.0 -t pmem -m mem0
{
  "region":"region0",
  "resource":"0x1290000000",
  "size":"256.00 MiB (268.44 MB)",
  "interleave_ways":1,
  "interleave_granularity":256,
  "decode_state":"commit",
  "mappings":[
    {
      "position":0,
      "memdev":"mem0",
      "decoder":"decoder2.0"
    }
  ]
}
cxl region: cmd_create_region: created 1 region

# cxl list
[
  {
    "memdevs":[
      {
        "memdev":"mem0",
        "pmem_size":268435456,
        "serial":0,
        "host":"0000:0d:00.0"
      }
    ]
  },
  {
    "regions":[
      {
        "region":"region0",
        "resource":79725330432,
        "size":268435456,
        "interleave_ways":1,
        "interleave_granularity":256,
        "decode_state":"commit"
      }
    ]
  }
]


[root@vm3 ~]# ndctl create-namespace
{
  "dev":"namespace0.0",
  "mode":"fsdax",
  "map":"dev",
  "size":"250.00 MiB (262.14 MB)",
  "uuid":"25fab29a-f4ce-483e-94b4-176c40111f6c",
  "sector_size":512,
  "align":2097152,
  "blockdev":"pmem0"
}
[root@vm3 ~]# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0   50G  0 disk
└─sda1   8:1    0   50G  0 part /
sr0     11:0    1  9.3G  0 rom
pmem0  259:0    0  250M  0 disk

 经过上面这一系列的cxl命令,ndctl命令,lsblk终于看到pmem0设备了,使用过AEP的的朋友对这个设备肯定不陌生,之后就跟AEP的使用方法一样了,格式化文件系统,映射到内存空间 ...,本文不再赘述。

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
要在Windows下交叉编译Qt 5.14.2至树莓派平台,您需要安装以下工具: 1. MinGW-w64:这是一个开源的Windows编译器,可以生成32位和64位的Windows可执行文件和Linux可执行文件。在这里,我们将使用MinGW-w64来交叉编译Qt。 2. SysGCC:SysGCC是一个基于MinGW-w64的交叉编译器,可以生成适用于ARM架构的Linux可执行文件。 3. Raspberry Pi Toolchain:这是一个树莓派交叉编译工具链。 现在,让我们开始配置工具链: 1. 安装MinGW-w64。您可以从这里下载MinGW-w64:http://mingw-w64.org/doku.php/download 2. 安装SysGCC。您可以从这里下载SysGCC:https://www.sourcetree.com/sysgcc.html 3. 安装Raspberry Pi Toolchain。您可以从这里下载Raspberry Pi Toolchain:https://github.com/raspberrypi/tools 4. 配置环境变量。在Windows系统中,您需要将MinGW-w64和Raspberry Pi Toolchain添加到环境变量中。打开“环境变量”对话框,找到“系统变量”下的“Path”,单击“编辑”,在路径列表中添加MinGW-w64和Raspberry Pi Toolchain的路径。 现在,您已经准备好开始交叉编译Qt了。按照以下步骤操作: 1. 下载Qt源代码。您可以从这里下载Qt源代码:https://www.qt.io/download-qt-installer 2. 解压Qt源代码。将源代码解压到您喜欢的位置。 3. 打开命令提示符。按下“Win + R”键,键入“cmd”并按回车键。 4. 导航到Qt源代码目录。使用“cd”命令导航到Qt源代码目录。 5. 运行configure命令。在命令提示符中运行以下命令: ``` configure -platform win32-g++ -xplatform linux-arm-gnueabihf-g++ -release -opengl es2 -device linux-rasp-pi-g++ -device-option CROSS_COMPILE=path/to/sysgcc/bin/arm-linux-gnueabihf- -sysroot path/to/raspbian/sysroot -prefix /usr/local/qt5pi -opensource -confirm-license -skip qtwebengine -skip qtscript -nomake examples -nomake tests ``` 在这个命令中,我们使用了以下参数: - `-platform win32-g++`:将Qt配置为使用MinGW-w64编译。 - `-xplatform linux-arm-gnueabihf-g++`:将Qt配置为在ARM架构上编译。 - `-release`:将Qt配置为生成发布版本。 - `-opengl es2`:将Qt配置为使用OpenGL ES 2.0。 - `-device linux-rasp-pi-g++`:将Qt配置为在树莓派平台上编译。 - `-device-option CROSS_COMPILE=path/to/sysgcc/bin/arm-linux-gnueabihf-`:告诉Qt使用SysGCC作为交叉编译器。 - `-sysroot path/to/raspbian/sysroot`:告诉Qt使用Raspbian的根文件系统作为系统根目录。 - `-prefix /usr/local/qt5pi`:告诉Qt将Qt安装到树莓派的`/usr/local/qt5pi`目录中。 - `-opensource -confirm-license`:告诉Qt使用开源许可证。 - `-skip qtwebengine -skip qtscript -nomake examples -nomake tests`:告诉Qt跳过一些不必要的模块,以加快编译速度。 6. 编译Qt。运行以下命令编译Qt: ``` mingw32-make ``` 7. 安装Qt。运行以下命令安装Qt: ``` mingw32-make install ``` 现在,Qt已经被成功交叉编译并安装到树莓派上了。您可以将生成的可执行文件复制到树莓派上,并在树莓派上运行它们。 如果您没有树莓派硬件,您可以使用QEMU模拟器来模拟树莓派。您可以按照以下步骤操作: 1. 安装QEMU模拟器。您可以从这里下载QEMU模拟器:https://www.qemu.org/download/ 2. 下载树莓派镜像。您可以从这里下载树莓派官方镜像:https://www.raspberrypi.org/downloads/ 3. 解压树莓派镜像。将镜像解压到您喜欢的位置。 4. 启动QEMU模拟器。在命令提示符中运行以下命令: ``` qemu-system-arm -M versatilepb -cpu arm1176 -m 256 -hda path/to/raspbian.img -kernel path/to/kernel-qemu-4.4.34-jessie -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw" -net nic -net user,hostfwd=tcp::5022-:22 -dtb path/to/versatile-pb.dtb -no-reboot ``` 在这个命令中,我们使用了以下参数: - `-M versatilepb`:将QEMU配置为使用Versatile PB开发板模拟器。 - `-cpu arm1176`:将QEMU配置为使用ARM1176 CPU模拟器。 - `-m 256`:将QEMU配置为使用256MB内存。 - `-hda path/to/raspbian.img`:告诉QEMU使用Raspbian映像作为硬盘驱动器。 - `-kernel path/to/kernel-qemu-4.4.34-jessie`:告诉QEMU使用适用于Versatile PB开发板模拟器的内核。 - `-append "root=/dev/sda2 panic=1 rootfstype=ext4 rw"`:告诉QEMU启动内核时使用的内核参数。 - `-net nic -net user,hostfwd=tcp::5022-:22`:告诉QEMU配置网络适配器和端口转发。 - `-dtb path/to/versatile-pb.dtb`:告诉QEMU使用适用于Versatile PB开发板模拟器的设备树文件。 - `-no-reboot`:告诉QEMU在停止模拟器时不要重新启动。 5. 在QEMU中安装Qt。按照前面的步骤交叉编译并安装Qt,然后将生成的可执行文件复制到QEMU模拟器中即可。 现在,您已经成功地将Qt交叉编译并安装到树莓派上或QEMU模拟器中了。
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值