当前位置: 首页 > news >正文

QEMU启动x86-Linux内核

目录

  • QEMU简介
  • linux启动流程
  • 我的环境
  • 安装QEMU
    • 软件包安装
    • 源码安装
  • 编译linux内核
  • 编译busybox
  • 制作initramfs
  • 使用QEMU启动linux内核
  • 简化命令
  • 参考


QEMU简介

QEMU(quick emulator)是一个通用的、开源的硬件模拟器,可以模拟不同硬件架构(如x86、ARM、ARM64、MIPS、PowerPC等),是目前比较流行的跨平台仿真软件。

QEMU主要的仿真方式包括:全系统仿真和用户模式仿真。

全系统仿真,QEMU提供了整个机器的虚拟模型(包括CPU、内存和模拟设备等外设)来运行客户操作系统。该模式下,相当于系统级虚拟机。

用户模式仿真,QEMU 允许一个应用程序执行在不同架构的CPU上,该模式下,相当于进程级虚拟机。

在这里插入图片描述

本文介绍如何使用QEMU模拟器启动linux内核,使用的就是QEMU的全系统仿真模式。

linux启动流程

在开始之前,需要了解linux的开机启动流程,详细可自行查阅资料,如《鸟哥的Linux私房菜》的“Linux 的启动流程分析”。简要总结就是:BIOS,MBR,启动Bootloader,加载Kernel,挂载虚拟rootfs,挂载真实rootfs,初始化用户程序(即执行init进程)。

为什么会有虚拟rootfs?这涉及到initrd(全称boot loader initialized RAM disk,初始化的内存盘),RAM disk就是将内存的一部分分配为一个分区并作为磁盘来使用,initrd就是由 boot loader 初始化的内存盘。

initrd出现的背景。

早期,linux系统用于存储rootfs的介质一般只有硬盘或者软盘,内核集成了这些磁盘驱动程序,开机时内核可以直接挂载基于磁盘的rootfs。后来,嵌入式系统可能将rootfs存储到各种介质上,包括IDE、SCSI、SATA,Flash、u-disk等等。如果将所有介质的驱动都编译进内核,内核会越来越臃肿。索性,将所有存储介质的驱动都编译成内核模块并将其ko文件保存在rootfs中,可按需加载。那么问题来了,内核要挂载rootfs就要先加载对应存储介质驱动模块,内核要加载存储介质驱动模块,就要先挂载rootfs。先有鸡还是先有蛋?

为了解决这一矛盾,出现了基于ramdisk的initrd。initrd是一个被压缩过的小型根目录,这个目录中包含了启动阶段中必须的驱动模块,可执行文件和启动脚本。在 Bootloader 配置了 initrd 的情况下,内核启动被分成了两个阶段,第一阶段先挂载基于内存盘的虚拟roofs,把系统内存的一部分作为根文件系统挂载,执行 initrd 文件系统中的启动脚本,完成加载驱动模块等任务,第二阶段才挂载真实rootfs并执行初始化用户程序init 进程。

