使用qemu创建ubuntu-base文件系统,并安装PM相关内核模块

这篇具有很好参考价值的文章主要介绍了使用qemu创建ubuntu-base文件系统,并安装PM相关内核模块。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

流程简述:
(镜像基本的文件系统配置)
1、下载ubuntu-base的镜像
2、挂载镜像,配置镜像的网络,并安装各类软件
(PM模块配置)
3、编译内核模块,并拷贝到镜像中
4、启动qemu
5、安装内核模块,并配置相关软件

一、配置镜像

1、使用qemu-img创建image镜像(此处起名为ubuntu-rootfs-raw-20G.image

# [可选] sudo apt install qemu
qemu-img create -f raw ubuntu-rootfs-raw-20G.image 20G

注意:此处需要是raw类型,否则后续无法正常格式化(因为qcow2类型没有预先分配空间)。报错信息如下

$ sudo mkfs.ext4 ubuntu-rootfs-qcow2-20G.image
mke2fs 1.45.5 (07-Jan-2020)
ubuntu-rootfs-qcow2-20G.image: Not enough space to build proposed filesystem while setting up superblock

2、格式化镜像文件为ext4的文件系统

# 格式化
sudo mkfs.ext4 ubuntu-rootfs-raw-20G.image
# 检查
file ubuntu-rootfs-raw-20G.image

3、创建一个空目录,镜像的挂载点;然后将镜像挂载上去

mkdir ubuntu-rootfs-dir
sudo mount ubuntu-rootfs-raw-20G.image ubuntu-rootfs-dir

4、下载ubuntu-base-20.04.1-base-amd64.tar.gz镜像,并将其解压到ubuntu-rootfs-dir文件夹中(实质就是向镜像中塞文件,因为当前镜像已经被挂载到文件夹了)
(1)下载地址,https://cdimage.ubuntu.com/ubuntu-base/releases/20.04/release/ubuntu-base-20.04.1-base-amd64.tar.gz。
也可以自行选择其他版本:https://cdimage.ubuntu.com/ubuntu-base/releases/,

wget https://cdimage.ubuntu.com/ubuntu-base/releases/20.04/release/ubuntu-base-20.04.1-base-amd64.tar.gz

(2)解压到ubuntu-rootfs-dir

sudo tar -xzvf ubuntu-base-20.04.1-base-amd64.tar.gz -C ubuntu-rootfs-dir

5、拷贝主机中的网络配置信息到镜像中,方便后续用apt安装软件

sudo cp /etc/resolv.conf ubuntu-rootfs-dir/etc/

6、自行修改source.list文件,设置apt镜像进行加速

假设主机与客服机都是基于ubuntu 20.04,则可以直接拷贝主机的source.list,
否则需要自行配置
sudo cp /etc/apt/source.list ubuntu-rootfs-dir/etc/apt/source.list 

7、使用chrootubuntu-rootfs-dir暂时设置为根目录(与docker类似),并启动终端

sudo chroot ubuntu-rootfs-dir

8、安装软件

apt update\
&& apt upgrade\
&& apt install linux-image-kvm init vim -y 

9、设置密码之类的

update-initramfs -u
echo root:root | chpasswd
echo ttyS0 > /etc/securetty
systemctl enable serial-getty@ttyS0.service

10、退出并卸载

sudo umount ubuntu-rootfs-dir

11、后续扩展
(1)如果需要重新安装软件,可以重复第7步骤,挂载镜像,然后chroot进去。
(2)镜像扩容操作

qemu-img resize ubuntu-rootfs-raw-20G.image +10G

二、使用qemu模拟nvdimm(安装PM相关内核模块)

如果要运行PM
1、安装软件包(安装到镜像里面)

apt install -y systemd numactl ndctl daxctl

2、编译内核时,编译相关模块

make -j $(nproc) vmlinux bzImage
make -j $(nproc) M=drivers/dax -j16
make -j $(nproc) M=drivers/nvdimm/ -j16
make -j $(nproc) M=drivers/dax/pmem -j16

3、将编译好的模块复制到镜像中

# 1、挂载镜像
# 略

# 2、设置路径(路径根据需要进行修改)
image_dir_path=/home/my/my_images/ubuntu-base/ubuntu-rootfs-dir
module_path=$image_dir_path/root/my_modules
sudo mkdir $module_path

# 3、拷贝编译的内核模块到镜像中
cd linux-5.15.114
sudo cp -r ./drivers/dax $module_path/drivers/dax
sudo cp -r ./drivers/nvdimm $module_path/drivers/nvdimm

# 4、卸载镜像
# 略

3、运行qemu

qemu-system-x86_64 \
    -machine pc,nvdimm=on \
    -m 2G,slots=4,maxmem=32G \
    -nographic -kernel bzImage \
    -smp cores=4,threads=1,sockets=2 \
    -hda ubuntu_rootfs.ext4 \
    -object memory-backend-ram,id=mem0,size=1G  \
    -object memory-backend-ram,id=mem1,size=1G  \
    -numa node,memdev=mem0,cpus=0-3,nodeid=0 \
    -numa node,memdev=mem1,cpus=4-7,nodeid=1 \
    -numa node,nodeid=2 -numa node,nodeid=3 \
    -object memory-backend-ram,id=nvdimm1,size=4G\
    -device nvdimm,memdev=nvdimm1,id=nv1,unarmed=off,node=2 \
    -object memory-backend-ram,id=nvdimm2,size=4G\
    -device nvdimm,memdev=nvdimm2,id=nv2,unarmed=off,node=3 \
    -append "console=ttyS0 crashkernel=256M root=/dev/sda rootfstype=ext4 rw loglevel=8"

4、安装模块(注意模块之间的依赖)

insmod /root/my_modules/drivers/dax/device_dax.ko
insmod /root/my_modules/drivers/dax/kmem.ko

insmod /root/my_modules/drivers/dax/pmem/dax_pmem_core.ko
insmod /root/my_modules/drivers/dax/pmem/dax_pmem.ko
insmod /root/my_modules/drivers/dax/pmem/dax_pmem_compat.ko

insmod /root/my_modules/drivers/nvdimm/nd_btt.ko
insmod /root/my_modules/drivers/nvdimm/nd_blk.ko
insmod /root/my_modules/drivers/nvdimm/nd_pmem.ko
insmod /root/my_modules/drivers/nvdimm/nd_virtio.ko
insmod /root/my_modules/drivers/nvdimm/virtio_pmem.ko

# check
lsmod

此处注意:模块之间可能存在依赖,需要按照一定的顺序。如果顺序不对,可能出现如下报错信息insmod: ERROR: could not insert module device_dax.mod: Invalid module format。此时,使用dmesg | tail可以查看详细日志信息,使用modinfo ./dax_pmem.ko | grep depend 可以查看模块的依赖。

$ modinfo ./dax_pmem.ko | grep depend 
depends:        dax_pmem_core
# 可以看到dax_pmem.ko依赖dax_pmem_core模块

5、配置nvdimm

# 首次配置
daxctl migrate-device-model
echo offline > /sys/devices/system/memory/auto_online_blocks
ndctl create-namespace -f --mode devdax --continue
daxctl reconfigure-device --mode=system-ram all

# 重启后重新配置
echo offline > /sys/devices/system/memory/auto_online_blocks
ndctl disable-namespace all
ndctl destroy-namespace all
ndctl create-namespace -f --mode devdax --continue
daxctl reconfigure-device --mode=system-ram all

6、合并四五步
后续可以创建一个init.sh文件放到镜像中,启动时自动运行

# init.sh
# 用于image镜像中挂载内核模块等

insmod /root/my_modules/drivers/dax/device_dax.ko
insmod /root/my_modules/drivers/dax/kmem.ko

insmod /root/my_modules/drivers/dax/pmem/dax_pmem_core.ko
insmod /root/my_modules/drivers/dax/pmem/dax_pmem.ko
insmod /root/my_modules/drivers/dax/pmem/dax_pmem_compat.ko

insmod /root/my_modules/drivers/nvdimm/nd_btt.ko
insmod /root/my_modules/drivers/nvdimm/nd_blk.ko
insmod /root/my_modules/drivers/nvdimm/nd_pmem.ko
insmod /root/my_modules/drivers/nvdimm/nd_virtio.ko
insmod /root/my_modules/drivers/nvdimm/virtio_pmem.ko


# 首次配置
# daxctl migrate-device-model
# echo offline > /sys/devices/system/memory/auto_online_blocks
# ndctl create-namespace -f --mode devdax --continue
# daxctl reconfigure-device --mode=system-ram all

# 重启后重新配置
echo offline > /sys/devices/system/memory/auto_online_blocks
ndctl disable-namespace all
ndctl destroy-namespace all
ndctl create-namespace -f --mode devdax --continue
daxctl reconfigure-device --mode=system-ram all

运行记录

root@localhost:~/my_modules/drivers/nvdimm/nvdimm# echo offline > /sys/devices/system/memory/auto_online_blocks
root@localhost:~/my_modules/drivers/nvdimm/nvdimm# ndctl create-namespace -f --mode devdax --continue
{
  "dev":"namespace1.0",
  "mode":"devdax",
  "map":"dev",
  "size":"3.94 GiB (4.23 GB)",
  "uuid":"12f978b1-c1f4-4be8-a67d-aa076e0a4152",
  "daxregion":{
    "id":1,
    "size":"3.94 GiB (4.23 GB)",
    "align":2097152,
    "devices":[
      {
        "chardev":"dax1.0",
        "size":"3.94 GiB (4.23 GB)",
        "target_node":3,
        "mode":"devdax"
      }
    ]
  },
  "align":2097152
}
{
  "dev":"namespace0.0",
  "mode":"devdax",
  "map":"dev",
  "size":"3.94 GiB (4.23 GB)",
  "uuid":"0529e940-38b1-45fd-a0b1-43fcf95192ce",
  "daxregion":{
    "id":0,
    "size":"3.94 GiB (4.23 GB)",
    "align":2097152,
    "devices":[
      {
        "chardev":"dax0.0",
        "size":"3.94 GiB (4.23 GB)",
        "target_node":2,
        "mode":"devdax"
      }
    ]
  },
  "align":2097152
}
created 2 namespaces
root@localhost:~/my_modules/drivers/nvdimm/nvdimm# daxctl reconfigure-device --mode=system-ram all
[
  {
    "chardev":"dax0.0",
    "size":4225761280,
    "target_node":2,
    "mode":"system-ram",
    "movable":true
  }
]

非首次运行:

root@localhost:~/my_modules/drivers/nvdimm# echo offline > /sys/devices/system/memory/auto_online_blocks
oy-namespace all
ndctl create-namespace -f --mode devdax --continue
daxctl reconfigure-device --moderoot@localhost:~/my_modules/drivers/nvdimm# ndctl disable-namespace all
=system-ram alldisabled 2 namespaces
root@localhost:~/my_modules/drivers/nvdimm# ndctl destroy-namespace all
destroyed 0 namespaces
root@localhost:~/my_modules/drivers/nvdimm# ndctl create-namespace -f --mode devdax --continue
{
  "dev":"namespace1.0",
  "mode":"devdax",
  "map":"dev",
  "size":"3.94 GiB (4.23 GB)",
  "uuid":"8259f939-0c3d-43c4-89cb-6e89653c290f",
  "daxregion":{
    "id":1,
    "size":"3.94 GiB (4.23 GB)",
    "align":2097152,
    "devices":[
      {
        "chardev":"dax1.0",
        "size":"3.94 GiB (4.23 GB)",
        "target_node":3,
        "mode":"devdax"
      }
    ]
  },
  "align":2097152
}
{
  "dev":"namespace0.0",
  "mode":"devdax",
  "map":"dev",
  "size":"3.94 GiB (4.23 GB)",
  "uuid":"41d3381f-cd6a-4c02-b8d1-c97cd2633cb4",
  "daxregion":{
    "id":0,
    "size":"3.94 GiB (4.23 GB)",
    "align":2097152,
    "devices":[
      {
        "chardev":"dax0.0",
        "size":"3.94 GiB (4.23 GB)",
        "target_node":2,
        "mode":"devdax"
      }
    ]
  },
  "align":2097152
}
created 2 namespaces
root@localhost:~/my_modules/drivers/nvdimm# daxctl reconfigure-device --mode=system-ram all
[
  {
    "chardev":"dax0.0",
    "size":4225761280,
    "target_node":2,
    "mode":"system-ram",
    "movable":true
  }
]
reconfigured 2 devices

遇到的一些问题

1、ext4文件系统损坏

问题:系统启动时,遇到ext4的报错信息
[ 3.630969] EXT4-fs error (device sda): htree_dirblock_to_tree:1080: inode #393220: comm systemd-tmpfile: Directory block failed checksum

这还会导致其它的问题,例如:

  • 有文件删不掉
rm: cannot remove 'directory': Bad message
  • 文件变成目录,还删不掉
# 提示双重目录(因为daxctl.conf变成了目录)
conf_files_filter_out: Directories inside directories are not supported: /etc/modprobe.d/daxctl.conf
# 删除不了
"cannot remove 'daxctl.conf': Directory not empty"
解决办法:

使用e2fsck工具扫描并修复一下文件系统,基本全程按y确定,即可。(按我看到的信息,貌似是一些文件的ref没有更新,导致文件出错)

e2fsck -y ubuntu-rootfs-raw-20G.image

其中,
-f 选项用于强制检查文件系统,即使文件系统处于已挂载状态。
-y 选项用于自动回答所有修复问题为 “yes”,以便自动修复文件系统错误。
检查:

$ e2fsck ubuntu-rootfs-raw-20G.image
e2fsck 1.45.5 (07-Jan-2020)
ubuntu-rootfs-raw-20G.image: clean, 13654/1310720 files, 321042/5242880 blocks
2、内核模块未成功加载

出错信息

$ ndctl create-namespace -f --mode devdax --continue
libkmod: ERROR ../libkmod/libkmod-module.c:838 kmod_module_insert_module: could not find module by name='dax_pmem'
原因:lsmod检查一下,应该是dax_pmem模块没有成功加载。
root@localhost:~# depmod -a
depmod: ERROR: could not open directory /lib/modules/5.15.114+: No such file or directory

原因:我一开始忘记把内核模块放到镜像里了。
3、qemu报错
# qemu环境中,执行关机命令
$ shutdown now
....
systemd-journald[202]: Failed to send stream file descriptor to service manager: Connection refused

猜测:可能是这里有文件没有写完,qemu就被我关了。说不定前面文件系统出错就是因为这个原因。

4、主机终端无法正常打开

不知道具体什么原因(猜测是因为我有时挂载了/dev目录,然后导致终端无法打开,vscode远程链接的终端也无法打开),报错信息如下:

There was an error creating the child proces for this terminalFailed to open PTY: No such device

使用qemu创建ubuntu-base文件系统,并安装PM相关内核模块,工具使用、环境搭建,nvdimm,内核模块,qemu,rootfs
解决办法:
1、想办法进入系统,通过安全模式或者启动盘,或者什么的,反正只要能运行boot-repair
2、下载boot-repair
3、运行boot-repair进行修复。

$ sudo apt install boot-repair
$ boot-repair
5、模块与内核版本不一致

insmod时出错,然后dmesg | tail可查到报错信息,大致如下:

device_dax: disagrees about version of symbol vmf_insert_mixed
 : unknown symbol kmalloc_caches (err -22)

原因:为了编译更快一点,我的编译命令是make -j16 vmlinux,因此只有vmlinux被更新了,其它的模块没有被更新。

tips(备忘录)
假如存在目录a/c和目录b/c,现在a/c下面添加了1.txt,而我想把这个1.txt同步到b/c下面。
首先, cp -r a/c b/ccp -r a/c b/c/都不行,它们会把a/c复制到b/c下面,出现了一个b/c/c的文件夹
然后,网上提出了一些方案:https://stackoverflow.com/questions/23698183/how-to-force-cp-to-overwrite-directory-instead-of-creating-another-one-inside,但是我觉得都不太优雅。。。

  1. 先rm旧文件夹,再cp新文件夹。简单,但是缺点是文件夹很大的话就很慢吧?
  2. 使用rsync同步文件夹。很好,唯一缺点:我用rsync用得没那么熟,而且我不确定rsync是否在所有服务器上都默认已经安装了
  3. 使用-T参数,将目标目录视为文件对象。缺点:很少用到这个参数,而且将文件夹视为文件这个功能,我怕我乱用之后,自己以后脑子都记不清了。
  4. cp -r a/c/* b/c/*。缺点:我平时用肯定会选这个,但是写在脚本里就不太方便,因为第一次运行得时候,b/c文件夹是不存在的,那这个命令就会报错。因此我写脚本的时候,需要判断这种情况,然后再用不同命令处理。

解决办法:
(1)在编译内核的时候同时编译相关模块

# 默认会编译所有代码
make -j16

(2)将新编译的模块替换旧的模块,为了方便这里写了个脚本。脚本内容就是先挂载镜像,然后拷贝文件,最后卸载镜像。只不过为了安全起见,加了一些check的代码(担心有参数是空的,然后路径变成/什么的)。文章来源地址https://www.toymoban.com/news/detail-565153.html

# 需要修改的变量
# 内核代码(默认当前文件夹)
linux_kernel_root=.
# 镜像路径
image_path=/home/dell/my_images/ubuntu-base/ubuntu-rootfs-raw-20G.image
# 挂载镜像的文件夹
mount_dir=/home/dell/my_images/ubuntu-base/ubuntu-rootfs-dir

# check
if [[ ! -f $image_path ]]
then
    echo $image_path" not exists"
    exit
fi
if [[ ! -d $mount_dir ]]
then
    echo $mount_dir" not exists"
    exit
fi


# mount
sudo mount $image_path $mount_dir
ret=$?
if [[ ! ret ]]
then
    echo "mount $image_path to $mount_dir failed"
    exit
fi
echo "success mounting $image_path to $mount_dir"

# copy
module_path=$mount_dir"/root/my_modules"

sudo mkdir -p $module_path/drivers/dax
sudo mkdir -p $module_path/drivers/nvdimm

sudo rm -r $module_path/drivers/dax
sudo rm -r $module_path/drivers/nvdimm

sudo cp -r $linux_kernel_root/drivers/dax $module_path/drivers/dax
sudo cp -r $linux_kernel_root/drivers/nvdimm $module_path/drivers/nvdimm

echo "success copying modules to $module_path"

# umount
sudo umount $mount_dir
if [[ ! ret ]]
then
    echo "umount $mount_dir failed"
    exit
fi
echo "success umounting $image_path to $mount_dir"

到了这里,关于使用qemu创建ubuntu-base文件系统,并安装PM相关内核模块的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Ubuntu-base(20.04/22.04) armhf / aarch64移植记录

    根文件系统官网 进入如下图选择版本-进入release 版本下载界面-下载armhf/arm64文件。 在/home/zynq/linux/rootfs/下建立mount.sh 在/home/zynq/linux/rootfs/下建立unmount.sh 给两个文件赋权限 运行mount.sh 挂载文件系统 adduser 和useradd的区别: adduser 和useradd的区别:

    2024年02月11日
    浏览(64)
  • Windows11 上使用 QEMU 创建 Ubuntu aarch64(ARM64)虚拟机

    最近在实现一个混沌测试工具,对汽车上分布式系统执行测试。计划运行在 Linux aarch64 环境,需要确定在目标环境能不能运行,但自己和实验室的电脑都是 x86_64,所以打算建一个虚拟机。 通过 Docker容器或VMware都不支持在 x86_64 宿主机运行 aarch64 容器/虚拟机, Virtual Box 似乎也

    2024年02月03日
    浏览(48)
  • QEMU安装Ubuntu 20.04的完整过程

    宿主机: Ubuntu 22.04.1 LTS Ubuntu 20.04镜像: ubuntu-20.04.5-desktop-amd64.iso QEMU版本: qemu-img version 7.1.0 Copyright (c) 2003-2022 Fabrice Bellard and the QEMU Project developers   1. 创建镜像文件 使用qemu-img命令创建镜像文件。命令及结果如下所示: 上述命令使用qemu-img create命令创建了一个空白的客户

    2023年04月08日
    浏览(38)
  • QEMU搭建X86_64 + Ubuntu虚拟系统环境

    QEMU搭建X86_64 + Ubuntu虚拟系统环境 本文记录一下学习和使用QEMU虚拟工具的过程,初次尝试,如有错误请各位大佬帮忙指正。 提示 :不推荐在低版本的Ubuntu中操作,QEMU需要很多依赖所用到的版本比较高,低版本ubuntu系统无法一键安装或者升级到对应的高版本的依赖,需要手动

    2024年02月05日
    浏览(46)
  • 在x86下运行的Ubuntu系统上部署QEMU用于模拟RISC-V硬件系统

    下载地址: 建议选择stable版本,arch选择riscv64-lp64d,libc选择常用的glibc。 下载后解压,然后将bin目录加入PATH环境变量中。 下载地址: 建议选择稳定版本,下载后解压,然后make --enable-virtfs 用户虚拟机和宿主机之间共享文件 Linux内核下载地址: 选择稳定的版本,下载完后解

    2024年02月13日
    浏览(57)
  • Ubuntu系统的conda基础操作(安装、创建环境、退出)

    一、安装Conda 直接在Tenminal中输入 下面 ,下载2021.11版本的anaconda安装包(可修改版本号)。 然后再输入 下面 ,有 ENTER 直接 回车 ,有 more 按 Q键 跳过,有 yes/no 输入 yes后按回车 。 打开.bashrc 配置环境变量,其中 crypto-cxf 为系统名称,并按 save 保存。 然后,输入 最好,安装

    2024年02月14日
    浏览(40)
  • 安装Ubuntu,创建分区时无EFI系统分区选项的解决方法

    电脑型号:联想小新Air2021 操作系统:windows10 硬盘:一块512G固态 如题,安装Ubuntu,在创建分区时,“用于”栏 没有“EFI系统分区”选项,导致在重启电脑后,发现直接进了Windows系统,并没有弹出选择操作系统的界面,在经过尝试后,解决步骤为: 1、使用DG分区助手将U盘的

    2024年02月13日
    浏览(45)
  • ubuntu22上使用qemu-system-arm调试linux

    qemu是用软件模拟硬件解析指令运行的软件,可以模拟arm、arm64、x86等,对于调试linux 内核机制很方便,不用额外购买开发板。由于linux上有对qemu的加速引擎,支持程度更高,且网络上教程居多,所以这里使用virtualbox+ubuntu22虚拟机,在ubuntu上运行qemu进行模拟。 virtualbox安装:

    2024年01月25日
    浏览(48)
  • ubuntu22.04 x86环境上使用QEMU搭建arm虚拟机

    apt-get -y install qemu apt-get -y install bridge-utils apt-get -y install vnc4server apt-get -y install qemu-kvm apt install -y qemu-system-arm apt-get -y install libvirt0 apt-get -y install libvirt-daemon apt-get -y install libvirt-daemon-system 安装完成后检查: virsh version ls /usr/bin/|grep qemu wget http://releases.linaro.org/components/kernel/

    2024年02月07日
    浏览(86)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包