找建设网站公司哪家好,专业生产佛山网站建设,成都网站优化,百度上的广告多少钱一个月目录QEMU简介linux启动流程我的环境安装QEMU软件包安装源码安装编译linux内核编译busybox制作initramfs使用QEMU启动linux内核简化命令参考QEMU简介
QEMU#xff08;quick emulator#xff09;是一个通用的、开源的硬件模拟器#xff0c;可以模拟不同硬件架构#xff08;如…
目录QEMU简介linux启动流程我的环境安装QEMU软件包安装源码安装编译linux内核编译busybox制作initramfs使用QEMU启动linux内核简化命令参考QEMU简介
QEMUquick emulator是一个通用的、开源的硬件模拟器可以模拟不同硬件架构如x86、ARM、ARM64、MIPS、PowerPC等是目前比较流行的跨平台仿真软件。
QEMU主要的仿真方式包括全系统仿真和用户模式仿真。
全系统仿真QEMU提供了整个机器的虚拟模型包括CPU、内存和模拟设备等外设来运行客户操作系统。该模式下相当于系统级虚拟机。
用户模式仿真QEMU 允许一个应用程序执行在不同架构的CPU上该模式下相当于进程级虚拟机。 本文介绍如何使用QEMU模拟器启动linux内核使用的就是QEMU的全系统仿真模式。
linux启动流程
在开始之前需要了解linux的开机启动流程详细可自行查阅资料如《鸟哥的Linux私房菜》的“Linux 的启动流程分析”。简要总结就是BIOSMBR启动Bootloader加载Kernel挂载虚拟rootfs挂载真实rootfs初始化用户程序即执行init进程。
为什么会有虚拟rootfs这涉及到initrd全称boot loader initialized RAM disk初始化的内存盘RAM disk就是将内存的一部分分配为一个分区并作为磁盘来使用initrd就是由 boot loader 初始化的内存盘。
initrd出现的背景。
早期linux系统用于存储rootfs的介质一般只有硬盘或者软盘内核集成了这些磁盘驱动程序开机时内核可以直接挂载基于磁盘的rootfs。后来嵌入式系统可能将rootfs存储到各种介质上包括IDE、SCSI、SATAFlash、u-disk等等。如果将所有介质的驱动都编译进内核内核会越来越臃肿。索性将所有存储介质的驱动都编译成内核模块并将其ko文件保存在rootfs中可按需加载。那么问题来了内核要挂载rootfs就要先加载对应存储介质驱动模块内核要加载存储介质驱动模块就要先挂载rootfs。先有鸡还是先有蛋
为了解决这一矛盾出现了基于ramdisk的initrd。initrd是一个被压缩过的小型根目录这个目录中包含了启动阶段中必须的驱动模块可执行文件和启动脚本。在 Bootloader 配置了 initrd 的情况下内核启动被分成了两个阶段第一阶段先挂载基于内存盘的虚拟roofs把系统内存的一部分作为根文件系统挂载执行 initrd 文件系统中的启动脚本完成加载驱动模块等任务第二阶段才挂载真实rootfs并执行初始化用户程序init 进程。
initrd是基于内存的块设备即ramdisk有个缺点就是大小固定是过时的机制。Linux 2.6开始采用initramfs替换了initrdinitramfsinit ram filesystem是基于内存的文件系统即ramfs其空间大小可动态变化本文使用的就是 initramfs。
总结起来就是在挂载基于磁盘的真正rootfs之前会先挂载一个基于内存的虚拟rootfs通过initrd或者initramfs 实现虚拟rootfs只是起个过渡的作用它完成一些内核不容易做到的事情比如加载必要的驱动模块挂载真正rootfs。
使用QEMU的全系统仿真模式启动linux内核时BIOS、MBR和Bootloader都已经在QEMU内置好了我们只要准备linux内核镜像和initramfs即可。本文重点演示QEMU启动内核执行到基于内存的虚拟rootfs就结束了并没有准备真实rootfs。
linux内核镜像可通过编译内核源码获得initramfs可以使用 busybox 来制作。
我的环境
宿主机硬件平台x86_64 宿主机操作系统Ubuntu 20.04 Linux 5.4.0-139-generic QEMU版本qemu-4.2.1 实验内核linux-5.19 busybox版本busybox-1.35.0
安装QEMU
qemu安装方式有两种Linux软件包安装、源码编译安装。
软件包安装
$ sudo apt-get install qemu-system-x86$ qemu-system-x86_64 --version
QEMU emulator version 4.2.1 (Debian 1:4.2-3ubuntu6.24)
Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers源码安装
官方Documentation有详细介绍 Building QEMU for Linux可供参考。
安装依赖项如果不知道自己环境装了没有也可以不急着安装可根据编译错误提示安装对应依赖项即可
sudo apt-get install git libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev ninja-build下载编译
$ mkdir ~/kvm
$ cd ~/kvm/
$ wget https://download.qemu.org/qemu-7.2.0.tar.xz
$ tar -xf qemu-7.2.0.tar.xz
$ cd qemu-7.2.0
$ ./configure --target-listx86_64-softmmu
$ make -jnproc说明
默认会编译所有平台如arm、i386、x86_64等的QEMU这会很慢加上 --target-listx86_64-softmmu 选项只编译我环境所需的 x86_64 版本以加快编译速度。make加上-j选项可加快编译速度nproc命令用于获取可用的CPU核数一般来说-j最大并行任务数可设为CPU数量的2倍。
编译结果在源码目录的build子目录下
$ ./build/qemu-system-x86_64 --version
QEMU emulator version 7.2.0
Copyright (c) 2003-2022 Fabrice Bellard and the QEMU Project developers源码编译过程中我遇到的依赖问题有
报错1
$ ./configure
Using ./build as the directory for build outputERROR: Cannot find Ninja解决1
$ sudo apt-get install ninja-build报错2
$ ./configure
Using ./build as the directory for build outputERROR: glib-2.56 gthread-2.0 is required to compile QEMU解决2
$ sudo apt-get install libglib2.0-dev报错3
$ ./configure
Using ./build as the directory for build output../meson.build:553:2: ERROR: Dependency pixman-1 not found, tried pkgconfigERROR: meson setup failed解决 3
$ sudo apt-get install libpixman-1-dev编译linux内核
$ mkdir ~/kvm
$ cd ~/kvm/
$ wget https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/snapshot/linux-5.19.tar.gz
$ tar -xf linux-5.19.tar.gz
$ cd linux-5.19/
$ make defconfig
$ make menuconfig
$ make -j nproc看到以下日志就表示编译成功
Kernel: arch/x86/boot/bzImage is ready其中bzImage文件就是编译后的内核镜像文件
$ file arch/x86/boot/bzImage
arch/x86/boot/bzImage: Linux kernel x86 boot executable bzImage, version 5.19.0 (kaoyakaoya-Inspiron-7472) #1 SMP PREEMPT_DYNAMIC Mon Feb 27 00:26:06 CST 2023, RO-rootFS, swap_dev 0xA, Normal VGA说明 3. 本次实验make menuconfig并未做任何修改直接选择保存、退出。 4. make加上-j选项可加快编译速度nproc命令用于获取可用的CPU核数一般来说-j最大并行任务数可设为CPU数量的2倍。 5. make过程可能会因为系统缺少依赖项而导致报错根据提示安装对应依赖项即可。
我的环境在make过程中报错及其解决方法如下 $ sudo apt install bison 报错1
$ make defconfig/bin/sh: 1: flex: not found解决1
$ sudo apt install flex报错2
$ make defconfig/bin/sh: 1: bison: not found解决2
在这里插入代码片编译busybox
$ mkdir ~/kvm
$ cd ~/kvm/
$ wget https://busybox.net/downloads/busybox-1.35.0.tar.bz2
$ tar -xf busybox-1.35.0.tar.bz2
$ cd busybox-1.35.0/
$ make menuconfig# 修改配置选中如下项目静态编译
# Settings – Build Options – [*] Build static binaryno share libs# 反选如下项目否则后续qemu执行会提示 /bin/sh:cant access tty;job control turned off
# Shells --- [ ] Job control$ make -j nproc
$ make install装完后会 默认安装到源码目录的 _install/ 目录下
$ ls _install/
bin linuxrc sbin usr最关键的就是_install/bin/busybox其他都是链接文件。
$ file _install/bin/busybox
_install/bin/busybox: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, BuildID[sha1]8be05d97976fc5de35a9ebf2631529223523296f, for GNU/Linux 3.2.0, stripped制作initramfs
使用busybox快速制作initramfs。
创建虚拟rootfs中的inti启动脚本并赋予可执行权限
$ cd ~/kvm/busybox-1.35.0/_install/
$ touch init
$ chmod x init脚本内容
#!/bin/sh# 挂载一些必要的文件系统
mkdir /proc mount -t proc none /proc
mkdir /sys mount -t sysfs none /sys
mkdir /tmp mount -t tmpfs none /tmpecho
echo Hello Linux# 显示开机消耗时间echo This boot took $(cut -d -f1 /proc/uptime) seconds
echo# 停留在控制台
exec /bin/sh制作initramfs文件它是多个文件通过cpio打包和gzip压缩的文件是一个cpio格式的内存文件系统。
$ find . -print0 | cpio --null -ov --formatnewc | gzip -9 ../initramfs.cpio.gz使用QEMU启动linux内核
linux内核镜像和initramfs都准备好就可以使用QEMU启动linux内核了。
以图形界面的方式启动QEMU
$ cd ~/kvm/
$ qemu-system-x86_64 \-kernel ./linux-5.19/arch/x86/boot/bzImage \-initrd ./busybox-1.35.0/initramfs.cpio.gz \-append init/init以字符界面方式启动QEMU不启动图形界面同时日志输出到控制台
$ qemu-system-x86_64 \-kernel ./linux-5.19/arch/x86/boot/bzImage \-initrd ./busybox-1.35.0/initramfs.cpio.gz \-nographic \-append init/init consolettyS0QEMU参数说明更多可参考Standard options
-kernel指定启动的内核镜像-initrd指定启动的内存文件系统-append传递给内核的启动参数启动后可使用cat /proc/cmdline命令核对。-nographic启动字符界面不启动图形界面输出重定向到宿主机命令行与参数 consolettyS0 组合使用
图形界面操作使用工具栏菜单即可字符界面操作使用快捷键如下所示更多可参考Keys in the character backend multiplexer
C-a h print this help C-a x exit emulator C-a s save disk data back to file (if -snapshot) C-a t toggle console timestamps C-a b send break (magic sysrq) C-a c switch between console and monitor C-a C-a sends C-a
简化命令
为了简化命令输入可以创建一个Makefile内容如下
$ vim ~/kvm/Makefileinitramfs:cd busybox-1.35.0/_install/ find . -print0 | cpio --null -ov --formatnewc | gzip -9 ../initramfs.cpio.gzrun-win:qemu-system-x86_64 \-kernel ./linux-5.19/arch/x86/boot/bzImage \-initrd ./busybox-1.35.0/initramfs.cpio.gz \-append init/initrun-console:qemu-system-x86_64 \-kernel ./linux-5.19/arch/x86/boot/bzImage \-initrd ./busybox-1.35.0/initramfs.cpio.gz \-nographic \-append init/init consolettyS0make initramfs制作initramfsmake run-win以图形界面的方式启动QEMUmake run-console以字符界面方式启动QEMU
参考
QEMU官方文档https://www.qemu.org/docs/master/ QEMU维基百科https://wiki.qemu.org/Documentation