initrd是基于内存的块设备(即ramdisk),有个缺点就是大小固定,是过时的机制。Linux 2.6开始采用initramfs替换了initrd,initramfs(init 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-list=x86_64-softmmu
$ make -j`nproc`

说明:

  1. 默认会编译所有平台(如arm、i386、x86_64等)的QEMU,这会很慢,加上 --target-list=x86_64-softmmu 选项只编译我环境所需的 x86_64 版本,以加快编译速度。
  2. 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 (kaoya@kaoya-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 binary(no share libs)# 反选如下项目,否则后续qemu执行会提示 /bin/sh:can't 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 --format=newc | 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 console=ttyS0"

QEMU参数说明(更多可参考:Standard options):

  • -kernel:指定启动的内核镜像;
  • -initrd:指定启动的内存文件系统;
  • -append:传递给内核的启动参数;启动后可使用cat /proc/cmdline命令核对。
  • -nographic:启动字符界面(不启动图形界面),输出重定向到宿主机命令行,与参数 console=ttyS0 组合使用;

图形界面操作使用工具栏菜单即可,字符界面操作使用快捷键如下所示(更多可参考: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 --format=newc | 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=/init"run-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 console=ttyS0"
  • make initramfs:制作initramfs;
  • make run-win:以图形界面的方式启动QEMU;
  • make run-console:以字符界面方式启动QEMU;

参考

QEMU官方文档:https://www.qemu.org/docs/master/
QEMU维基百科:https://wiki.qemu.org/Documentation

相关文章:

QEMU启动x86-Linux内核

目录QEMU简介linux启动流程我的环境安装QEMU软件包安装源码安装编译linux内核编译busybox制作initramfs使用QEMU启动linux内核简化命令参考QEMU简介 QEMU(quick emulator)是一个通用的、开源的硬件模拟器,可以模拟不同硬件架构(如…...

C/C++每日一练(20230311)

目录 1. 计算阶乘的和 ★ 2. 基本计算器 ★★★ 3. N皇后 II ★★★ 🌟 每日一练刷题专栏 C/C 每日一练 ​专栏 Python 每日一练 专栏 1. 计算阶乘的和 计算:1!-2!3!-4!5!-6!7!-8!9!-10!,并输出计算结果。 注意:不全是…...

哪个牌子的洗地机耐用?耐用的洗地机推荐

作为当下非常热销的洗地机,它不仅解放了双手,使用也非常的便捷。是生活品质提高的最好代表,但是面对市面上让人眼花缭乱的洗地机,挑选几个来回都决定不了到底入手哪个好!为了能帮助大家选购到合适的洗地机,…...

搭建一个中心化的定时服务

1. 背景 在物联网络,很多设备之间都在进行交互,其中云端在远程交流中起到了很重要的作用。比如,一台设备想进行调温,但是需要知道此时房间的温度,那就需要定时去查询传感器测出来的房间温度,如果温度过高&a…...

【CSS】快速入门笔记

视频链接:https://www.bilibili.com/video/BV1mS4y1Z7Ga/?spm_id_from333.999.0.0&vd_source1ad00d913eae8281cbadad6ae66fb06c 文章目录一、CSS语法1.结构2.样式类型1)内联样式 Inline Style2)内部样式 Internal Style3)外部…...

第161篇 笔记-去中心化的含义

本文主要内容来自Vitalik Buterin的文章。“去中心化”这个词是在加密经济学领域用得最多的一个词,通常也作为辨别区块链的依据。然而,这个词也可能是被定义得最不恰当的一个词。数千小时的研究和价值数十亿美元哈希算力的投入都旨在实现去中心化&#x…...

「计算机组成原理」数据的表示和运算(二)

文章目录五、奇偶校验码六、算术逻辑单元ALU6.1 电路的基本原理6.2 加法器的设计6.2.1 一位全加器6.2.2 串行加法器6.2.3 串行进位的并行加法器6.2.4 并行进位的并行加法器七、补码加减运算器八、标志位的生成九、定点数的移位运算9.1 算数移位9.2 逻辑移位9.3 循环移位五、奇偶…...

建立自己的博客

环境安装: w10系统安装 第一步:安装git Git 官网: https://git-scm.com/ 第二步:安装Node.js Node.js官网:https://nodejs.org/zh-cn/ 使用cmd检测: node -v 第三步:安装Hexo Hexo官网:htt…...

Docker 安装mysql Mac 环境下

已安装桌面端 Docker (Mac安装Docker) 安装方式一 打开链接 https://www.docker.com/products/docker-desktop 选择平台下载 安装方式二 安装homebrew /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/m…...

《C++代码分析》第三回:类成员函数覆盖父类函数的调用(分析this指针的变化)

一、前言 在C的学习中我们知道&#xff0c;子类是可以覆盖父类的方法&#xff0c;这里我们探讨一下子类方法调用父类方法时this指针时如何变化的。 二、示例代码 #include "windows.h" #include "windef.h" #include <iostream> #include <tch…...

Altium designer--软件简介及安装教程(Altium designer16)

一、软件介绍&#xff08;完整安装包资源见文末链接&#xff0c;含破解license&#xff09; Altium Designer 是一款简单易用、原生3D设计增强的一体化设计环境&#xff0c;结合了原理图、ECAD库、规则和限制条件、BoM、供应链管理、ECO流程和世界一流的PCB设计工具。通过原理…...

Windows系统下基于开源软件的多物理场仿真

Windows系统下基于开源软件的多物理场仿真实践技术应用随着计算机技术的发展&#xff0c;计算机仿真技术日益成为继实验和理论之后的第三种重要研究和设计手段。真实世界中遇到的问题往往是固体力学&#xff0c;流体力学&#xff0c;热&#xff0c;电磁等多种现象耦合而成&…...

【STL】list剖析及模拟实现

✍作者&#xff1a;阿润菜菜 &#x1f4d6;专栏&#xff1a;C 初识list 1. list基本概况 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立…...

Go打包附件内容到执行文件

前言 如果我们的应用在启动的时候需要对数据库进行初始化(比如建表等), 可以通过读取.sql文件内容直接执行. 但是, 这样会带出一个问题: 在发送可执行文件的时候, 需要连带着附件文件, 并且相对路径还不能出错. 这样太麻烦了有时我们并不希望附件的内容被使用者看到 处于种种…...

Spring的配置属性

介绍 以前都是用XML来设置属性值&#xff0c;SpringBoot的自动配置可以简化Spring应用的开发。配置属性只是配置Spring应用上下文中bean的属性而已&#xff0c;可以通过多个源来配置&#xff0c;包括JVM系统属性、环境变量等。 Spring中有两种不同(但相关)的配置 bean装配&…...

132.《render-props, Hoc,自定义hooks 详解》

文章目录render-props 模式props 方式children 方式(推荐)Hoc&#xff08;高阶组件&#xff09;使用步骤示例props 丢失解决方案自定义 hook1.只执行一次2.防抖hook高阶组件与自定义hook有什么区别相同点不同点React 中代码逻辑复用有三种方式&#xff0c;render-props, Hoc&am…...

通过Session共享数据验证码进行用户登录

通过Session共享数据验证码进行用户登录 需求&#xff1a; 访问带有验证码的登录页面login.jsp。用户输入用户名&#xff0c;密码以及验证码。 ①。如果用户名和密码输入有误&#xff0c;跳转登陆页面&#xff0c;提示&#xff1a;用户名或密码错误。 ②。如果验证码输入有误…...

C++STL详解(六)——stack和queue

文章目录空间适配器stackstack的定义方式stack的使用stack的模拟实现queuequeue的定义方式queue的使用queue的模拟实现空间适配器 适配器是一种设计模式&#xff08;设计模式是一套被反复使用的&#xff0c;多数人知晓的&#xff0c;经过分类编目的&#xff0c;代码设计经验的…...

javaEE 初阶 — CSS 的 基本语法 与 引入方式

文章目录1. 基本语法规范2. 三种引入方式1. 基本语法规范 CSS 的基本语法规范是由 选择器 和 若干个声明 组成的。 选择器选中一个元素之后&#xff0c;这些属性都是针对于这个元素展开的。 先来看一个没有 CSS 的效果。 <body><p>这是一个段落</p> </bo…...

QEMU启动ARM32 Linux内核

目录前言前置知识ARM Versatile Express开发板简介ARM处理器家族简介安装qemu-system-arm安装交叉编译工具交叉编译ARM32 Linux内核交叉编译ARM32 Busybox使用busybox制作initramfs使用QEMU启动ARM32 Linux内核模拟vexpress-a9开发板模拟vexpress-a15开发板参考前言 本文介绍采…...

终极指南:如何在Open Interpreter中快速集成vLLM高速推理引擎

终极指南&#xff1a;如何在Open Interpreter中快速集成vLLM高速推理引擎 【免费下载链接】open-interpreter Open Interpreter 工具能够让大型语言模型在本地执行如Python、JavaScript、Shell等多种编程语言的代码。 项目地址: https://gitcode.com/GitHub_Trending/op/open…...

Zotero Style插件:如何通过3个核心功能让文献管理效率提升200%?

Zotero Style插件&#xff1a;如何通过3个核心功能让文献管理效率提升200%&#xff1f; 【免费下载链接】zotero-style zotero-style - 一个 Zotero 插件&#xff0c;提供了一系列功能来增强 Zotero 的用户体验&#xff0c;如阅读进度可视化和标签管理&#xff0c;适合研究人员…...

3分钟掌握Chrome密码提取:ChromePass让你不再遗忘任何登录凭据

3分钟掌握Chrome密码提取&#xff1a;ChromePass让你不再遗忘任何登录凭据 【免费下载链接】chromepass Get all passwords stored by Chrome on WINDOWS. 项目地址: https://gitcode.com/gh_mirrors/chr/chromepass 你是否曾经在登录网站时&#xff0c;明明记得在Chrom…...

Simulink频域分析避坑指南:如何准确获取谐振频率(含MATLAB代码)

Simulink频域分析实战&#xff1a;谐振频率精准提取方法论与MATLAB实现 在控制系统设计与分析领域&#xff0c;频域特性是评估系统动态性能的核心指标之一。而谐振频率作为频域响应中的关键特征点&#xff0c;直接影响着系统的稳定性和响应速度。然而&#xff0c;许多工程师在使…...

158.基于matlab的用于分析弧齿锥齿轮啮合轨迹的输出齿轮啮合轨迹及传递误差程序已调通

158.基于matlab的用于分析弧齿锥齿轮啮合轨迹的输出齿轮啮合轨迹及传递误差程序已调通&#xff0c;可直接运行1. 引言&#xff1a;TCA技术的重要性与挑战 弧齿锥齿轮作为机械传动系统的核心部件&#xff0c;其啮合质量直接影响整个传动装置的可靠性、效率和使用寿命。齿面接触分…...

嵌入式AI边缘计算原型:STM32与云端PyTorch模型协同工作流设计

嵌入式AI边缘计算原型&#xff1a;STM32与云端PyTorch模型协同工作流设计 1. 场景需求与痛点分析 在智能家居、工业监测等物联网场景中&#xff0c;我们常常遇到这样的矛盾&#xff1a;边缘设备需要实时响应&#xff0c;但计算能力有限&#xff1b;云端算力强大&#xff0c;但…...

工厂里EtherCAT从站模块坏了别慌!手把手教你用Startup list和CoE-online快速换新(附配置顺序避坑指南)

工厂EtherCAT从站模块更换实战指南&#xff1a;Startup list与CoE-online的高效应用 当生产线上的EtherCAT从站模块突然罢工&#xff0c;设备维护工程师往往面临两难选择&#xff1a;是临时在线修改参数快速恢复生产&#xff0c;还是彻底解决"即插即用"的配置难题&am…...

OpenProject全球化协作本地化策略指南:打破语言壁垒的实战方案

OpenProject全球化协作本地化策略指南&#xff1a;打破语言壁垒的实战方案 【免费下载链接】openproject OpenProject is the leading open source project management software. 项目地址: https://gitcode.com/GitHub_Trending/op/openproject OpenProject作为领先的开…...

MATLAB图像处理实战:用imfindcircles快速定位硬币边缘(附完整代码)

MATLAB图像处理实战&#xff1a;用imfindcircles快速定位硬币边缘&#xff08;附完整代码&#xff09; 在工业检测和医学影像分析中&#xff0c;圆形物体的精准定位往往是关键的第一步。无论是生产线上的硬币质量检查&#xff0c;还是显微镜下的细胞计数&#xff0c;快速准确地…...

Swift-All镜像入门:手把手教你快速部署,无需配置轻松上手

Swift-All镜像入门&#xff1a;手把手教你快速部署&#xff0c;无需配置轻松上手 想体验600大模型和300多模态模型的强大能力&#xff0c;却被复杂的安装配置劝退&#xff1f;Swift-All镜像就是为你准备的"开箱即用"解决方案。本文将带你从零开始&#xff0c;一步步…...