Linux_KVM虚拟化源代码分析
- 格式:pdf
- 大小:591.93 KB
- 文档页数:20
KVM的工作原理KVM(Kernel-based Virtual Machine)是一种开源的虚拟化技术,它允许在一台物理主机上运行多个虚拟机。
KVM的工作原理可以分为三个主要方面:硬件虚拟化支持、内核模块和用户空间工具。
1. 硬件虚拟化支持:KVM利用现代处理器的硬件虚拟化技术(如Intel的VT-x和AMD的AMD-V)来提供虚拟化的基础。
这些技术允许虚拟机在物理主机上直接运行,并提供了对虚拟机的隔离和保护。
硬件虚拟化支持包括虚拟化扩展、虚拟I/O设备和内存管理。
2. 内核模块:KVM是一个内核模块,它与Linux内核紧密集成。
当KVM模块加载到内核中时,它将Linux内核转变为一个虚拟化管理程序。
KVM通过使用虚拟CPU (vCPU)和虚拟内存管理单元(MMU)来为每个虚拟机提供运行环境。
KVM还负责处理虚拟机的调度、内存管理和设备模拟等任务。
3. 用户空间工具:KVM提供了一组用户空间工具,用于管理和配置虚拟机。
其中最重要的工具是QEMU(Quick EMUlator),它是一个开源的虚拟机监控程序。
QEMU提供了虚拟机的设备模拟、磁盘和网络的管理等功能。
除了QEMU,KVM还提供了一些命令行工具(如kvm、kvm_stat和kvm_host)和图形界面工具(如virt-manager和virt-viewer)。
KVM的工作流程如下:1. 用户通过管理工具(如virt-manager)创建虚拟机配置文件,并指定虚拟机的硬件配置、磁盘映像和网络设置等。
2. KVM模块加载到Linux内核中,并创建一个虚拟化环境。
3. 当用户启动虚拟机时,KVM模块会为虚拟机创建一个vCPU,并将虚拟机的代码和数据加载到虚拟内存中。
4. 虚拟机的代码在vCPU上运行,并通过KVM模块与物理主机的硬件进行交互。
KVM模块负责将虚拟机的指令翻译为物理主机的指令,并将虚拟机的内存访问映射到物理主机的内存。
5. 虚拟机的设备模拟由QEMU负责。
详解虚拟化技术QEMU-KVM⼊门⼀.QEMU、KVM、QEMU-KVMQEMU提供⼀系列的硬件模拟设备(CPU,⽹卡,磁盘等),客户机指令都需要QEMU翻译,因⽽性能较差。
KVM是linux内核提供的虚拟化,可以⽤来进⾏vCPU的创建与运⾏,虚拟内存的地址空间分配,指令执⾏效率较⾼,但缺少IO设备的虚拟化。
QEMU-KVM就是KVM与QEMU的结合,KVM负责CPU虚拟化+内存虚拟化,QEMU模拟其它IO设备。
⼆.安装并创建虚拟机安装qemu-kvm软件faramita2016@linux-l9e6:~> zypper install qemu-kvm // Ubuntu系统使⽤apt-get install qemu-kvm创建qcow2格式虚拟机磁盘⽂件faramita2016@linux-l9e6:~> qemu-img create -f qcow2 vdisk.img 5G // 磁盘⼤⼩5G使⽤debian镜像安装虚拟机,order=dc优先使⽤CD-ROW(d),后使⽤硬盘(c),内存默认128m,使⽤-m 512指定faramita2016@linux-l9e6:~> qemu-kvm -cpu host -cdrom debian-9.4.0.iso -hda vdisk.img -boot order=dc三.设置虚拟机使⽤⽹桥bridge模式宿主机中执⾏,qemu-bridge-helper增加当前⽤户可执⾏权限,⽤来⾃动添加⽹络后端tap设备faramita2016@linux-l9e6:~> sudo chmod o+x /usr/lib/qemu-bridge-helper宿主机中执⾏,-net nic为虚拟机创建nic⽹卡(⽹络前端),-net bridge指定宿主机中使⽤⽹桥(⽹络后端)faramita2016@linux-l9e6:~> qemu-kvm -cpu host -hda vdisk.img -net nic -net bridge,br=br0 // 指定⽹桥br0虚拟机中执⾏,编辑/etc/network/interfaces,设置静态IProot@debian:~# vi /etc/network/interfaces# The primary network interfaceallow-hotplug ens3#iface ens3 inet dhcpiface ens3 inet staticaddress 10.0.0.8netmask 255.0.0.0gateway 10.0.0.1hwaddress ether 52:54:00:12:34:56 // 设置mac地址,前3组不变root@debian:~# ifup ens3 // 打开ens3⽹络接⼝,ifdown关闭⽹络接⼝root@debian:~# /etc/init.d/networking restart // 重启⽹络服务虚拟机中执⾏,编辑/etc/resolv.conf,设置DNSroot@debian:~# vi /etc/resolv.confnameserver 8.8.8.8 // Google DNS四.设置虚拟机为⾮图形模式虚拟机中执⾏,编辑/etc/default/grub⽂件,添加console=ttyS0启动参数root@debian:~# vi /etc/default/grubGRUB_DEFAULT=0 // 默认启动项GRUB_TIMEOUT=0 // 默认菜单项停留时间GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`GRUB_CMDLINE_LINUX_DEFAULT="quiet" // 默认内核启动参数GRUB_CMDLINE_LINUX="console=ttyS0" // ⼿动添加内核启动参数,添加console=ttyS0虚拟机中执⾏,更新grub配置,并重启root@debian:~# update-grubroot@debian:~# shutdown -h nowa.宿主机中执⾏,添加-nographic参数创建虚拟机,当前shell前台创建虚拟机faramita2016@linux-l9e6:~> qemu-kvm -cpu host -hda vdisk.img -net nic -net bridge,br=br0 -nographicb.宿主机中执⾏,添加-display none -daemonize参数创建虚拟机,当前shell后台创建虚拟机faramita2016@linux-l9e6:~> qemu-kvm -cpu host -hda vdisk.img -net nic -net bridge,br=br0 -display none -daemonize五.以只读⽅式启动虚拟机a.创建⼀个快照⽤qemu-img命令创建⼀个原始镜像的快照faramita2016@linux-l9e6:~> qemu-img create -f qcow2 -b vdisk.img snapshot.img使⽤快照⽂件启动虚拟机faramita2016@linux-l9e6:~> qemu-kvm -cpu host -hda snapshot.img -net nic -net bridge,br=br0 -nographicb.使⽤临时快照原理:创建⼀个临时快照,虚拟机启动之后,⾃动删除快照⽂件faramita2016@linux-l9e6:~> qemu-kvm -cpu host -hda vdisk.img -net nic -net bridge,br=br0 -snapshot -nographic以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
kvm虚拟化工作原理KVM虚拟化工作原理KVM是一种开源的虚拟化技术,它是Linux内核中自带的一种虚拟化模块。
KVM全称为Kernel-based Virtual Machine,即基于内核的虚拟机。
它可以将物理服务器划分为多个独立的虚拟机,每个虚拟机都可以运行不同的操作系统和应用程序。
本文将详细介绍KVM虚拟化工作原理。
1. KVM架构KVM架构主要由三部分组成:Linux内核、QEMU和libvirt。
其中,Linux内核提供了硬件抽象层和CPU虚拟化技术,QEMU提供了设备模型和磁盘映像管理等功能,libvirt则是一个高级API,用于管理虚拟机生命周期、配置和监控等。
2. KVM CPU虚拟化CPU虚拟化是KVM最重要的部分之一。
在CPU虚拟化中,KVM利用了Intel VT或AMD-V等硬件扩展来实现对CPU资源的管理。
这些硬件扩展提供了一种称为“硬件辅助的虚拟化技术”,使得操作系统可以在不知道自己被虚拟化的情况下运行。
具体来说,在CPU虚拟化中,KVM将每个虚拟机视为一个独立的进程,并为其分配一组虚拟CPU。
当虚拟机运行时,KVM会将虚拟CPU指令转换为物理CPU指令,并利用硬件扩展提供的特殊指令来实现对CPU资源的隔离和管理。
这样,每个虚拟机就可以像运行在物理服务器上一样运行。
3. KVM设备模型KVM设备模型是QEMU的一部分,它提供了对各种设备(如磁盘、网卡、USB等)的模拟和管理。
在设备模型中,每个虚拟机都被视为一个独立的计算机系统,具有自己的设备树和驱动程序。
具体来说,在设备模型中,QEMU会模拟各种硬件设备,并将其映射到虚拟机中。
例如,在磁盘映像管理中,QEMU会将虚拟机硬盘映像文件与物理服务器上的实际磁盘进行关联,并通过驱动程序来实现数据读写等操作。
4. KVM网络管理KVM网络管理是指对虚拟网络进行配置和管理。
在KVM中,每个虚拟机都可以配置多个网络接口,并且可以使用不同类型的网络连接方式(如桥接、NAT等)。
Linux KVM虚拟机PVE使用指南1引言KVM (全称是 Kernel-based Virtual Machine) 是 Linux 下 x86 硬件平台上的全功能虚拟化解决方案,包含一个可加载的内核模块 kvm.ko 提供和虚拟化核心架构和处理器规范模块。
使用 KVM 可允许多个包括 Linux 和 Windows 每个虚拟机有私有的硬件,包括网卡、磁盘以及图形适配卡等PVE使用图形化安装方式,支持裸机安装,管理界面是WEB方式,易于操作,浏览器(fireox,chrome等)支持JAVA即可以进行guest OS的图形管理,无须安装客户端,方便快捷。
本文将详细介绍PVE的安装,使用,部署优化等各方面的内容。
2KVM/QEMU体系架构2.1总体架构QEMU作为一个开源的硬件模拟器项目,除了支持x86体系架构之外,还支持ARM、MIPS、PowerPC、IA64等多种硬件架构。
QEMU采用模块化设计的方法,因此,还能支持多种多样的外设硬件,并且能够方便地进行扩充。
除了支持KVM之外,QEMU还支持全模拟化和kqemu加速模块等方式,这三种方式的架构区别如图5-6所示。
第一种模式是通过kqemu模块实现内核态的加速。
通过在内核中加入kqemu 的相关模块,在用户态的QEMU则通过访问/dev/kqemu设备文件接口调用改进型加速。
在这种模式中,主要针对虚拟机和宿主机运行于统一架构的情况下进行虚拟化。
第二种模式是在用户态直接运行QEMU,由QEMU对目标机的所有指令进行翻译后执行,相当于全虚拟化。
在这种模式下,可以运行各种不同形态的体系结构,如Android开发环境中即使用了QEMU来为其模拟ARM运行环境,但是在这种模拟环境下,每一条目标机的执行指令都需要耗费少则数个,多则成千上万个宿主机的指令周期来模拟实现,速度方面不太理想。
第三种模式则是KVM官方提供的kvm-qemu加速模式。
运行在内核态的KVM 模块通过/dev/kvm字符设备文件向外提供操作接口。
kvm 模块编译一、什么是 kvm 模块KVM(Kernel-based Virtual Machine)是一个开源的全虚拟化解决方案,它是Linux 内核的一部分,通过将虚拟化功能直接集成到内核中,提供了一种轻量级的虚拟化解决方案。
kvm 模块是用于在 Linux 内核中支持虚拟化的模块,它提供了一组接口和功能,使得用户能够使用 KVM 技术创建和管理虚拟机。
二、为什么需要编译 kvm 模块在大多数 Linux 发行版中,kvm 模块通常是作为内核的一个模块提供的,而不是默认内核的一部分。
因此,如果我们想要使用 KVM 技术创建和管理虚拟机,就需要在 Linux 内核中编译并加载 kvm 模块。
编译 kvm 模块的好处是可以根据自己的需要定制内核,只包含所需的模块,从而提高系统的性能和安全性。
此外,编译 kvm 模块还可以解决一些兼容性问题,确保 kvm 模块与当前系统环境的兼容性。
三、编译 kvm 模块的步骤下面是编译 kvm 模块的详细步骤:1. 准备编译环境在开始编译 kvm 模块之前,我们需要确保系统中已经安装了所需的编译工具和依赖项。
通常情况下,需要安装以下软件包:•gcc:C 语言编译器•make:构建工具•kernel-devel:内核开发包2. 下载内核源代码在编译 kvm 模块之前,我们需要下载与当前运行的内核版本相对应的内核源代码。
可以从 Linux 内核的官方网站或者使用发行版提供的工具下载内核源代码。
3. 配置内核编译选项进入内核源代码目录,并执行以下命令来配置内核编译选项:make menuconfig在配置界面中,可以根据需要选择和定制所需的功能和模块。
确保启用 kvm 模块和相关的虚拟化选项。
4. 编译内核配置完成后,执行以下命令来编译内核:make这个过程可能需要一些时间,取决于系统的配置和硬件性能。
5. 编译 kvm 模块编译完成后,进入 kvm 模块的源代码目录,并执行以下命令来编译 kvm 模块:make6. 安装 kvm 模块编译完成后,执行以下命令来安装 kvm 模块:make install这将把 kvm 模块复制到系统的模块目录中,并更新内核的模块依赖关系。
Linux KVM虚拟机PVE使用指南1引言KVM (全称是 Kernel-based Virtual Machine) 是 Linux 下 x86 硬件平台上的全功能虚拟化解决方案,包含一个可加载的内核模块 kvm.ko 提供和虚拟化核心架构和处理器规范模块。
使用 KVM 可允许多个包括 Linux 和 Windows 每个虚拟机有私有的硬件,包括网卡、磁盘以及图形适配卡等PVE使用图形化安装方式,支持裸机安装,管理界面是WEB方式,易于操作,浏览器(fireox,chrome等)支持JAVA即可以进行guest OS的图形管理,无须安装客户端,方便快捷。
本文将详细介绍PVE的安装,使用,部署优化等各方面的内容。
2KVM/QEMU体系架构2.1总体架构QEMU作为一个开源的硬件模拟器项目,除了支持x86体系架构之外,还支持ARM、MIPS、PowerPC、IA64等多种硬件架构。
QEMU采用模块化设计的方法,因此,还能支持多种多样的外设硬件,并且能够方便地进行扩充。
除了支持KVM之外,QEMU还支持全模拟化和kqemu加速模块等方式,这三种方式的架构区别如图5-6所示。
第一种模式是通过kqemu模块实现内核态的加速。
通过在内核中加入kqemu 的相关模块,在用户态的QEMU则通过访问/dev/kqemu设备文件接口调用改进型加速。
在这种模式中,主要针对虚拟机和宿主机运行于统一架构的情况下进行虚拟化。
第二种模式是在用户态直接运行QEMU,由QEMU对目标机的所有指令进行翻译后执行,相当于全虚拟化。
在这种模式下,可以运行各种不同形态的体系结构,如Android开发环境中即使用了QEMU来为其模拟ARM运行环境,但是在这种模拟环境下,每一条目标机的执行指令都需要耗费少则数个,多则成千上万个宿主机的指令周期来模拟实现,速度方面不太理想。
第三种模式则是KVM官方提供的kvm-qemu加速模式。
运行在内核态的KVM 模块通过/dev/kvm字符设备文件向外提供操作接口。
Linux的虚拟化技术Linux是一款流行的开源操作系统,在全球范围内受到广泛应用。
它拥有许多强大的功能和工具,因此成为许多企业和个人用户的首选系统。
其中一个最重要的特点就是它的虚拟化技术。
在这篇文章中,我们将介绍Linux的虚拟化技术,并探讨它们的应用和优势。
虚拟化技术的意义虚拟化技术是一种使物理计算机能够运行多个虚拟计算机的技术。
这种技术基于将多个模拟的计算机系统运行在一个实际的物理计算机系统上。
这种技术是现代计算机系统中非常重要的一项技术,它给用户和企业带来了许多好处。
首先,虚拟化技术可以消除物理计算机数量的限制。
由于虚拟化技术允许在一个机器上运行多个虚拟机,因此用户可以利用资源更加高效地工作,节省大量的硬件驱动和空间。
同时,虚拟化技术也可以提高整个系统的安全性,特别是当多个虚拟机运行在同一台物理计算机上时。
其次,虚拟化技术可以简化整个系统的管理。
由于虚拟化技术可以将多个系统合并在一起,因此减少了对不同系统的升级、维护和备份的需求。
而且,涉及管理的工作也可以变得更加简单。
如何实现虚拟化?在Linux中,有几个不同的虚拟化技术可供选择。
下面介绍最常用的几个技术。
1.KVMKVM是"Kernel-based Virtual Machine"(基于内核的虚拟机)的缩写。
它是一种用于Linux的开源虚拟化技术。
KVM利用Linux的硬件虚拟化技术和虚拟化命令集来允许多个虚拟机共享一个物理计算机上的资源。
KVM通常用于基于x86架构的系统,这也是它在Linux系统中最受欢迎的虚拟化技术。
KVM的优点包括:- 支持多种虚拟机类型和操作系统- 可以优化虚拟机的性能- 可以提供安全的虚拟化环境2.XenXen是另一种广受欢迎的开源虚拟化技术。
它采用了自主架构和虚拟机监视器(hypervisor)来实现虚拟化。
Xen经常用于虚拟化基于x86架构的系统以及ARM架构的系统。
Xen的优点包括:- 高性能虚拟机- 简化虚拟机的管理- 完全自由和可定制的虚拟机3. LXCLXC是"Linux Containers"(Linux容器)的缩写。
一些关于kvm和vmware虚拟化原理的总结KVM(Kernel-based Virtual Machine)和VMware都是虚拟化技术的代表性实现,它们在实现虚拟化的原理和架构上有一些共通之处,同时也有一些不同之处。
以下是关于KVM和VMware虚拟化原理的一些总结:共通之处:1.硬件虚拟化支持:KVM和VMware都利用硬件虚拟化扩展,如Intel的VT-x和AMD的AMD-V,以提高虚拟化性能和效率。
2.Hypervisor:两者都采用Hypervisor技术,将物理服务器划分为多个虚拟机(VM),每个VM独立运行。
3.虚拟机监控程序:Hypervisor作为虚拟机监控程序(VMM)来管理和调度虚拟机的资源。
4.虚拟设备模拟:KVM和VMware会模拟虚拟设备,使得虚拟机能够与这些虚拟设备进行交互,而不必依赖于物理硬件。
KVM 的特点:1.嵌入于Linux 内核:KVM是Linux内核的一部分,利用了Linux内核的特性。
它允许Linux主机作为Hypervisor,并在每个虚拟机中运行一个独立的Linux内核。
2.QEMU 协作:KVM通常与QEMU(Quick Emulator)结合使用,QEMU提供了虚拟机模拟和设备模拟的功能。
3.开源:KVM是开源的,作为Linux内核的一部分,具有开放源代码的特点,这使得用户能够自定义和修改虚拟化环境。
VMware 的特点:1.独立Hypervisor:VMware通常使用独立的Hypervisor,例如ESXi,它直接运行在硬件上,而不需要基于主机操作系统。
2.vSphere 套件:VMware提供了完整的虚拟化解决方案,包括vSphere套件,提供了广泛的管理和监控工具,用于创建、部署和管理虚拟机。
3.vMotion 和DRS:VMware引入了先进的功能,如vMotion(虚拟机迁移)和DRS(动态资源调度),使虚拟机能够在物理主机之间自动迁移以实现负载均衡。
深入分析Linux内核源码前言第一章走进linux1.1 GNU与Linux的成长1.2 Linux的开发模式和运作机制1.3走进Linux内核1.3.1 Linux内核的特征1.3.2 Linux内核版本的变化1.4 分析Linux内核的意义1.4.1 开发适合自己的操作系统1.4.2 开发高水平软件1.4.3 有助于计算机科学的教学和科研1.5 Linux内核结构1.5.1 Linux内核在整个操系统中的位置1.5.2 Linux内核的作用1.5.3 Linux内核的抽象结构1.6 Linux内核源代码1.6.1 多版本的内核源代码1.6.2 Linux内核源代码的结构1.6.3 从何处开始阅读源代码1.7 Linux内核源代码分析工具1.7.1 Linux超文本交叉代码检索工具1.7.2 Windows平台下的源代码阅读工具Source Insight第二章Linux运行的硬件基础2.1 i386的寄存器2.1.1通用寄存器2.1.2段寄存器2.1.3状态和控制寄存器2.1.4 系统地址寄存器2.1.5 调试寄存器和测试寄存器2.2 内存地址2.3 段机制和描述符2.3.1 段机制2.3.2 描述符的概念2.3.3系统段描述符2.3.4 描述符表2.3.5 选择符与描述符表寄存器2.3.6 描述符投影寄存器2.3.7 Linux中的段2.4 分页机制2.4.1 分页机构2.4.2页面高速缓存2.5 Linux中的分页机制2.5.1 与页相关的数据结构及宏的定义2.5.2 对页目录及页表的处理2.6 Linux中的汇编语言2.6.1 A T&T与Intel汇编语言的比较2.6.2 A T&T汇编语言的相关知识2.6.3 Gcc嵌入式汇编2.6.4 Intel386汇编指令摘要第三章中断机制3.1 中断基本知识3.1.1 中断向量3.1.2 外设可屏蔽中断3.1.3异常及非屏蔽中断3.1.4中断描述符表3.1.5 相关汇编指令3.2中断描述符表的初始化3.2. 1 外部中断向量的设置3.2.2中断描述符表IDT的预初始化3.2.3 中断向量表的最终初始化3.3异常处理3.3.1 在内核栈中保存寄存器的值3.3.2 中断请求队列的初始化3.3.3中断请求队列的数据结构3.4 中断处理3.4.1中断和异常处理的硬件处理3.4.2 Linux对异常和中断的处理3.4.3 与堆栈有关的常量、数据结构及宏3.4.4 中断处理程序的执行3.4.5 从中断返回3.5中断的后半部分处理机制3.5.1 为什么把中断分为两部分来处理3.5.2 实现机制3.5.3数据结构的定义3.5.4 软中断、bh及tasklet的初始化3.5.5后半部分的执行3.5.6 把bh移植到tasklet第四章进程描述4.1 进程和程序(Process and Program)4.2 Linux中的进程概述4.3 task_struct结构描述4.4 task_struct结构在内存中的存放4.4.1 进程内核栈4.4.2 当前进程(current宏)4.5 进程组织的方式4.5.1哈希表4.5.2双向循环链表4.5.3 运行队列4.5.4 等待队列4.6 内核线程4.7 进程的权能4.8 内核同步4.8.1信号量4.8.2原子操作4.8.3 自旋锁、读写自旋锁和大读者自旋锁4.9 本章小节第五章进程调度5.1 Linux时间系统5.1.1 时钟硬件5.1.2 时钟运作机制5.1.3 Linux时间基准5.1.4 Linux的时间系统5.2 时钟中断5.2.1 时钟中断的产生5.2.2.Linux实现时钟中断的全过程5.3 Linux的调度程序-Schedule( )5.3.1 基本原理5.3.2 Linux进程调度时机5.3.3 进程调度的依据5.3.4 进程可运行程度的衡量5.3.5 进程调度的实现5.4 进程切换5.4.1 硬件支持5.4.2 进程切换第六章Linux内存管理6.1 Linux的内存管理概述6.1.1 Linux虚拟内存的实现结构6.1.2 内核空间和用户空间6.1.3 虚拟内存实现机制间的关系6.2 Linux内存管理的初始化6.2.1 启用分页机制6.2.2 物理内存的探测6.2.3 物理内存的描述6.2.4 页面管理机制的初步建立6.2.5页表的建立6.2.6内存管理区6.3 内存的分配和回收6.3.1 伙伴算法6.3.2 物理页面的分配和释放6.3.3 Slab分配机制6.4 地址映射机制6.4.1 描述虚拟空间的数据结构6.4.2 进程的虚拟空间6.4.3 内存映射6.5 请页机制6.5.1 页故障的产生6.5.2 页错误的定位6.5.3 进程地址空间中的缺页异常处理6.5.4 请求调页6.5.5 写时复制6.6 交换机制6.6.1 交换的基本原理6.6.2 页面交换守护进程kswapd6.6.3 交换空间的数据结构6.6.4 交换空间的应用6.7 缓存和刷新机制6.7.1 Linux使用的缓存6.7.2 缓冲区高速缓存6.7.3 翻译后援存储器(TLB)6.7.4 刷新机制6.8 进程的创建和执行6.8.1 进程的创建6.8.2 程序执行6.8.3 执行函数第七章进程间通信7.1 管道7.1.1 Linux管道的实现机制7.1.2 管道的应用7.1.3 命名管道(FIFO)7.2 信号(signal)7.2.1 信号种类7.2.2 信号掩码7.2.3 系统调用7.2.4 典型系统调用的实现7.2.5 进程与信号的关系7.2.6 信号举例7.3 System V 的IPC机制7.3.1 信号量7.3.2 消息队列7.3.3 共享内存第八章虚拟文件系统8.1 概述8.2 VFS中的数据结构8.2.1 超级块8.2.2 VFS的索引节点8.2.3 目录项对象8.2.4 与进程相关的文件结构8.2.5 主要数据结构间的关系8.2.6 有关操作的数据结构8.3 高速缓存8.3.1 块高速缓存8.3.2 索引节点高速缓存8.3.3 目录高速缓存8.4 文件系统的注册、安装与拆卸8.4.1 文件系统的注册8.4.2 文件系统的安装8.4.3 文件系统的卸载8.5 限额机制8.6 具体文件系统举例8.6.1 管道文件系统pipefs8.6.2 磁盘文件系统BFS8.7 文件系统的系统调用8.7.1 open 系统调用8.7.2 read 系统调用8.7.3 fcntl 系统调用8 .8 Linux2.4文件系统的移植问题第九章Ext2文件系统9.1 基本概念9.2 Ext2的磁盘布局和数据结构9.2.1 Ext2的磁盘布局9.2.2 Ext2的超级块9.2.3 Ext2的索引节点9.2.4 组描述符9.2.5 位图9.2.6 索引节点表及实例分析9.2.7 Ext2的目录项及文件的定位9.3 文件的访问权限和安全9.4 链接文件9.5 分配策略9.5.1 数据块寻址9.5.2 文件的洞9.5.3 分配一个数据块第十章模块机制10.1 概述10.1.1 什么是模块10.1.2 为什么要使用模块?10.2 实现机制10.2.1 数据结构10.2.2 实现机制的分析10.3 模块的装入和卸载10.3.1 实现机制10.3.2 如何插入和卸载模块10.4 内核版本10.4.1 内核版本与模块版本的兼容性10.4.2 从版本2.0到2.2内核API的变化10.4.3 把内核2.2移植到内核2.410.5 编写内核模块10.5.1 简单内核模块的编写10.5.2 内核模块的Makefiles文件10.5.3 内核模块的多个文件第十一章设备驱动程序11.1 概述11.1.1 I/O软件11.1.2 设备驱动程序11.2 设备驱动基础11.2.1 I/O端口11.2.2 I/O接口及设备控制器11.2.3 设备文件11.2.4 VFS对设备文件的处理11.2.5 中断处理11.2.6 驱动DMA工作11.2.7 I/O 空间的映射11.2.8 设备驱动程序框架11.3 块设备驱动程序11.3.1 块设备驱动程序的注册11.3.2 块设备基于缓冲区的数据交换11.3.3 块设备驱动程序的几个函数11.3.4 RAM 盘驱动程序的实现11.3.5 硬盘驱动程序的实现11.4 字符设备驱动程序11.4.1 简单字符设备驱动程序11.4.2 字符设备驱动程序的注册11.4.3 一个字符设备驱动程序的实例11.4.4 驱动程序的编译与装载第十二章网络12.1 概述12.2 网络协议12.2.1 网络参考模型12.2.2 TCP/IP协议工作原理及数据流12.2.3 Internet 协议12.2.4 TCP协议12.3 套接字(socket)12.3.1 套接字在网络中的地位和作用12.3.2 套接字接口的种类12.3.3 套接字的工作原理12.3.4 socket 的通信过程12.3.5 socket为用户提供的系统调用12.4 套接字缓冲区(sk_buff)12.4.1 套接字缓冲区的特点12.4.2 套接字缓冲区操作基本原理12.4.3 sk_buff数据结构的核心内容12.4.4 套接字缓冲区提供的函数12.4.5 套接字缓冲区的上层支持例程12.5 网络设备接口12.5.1 基本结构12.5.2 命名规则12.5.3 设备注册12.5.4 网络设备数据结构12.5.5 支持函数第十三章启动系统13.1 初始化流程13.1.1 系统加电或复位13.1.2 BIOS启动13.1.3 Boot Loader13.1.4 操作系统的初始化13.2 初始化的任务13.2.1 处理器对初始化的影响13.2.2 其他硬件设备对处理器的影响13.3 Linux 的Boot Loarder13.3.1 软盘的结构13.3.2 硬盘的结构13.3.3 Boot Loader13.3.4 LILO13.3.5 LILO的运行分析13.4 进入操作系统13.4.1 Setup.S13.4.2 Head.S13.5 main.c中的初始化13.6 建立init进程13.6.1 init进程的建立13.6.2 启动所需的Shell脚本文件附录:1 Linux 2.4内核API2.1驱动程序的基本函数2.2 双向循环链表的操作2.3 基本C库函数2.4 Linux内存管理中Slab缓冲区2.5 Linux中的VFS2.6 Linux的连网2.7 网络设备支持2.8 模块支持2.9 硬件接口2.10 块设备2.11 USB 设备2 参考文献前言Linux内核全部源代码是一个庞大的世界,大约有200多万行,占60MB左右的空间。
KVM虚拟机源代码分析 1, KVM结构及工作原理 1.1 KVM结构 KVM基本结构有两部分组成。一个是KVM Driver ,已经成为Linux 内核的一个模块。负责虚拟机的创建,虚拟内存的分配,虚拟CPU寄存器的读写以及虚拟CPU的运行等。另外一个是稍微修改过的Qemu,用于模拟PC硬件的用户空间组件,提供I/O设备模型以及访问外设的途径。
VMM(Linux 内核+ KVM Driver)Linux内核模式
Linux用户模式
/dev/kvmKvm-vm fd Kvm-vcpu fdKVM fd
ioctl
LibKvmQemu客户模式内核模式
用户模式
图1 KVM基本结构 KVM基本结构如图1所示。其中KVM加入到标准的Linux内核中,被组织成Linux中标准的字符设备(/dev/kvm)。Qemu通KVM提供的LibKvm应用程序接口,通过ioctl系统调用创建和运行虚拟机。KVM Driver使得整个Linux成为一个虚拟机监控器。并且在原有的Linux两种执行模式(内核模式和用户模式)的基础上,新增加了客户模式,客户模式拥有自己的内核模式和用户模式。在虚拟机运行下,三种模式的分工如下: 客户模式:执行非I/O的客户代码。虚拟机运行在客户模式下。 内核模式:实现到客户模式的切换。处理因为I/O或者其它指令引起的从客户模式的退出。KVM Driver工作在这种模式下。 用户模式:代表客户执行I/O指令Qemu运行在这种模式下。 在KVM模型中,每一个Guest OS 都作为一个标准的Linux进程,可以使用Linux的进程管理指令管理。 在图1中./dev/kvm在内核中创建的标准字符设备,通过ioctl系统调用来访问内核虚拟机,进行虚拟机的创建和初始化;kvm_vm fd是创建的指向特定虚拟机实例的文件描述符,通过这个文件描述符对特定虚拟机进行访问控制;kvm_vcpu fd指向为虚拟机创建的虚拟处理器的文件描述符,通过该描述符使用ioctl系统调用设置和调度虚拟处理器的运行。
1.2 KVM工作原理 KVM的基本工作原理:用户模式的Qemu利用接口libkvm通过ioctl系统调用进入内核模式。KVM Driver为虚拟机创建虚拟内存和虚拟CPU后执行VMLAUCH指令进入客户模式。装载Guest OS执行。如果Guest OS发生外部中断或者影子页表缺页之类的事件,暂停Guest OS的执行,退出客户模式进行一些必要的处理。然后重新进入客户模式,执行客户代码。如果发生I/O事件或者信号队列中有信号到达,就会进入用户模式处理。KVM采用全虚拟化技术。客户机不用修改就可以运行。
开始用户模式Qemu内核模式KVM Driver客户模式Guest OS
执行IOCTL系统调用
处理I/O进入客户模式处理退出执行客户代码VMX Root OperationVMX Non Root OperationI/O?信号到达NOYes
图2 KVM 工作基本原理 2 ,相关技术-处理器管理和硬件辅助虚拟化技术 Intel 在2006年发布了硬件虚拟化技术。其中支持X86体系结构的称为Intel VT-x技术。ADM称为SVM技术。 VT-x引入了一种新的处理器操作,叫做VMX(Virtual Machine Extension),提供了两种处理器的工作环境。VMCS结构实现两种环境之间的切换。VM Entry使虚拟机进去客户模式,VM Exit使虚拟机退出客户模式。
2.1 KVM中Guest OS的调度执行 VMM调度Guest OS执行时,Qemu通过ioctl系统调用进入内核模式,在KVM Driver中通过get_cpu获得当前物理CPU的引用。之后将Guest状态从VMCS中读出。并装入物理CPU中。执行VMLAUCH指令使得物理处理器进入非根操作环境,运行客户代码。 当Guest OS执行一些特权指令或者外部事件时,比如I/O访问,对控制寄存器的操作,MSR的读写数据包到达等。都会导致物理CPU发生VMExit,停止运行Guest OS。将Guest OS保存到VMCS中,Host状态装入物理处理器中,处理器进入根操作环境,KVM取得控制权,通过读取VMCS中VM_EXIT_REASON字段得到引起VM Exit的原因。从而调用kvm_exit_handler处理函数。如果由于I/O获得信号到达,则退出到用户模式的Qemu处理。处理完毕后,重新进入客户模式运行虚拟CPU。如果是因为外部中断,则在Lib KVM中做一些必要的处理,重新进入客户模式执行客户代码。
2.2 KVM中内存管理 KVM使用影子页表实现客户物理地址到主机物理地址的转换。初始为空,随着虚拟机页访问实效的增加,影子页表被逐渐建立起来,并随着客户机页表的更新而更新。在KVM中提供了一个哈希列表和哈希函数,以客户机页表项中的虚拟页号和该页表项所在页表的级别作为键值,通过该键值查询,如不为空,则表示该对应的影子页表项中的物理页号已经存在并且所指向的影子页表已经生成。如为空,则需新生成一张影子页表,KVM将获取指向该影子页表的主机物理页号填充到相应的影子页表项的内容中,同时以客户机页表虚拟页号和表所在的级别生成键值,在代表该键值的哈希桶中填入主机物理页号,以备查询。但是一旦Guest OS中出现进程切换,会把整个影子页表全部删除重建,而刚被删掉的页表可能很快又被客户机使用,如果只更新相应的影子页表的表项,旧的影子页表就可以重用。因此在KVM中采用将影子页表中对应主机物理页的客户虚拟页写保护并且维护一张影子页表的逆向映射表,即从主机物理地址到客户虚拟地址之间的转换表,这样VM对页表或页目录的修改就可以触发一个缺页异常,从而被KVM捕获,对客户页表或页目录项的修改就可以同样作用于影子页表,通过这种方式实现影子页表与客户机页表保持同步。 2.3 KVM中设备管理 一个机器只有一套I/o地址和设备。设备的管理和访问是操作系统中的突出问题、同样也是虚拟机实现的难题,另外还要提供虚拟设备供各个VM使用。在KVM中通过移植Qemu中的设备模型(Device Model)进行设备的管理和访问。操作系统中,软件使用可编程I/O(PIO)和内存映射I/O(MMIO)与硬件交互。而且硬件可以发出中断请求,由操作系统处理。在有虚拟机的情况下,虚拟机必须要捕获并且模拟PIO和MMIO的请求,模拟虚拟硬件中断。 捕获PIO:由硬件直接提供。当VM发出PIO指令时,导致VM Exit然后硬件会将VM Exit原因及对应的指令写入VMCS控制结构中,这样KVM就会模拟PIO指令。MMIO捕获:对MMIO页的访问导致缺页异常,被KVM捕获,通过X86模拟器模拟执行MMIO指令。KVM中的I/O虚拟化都是用户空间的Qemu实现的。所有PIO和MMIO的访问都是被转发到Qemu的。Qemu模拟硬件设备提供给虚拟机使用。KVM通过异步通知机制以及I/O指令的模拟来完成设备访问,这些通知包括:虚拟中断请求,信号驱动机制以及VM间的通信。 以虚拟机接收数据包来说明虚拟机和设备的交互。
图3 I/O分析 (1)当数据包到达主机的物理网卡后,调用物理网卡的驱动程序,在其中利用Linux内核中的软件网桥,实现数据的转发。 (2)在软件网挢这一层,会判断数据包是发往那个设备的,同时调用网桥的发送函数,向对应的端口发送数据包。 (3)若数据包是发往虚拟机的,则要通过tap设备进行转发,tap设备由两部分组成,网络设备和字符设备。网络设备负责接收和发送数据包,字符设备负责将数据包往内核空间和用户空间进行转发。Tap网络部分收到数据包后,将其设备文件符置位,同时向正在运行VM的进程发出I/O可用信号,引起VM Exit,停止VM运行,进入根操作状态。KVM根据KVM_EXIT_REASON判断原因,模拟I/O指令的执行,将中断注入到VM的中断向量表中。 (4)返回用户模式的Qemu中,执行设备模型。返回到kvm_main loop中,执行Kvm—main—loop—wait,之后进入main_loop wait中,在这个函数里收集对应设备的设备文件描述符的状态,此时tap设备文件描述符的状态同样被集到fd set。 (5)Kvm main—loop不停地循环,通过select系统调用判断哪螋文件描述符的状态发生变化,相应的调用对应的处理函数。对予tap来说,就会通过Qemu—send_packet将数据发往rtl8139一do—receiver,在这个函数中完成相当于硬件RTL8139网卡的逻辑操作。KVM通过模拟I/O指令操作虚拟RTL8139将数据拷贝到用户地址空间,放在相应的I/O地址。用户模式处理完毕后返回内核模式,而后进入客户模式,VM被再次执行,继续收发数据包。
3,KVM 源代码分析-虚拟机创建和运行流程代码分析
3.1 KVM创建和运行虚拟机流程 KVM虚拟机创建和运行虚拟机分为用户态和核心态两个部分,用户态主要提供应用程序接口,为虚拟机创建虚拟机上下文环境,在libkvm中提供访问内核字符设备/dev/kvm的接口;内核态为添加到内核中的字符设备/dev/kvm,模块加载进内核后即可进行接口用户空间调用创建虚拟机。在创建虚拟机过程中,kvm字符设备主要为客户机创建kvm数据机构,创建该虚拟机的虚拟机文件描述符及其相应的数据结构以及创建虚拟处理器及其相应的数据结构。Kvm创建虚拟机的流程如图4所示。 首先申明一个kvm_context_t 变量用以描述用户态虚拟机上下文信息,然后调用kvm_init()函数初始化虚拟机上下文信息;函数kvm_create()创建虚拟机实例,该函数通过ioctl系统调用创建虚拟机相关的内核数据结构并且返回虚拟机文件描述符给用户态kvm_context_t数据结构;创建完内核虚拟机数据结构后,再创建内核pit以及mmio等基本外设模拟设备,然后调用kvm_create_vcpu()函数来创建虚拟处理器,kvm_create_vcpu()函数通过ioctl()系统调用向由vm_fd文件描述符指向的虚拟文件调用创建虚拟处理器,并将虚拟处理器的文件描述符返回给用户态程序,用以以后的调度使用;创建完虚拟处理器后,由用户态的QEMU程序申请客户机用户空间,用以加载和运行客户机代码;为了使得客户虚拟机正确执行,必须要在内核中为客户机建立正确的内存映射关系,即影子页表信息。因此,申请客户机内存地址空间后,调用函数kvm_create_phys_mem()创建客户机内存映射关系,该函数主要通过ioctl系统调用向vm_fd指向的虚拟文件调用设置内核数据结构中客户机内存域相关信息,主要建立影子页表信息;当创建好虚拟处理器和影子页表后,即可读取客户机到指定分配的空间中,然后调度虚拟处理器运行。调度虚拟机的函数为kvm_run(),该函数通过ioctl系统调用调用由虚拟处理器文件描述符指向的虚拟文件调度处理函数kvm_run()调度虚拟处理器的执行,该系统调用将虚拟处理器vcpu信息加载到物理处理器中,通过vm_entry执行进入客户机执行。在客户机正常运行期间kvm_run()函数不返回,只有发生以下两种情况时,函数返回:1,发生了I/O事件,如客户机发出读写I/O的指令;2,产生了客户机和内核KVM都无法处理的异常。I/O事件处理完毕后,通过重新调用KVM_RUN()函数继续调度客户机的执行。