- 博客(74)
- 收藏
- 关注
原创 Linux中断处理过程分析
很久以来对于中断处理没有系统化理解和分析,总是有点好似明白感觉,现在进行从头整理一番。1.中断处理过程总体介绍中断处理过程,非常简单1).中断准备(计算中断向量,保存寄存器),2). 中断处理3). 中断处理完成返回代码如下: addl $-0x80,(%esp) SAVE_ALL call do_IR
2014-08-12 16:26:07 309
原创 Linux 预读代码分析
一. 预读算法触发条件预读触发也就是什么时候进行预读算法判别?下面代码2.6.32内核,分析代码可见预读算法触发条件为两种:页面缺失(页缓存没有找到)和读取含预读标志的页面。static void do_generic_file_read(struct file *filp, loff_t *ppos, read_descriptor_t *desc,
2014-03-06 14:54:02 857
原创 页面回收分析之二
函数分析-----page_check_references shrink_active_list mark_page_accessed首先看看页面扫描回收大概过程, 然后分析三个函数如何进行页面状态变换1.首先扫描非活跃链表中,然后当空闲页面不够时,扫描活动链表,并将相应页面状态变换。2.然后回收非活跃链表,没有设置页描述符的字段 flags位PG_referenced页。
2014-03-06 14:35:45 883 1
原创 Linux 内存页面回收
页面回收内容感觉非常复杂,主要原因在于分析者,把其复杂化。1.内存页面页面回收实际就是回收相应缓存, 因为系统为了性能有效,使用大量缓存。 这些缓存占用大量内存。 当系统内存短缺时,可以回收相应页面。如果不一致话,首先要把缓存内容,刷新到外部存储中。缓存页面可分为:可压缩的缓存(目录和inode节点占用内存页面), slab, 交换高速缓存(缓存交换分区的页面),页高速缓存(缓存文件内容的
2014-02-27 15:06:31 524
原创 Linux驱动----设备内存映射
1.什么是内存映射呢?如何理解?所谓映射是两个集合中的一种特殊的对应关系,通过这一关系把一个集合的内容投影到另一个集合中去。根据此定义可知存在这两个集合。内存映射这个概念中,只设计一个集合内存,另一个集合呢?根据另一个集合的类型可以分为匿名映射(anonymous)和文件映射(file_backed). 在Linux系统中, 文件有可分为普通文件和设备文件等。普通文件的内存映射系统已经
2014-01-06 15:53:20 347
原创 内核链表及应用
1.内核链表的定义1)上面是链表结构体定义,又定义可知为双向链表2)通过链表命名可知该链表没有头结节(链表头),没有头节点意味着每一也都是头节点。3)由于没有头节点,该链表又实现循环链表功能。struct list_head { struct list_head *next, *prev;};2.链表初始化链表使用首先要初始化,下面初始化代码。
2013-12-31 11:46:15 305
原创 cond_resched探讨和分析
下面有cond_resched注释和源代码1.顾名思义有条件的调度,条件是什么呢?2.注释解释/* * cond_resched() and cond_resched_lock(): latency reduction via * explicit rescheduling in places that are safe. The retur
2013-12-30 17:10:19 1383
原创 Linux驱动----PCI 驱动开发实例
详细原理不介绍, 参照《Linux 设备驱动 Edition 3》中第16章块设备驱动,第12章 PCI 驱动开发,以及qemu-kvm虚拟化设备模拟,以及其他设备中断,端口读写等等, 涉及知识较多,应该是一个综合实例。多余不必叙述,可参考下面代码。由于该实例涉及知识较多,建议首先学习《Linux 设备驱动 Edition 3》中第16章块设备驱动,第12章 PCI 驱动开发,再尝试该实例。注
2013-08-30 10:50:56 1246
原创 Linux驱动----块驱动开发实例
详细原理不介绍, 参照《Linux 设备驱动 Edition 3》中第16章块设备驱动. 本文把Linux设备驱动示例代码sbull移植到2.6.32版本,对应于发行版redhat6,centos6。由于对sbull比较复杂,便于理解,进行相应裁剪,去掉对功能没有影响代码,具体原因测试过程,可以不修改(你觉得无关紧要或者无法确定代码),看看会出现什么问题,这样会理解更深。注意:1.本人内核
2013-08-30 10:04:41 554
原创 Linux驱动----网络驱动开发实例
详细原理不介绍, 参照《Linux 设备驱动 Edition 3》中第17章网络驱动. 本文把Linux设备驱动示例代码snull移植到2.6.32版本,对应于发行版redhat6,centos6。为了提高高端 Linux 系统性能的方法, 目前网络子系统开发一般采用基于查询的接口,所以把snull代码中接收中断去掉了,只使用NAPI。由于对snull比较复杂,便于理解,进行相应裁剪,去掉对功
2013-08-29 16:35:19 995
原创 Linux驱动----TTY驱动开发实例
详细原理不介绍, 参照《Linux 设备驱动 Edition 3》中第18章TTY 驱动. 本文把Linux设备驱动示例代码tiny_tty移植到2.6.32版本,对应于发行版redhat6,centos6。对于修改原因,下面做了简单说明,具体原因测试过程,可以不修改(你觉得无关紧要或者无法确定代码),看看会出现什么问题,这样会理解更深。注意:1.本人内核版本:# uname -r
2013-08-29 15:07:58 1322 1
原创 Linux内核线程,定时器,工作队列编程实例
Linux内核线程,定时器,工作队列编程实例:实例大概过程如下: 一.初始化1.创建一个工作队列test_wq2.创建一个定时器timer3.创建一个内核线程二.工作过程1.定时器每隔500ms调用do_htimer2.定时器触发工作队列调用do_work3.工作队列触发睡眠的内核线程(唤醒睡眠线程)三.结束1.停止内核线程2.取消定时器
2013-08-09 10:45:37 783
原创 qemu-kvm virtio 虚拟化-----Linux客户机 virtio设备初始化
Linux客户机 virtio设备初始化virtio设备物理上连接在pci物理总线上,逻辑上连接在virtio虚拟总线。做为pci设备便于资源分配与配置,逻辑设备模型中,便于管理与组织。1.qemu-kvm提供的virtio pci设备virtio-blk(硬盘),virtio-net(网络),virtio-balloon(气球)等pci设备,这些设备连接在pci总线上。代码位于qem
2013-07-17 16:58:06 2443
原创 中断屏蔽的综合分析
中断过程: | | | | | | + 设备 +------>+ 中断控制器 +------->+ cpu + | | | | | |1.设备发送中断,如果中断控制器没有屏蔽,中断控制收到中断。2.中断控制器发送设备中断, 如果处理器没有屏蔽,c
2013-07-10 11:01:26 535
原创 qemu-kvm 设备虚拟化----I/O 端口和 I/O 内存
qemu-kvm 设备虚拟化----I/O 端口和 I/O 内存操作设备存在两种接口:I/O 端口和 I/O 内存,下面分析虚拟机如何截获和模拟这两种情况的。1.用户空间访问内核数据结构信息内存映射可被实现来提供用户程序对设备内存的直接存取,KVM 内核代表每个 VCPU 的 struct kvm_run 数据结构被 mmap用户空间,从而用户空间可以读取 struct kvm
2013-07-03 15:03:34 1524
原创 qemu-kvm i/o虚拟化----设备注册和加载
/////////////////////////////////////////////1.注册映像,设备,机器相应数据结构block_init()device_init()machine_init()注意: 上述函数为构造函数__attribute__((constructor)),即在main()函数执行前,相关函数已执行。#define module_
2013-07-03 13:40:30 1179
原创 qemu-kvm 内存虚拟化---影子页表
qemu-kvm 内存虚拟化---影子页表影子页表被载入到真正硬件MMU中,通过影子页表进行客户机虚拟地址到宿主机物理地址(gva--->hpa)的转换。由于影子页表项不存在或者访问权限不够,可能导致页故障,这页故障由物理硬件MMU产生的,这些故障被截获,并且进行处理和模拟。影子页表页故障处理流程:1.首先遍历客户机页表,获取页表的结构和内容,判断客户机页表的权限是否足够,
2013-06-20 17:22:39 1454
原创 虚拟MMU---客户机页表遍历
客户机页表的遍历MMU的功能:虚拟机地址转换为物理地址,下面函数模拟此过程。1.数据结构 struct guest_walker { int level; gfn_t table_gfn[PT_MAX_FULL_LEVELS]; pt_element_t ptes[PT_MAX_FULL_LEVELS]; gp
2013-06-08 14:34:40 674
原创 影子页表页内存管理----分配与回收
影子页表页管理-----分配和回收影子页表页分配static struct kvm_mmu_page *kvm_mmu_alloc_page(struct kvm_vcpu *vcpu, u64 *parent_pte){ struct kvm_mmu_page *sp
2013-06-07 15:01:18 1219
原创 影子页表虚拟化---INVLPG
影子页表虚拟化---INVLPG当客户机修改客户机页表的表项,客户机执行INVLPG敏感指令刷新TLB部分内容。正常流程为:VMM截获这一操作,并对影子页表项进行相应修改,设置不存在,刷新影子页表部分内容。代码分析:static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva){ struct kvm
2013-06-05 17:23:07 1190
原创 影子页表虚拟化-----反向映射
反向映射 mmu维护一个反向映射, 因此映射这个页的所有页表项,由gfn(客户机页框号)找到映射此页的影子页表项spte。这些情况下:当客户机的宿主机物理页面被交换到硬盘上或者被回收,这是有用的。为什么有用呢?如果客户机的宿主机物理页面被交换到硬盘,影子页表肯定要知道,并且要更新影子页表,设置不存在。下一次客户机访问被交换出去页面,查询影子页表被截获,进行处理。如何更新影子页表呢?
2013-06-05 16:39:55 874
原创 客户机物理页框到宿主机虚拟地址转换
对于虚拟机来说, 如果指定1G内存,以slot为单位,进行mmap虚拟内存映射申请,申请之后memset进行物理内存申请,从而占用物理内存。对于宿主机来说mmap申请宿主机虚拟内存为连续的,进行memset初始化发生缺页中断从而申请物理内存,这些宿主机物理内存未必是连续的。对于虚拟机来说,虚拟机物理内存当然是连续的,所以可以让虚拟机物理内存虚拟对应与宿主机虚拟内存。注意:1.slot不是物
2013-05-24 10:50:07 899
翻译 APIC-access address Virtual-APIC address IA32_APIC_BASE
virtual-APIC页唯一功能是影子化TPR。存在三个有意思地址,三个地址全部都是物理地址(意思是它们没有进行过任何一种转换)1. IA32_APIC_BASE。这个地址包含在MSR中, 这个地址是实际硬件APIC映射的地址。访问这个地址就是访问实际硬件APIC映射的寄存器。VMM将不映射这个物理地址到任何一个客户机地址空间。那意味着(1):如果EPT启用,EPT相应的表项不包含这个地
2013-05-17 15:08:41 848
原创 spice 鼠标移动代码分析
spice工作过程,相当繁琐。其中经过组件依次为1.客户端(例如spicec,spicy)2.spice-server3.qemu-kvm4.guest具体流程可参照网上资料,下面分析spice鼠标移动事件工作过程,spice鼠标相对其他是比较简单的。1.客户端spice mouse鼠标的移动操作鼠标在Linux spice客户端进行移动时X11引擎捕获该事件
2013-04-24 15:45:19 1618
原创 qemu-kvm 线程事件模型
qemu-kvm 线程事件模型1.主(父)线程。主线程执行循环,主要做三件事情1).执行select操作,查询文件描述符有无读写操作2).执行定时器回调函数3).执行下半部(BH)回调函数。为什么要采用BH,资料说主要避免可重入性和调用栈溢出。2.执行客户机代码的线程只讨论kvm执行客户机代码情况(不考虑TCG,TCG采用动态翻译技术),如果有多个vcpu,就意味着
2013-04-22 17:26:45 1092
原创 qemu i/o虚拟化-- virtio-blk设备
qemu-kvm virtio-blk设备virtio-blk为半虚拟驱动,virtio-blk请求处理过程如下:1.客户机(virtio-blk设备驱动)读写数据方式vring队列2.客户机执行Virtqueue队列函数kick通知host宿主机(通过virtio-pci硬件寄存器发送通知)3.宿主机host截获通知信息4.宿主机host从vring队列获取读写请求(vrin
2013-04-19 16:01:34 3338 5
原创 qemu i/o虚拟化-- ide设备
首先了解一下Linux的文件操作,接下来看一下qemu对于ide设备虚拟化过程一)学习Linux的文件操作涉及分层-----------虚拟文件层vfs-----------磁盘设备缓存(directio不存在)----------块设备层(包括映射,调度)---------块设备驱动---------硬件设备----------二)
2013-04-18 14:53:01 1319
原创 qemu-kvm虚拟化 vpid 代码分析
qemu-kvm虚拟化 vpid 代码分析1.页表实现线性地址到物理地址转换。2.ept (Extended Page Tables)实现客户机物理地址到宿主机物理地址装换。3.tlb (Translation lookaside buffer )旁路装换缓冲区,改进虚拟地址(线性地址)到物理地址转换速度的缓存。操作系统中我们知道每个进程都有自己页表,进程切换重新设置c
2013-04-18 14:40:53 895
原创 qemu-kvm 内存虚拟化---ept
qemu-kvm内存虚拟化内存虚拟化实际就是进行地址转换从客户机虚拟地址-->客户机物理地址-->宿主机的物理地址,转换实现有两种硬件内存虚拟化和软件影子页表方式, 下面主要分析基于intel ept硬件内存虚拟化实现,此实现主要做两件事情1.开启ept功能2.构造转换页表。注意该页表构造采用动态方式(常说懒惰方式),就是不到完不得以情况不创建。此页表创建实现就是采用ept violati
2013-04-17 16:25:20 2482
原创 Qemu-kvm模拟APIC Timer中断
Qemu-kvm模拟APIC Timer中断qemu-kvm模拟两个时钟中断设备PIT(i8254)和APIC Timer设备,也就是产生中断源。两者电子线路连接不同,对于i8254设备来说首先连接到i8259中断控制器,i8259中断控制器再连接到ioapic设备中,送到lapic,最后注入到vcpu中。对于APIC Timer设备实际就是lapic的一个功能,意思就是通过编程可以触发l
2013-04-17 11:32:54 1385
原创 qemu-kvm 中断虚拟化代码分析
硬件中断发生(qemu模拟设备)1.硬件产生中断的接口void qemu_set_irq(qemu_irq irq, int level);2.中断过程void qemu_set_irq(qemu_irq irq, int level){ if (!irq) return; irq->handler(irq->opaque, irq
2013-04-16 17:32:28 1705
原创 qemu-kvm 代码分析
物理计算机由处理器,存储器,输入与设备三大部件组成,虚拟机实际也是一台计算机,必然包括这三大组件,所以虚拟技术包括处理机虚拟化,存储器虚拟化,输入与输出设备虚拟化,这些虚拟化是通过软件虚拟还是硬件虚拟呢?接下来看看具体虚拟化软件qemu-kvm是如何处理的?qemu是采用纯软件模拟的技术,kvm暂且认为采用硬件模拟技术, 可见qemu-kvm的虚拟机是硬件辅助虚拟机,其中处理机虚拟化和存储器虚
2013-03-22 15:52:20 1653 1
原创 友元函数浅谈
友元函数1.友元函数必须在一个类中声明,拍拍胸脯,告诉它是我的朋友,既然是朋友,那么可以使用和访问我的资源(包括私有,公有,保护)。2.友元函数访问我的资源,通过什么方式呢? 只能通过对象变量,不能通过类的变量。 实现方式,以参数方式传递对象,进入友元函数。3.既然是友元函数,那么与成员函数有区别,如何使用呢? 不能通过成员符号,例如(->, . , ::)使用该函数。友元函数
2013-03-07 16:46:51 304
原创 dynamic_cast 类型转换全面深入讨论
dynamic_cast 类型转换全面深入讨论理解dynamic_cast,必须明白C++语言中继承和多态概念以及实现,不然无法真正明白其要求。1.dynamic_cast在继承情况要求dynamic_cast 只能在对象的引用和指向对象指针情况下, 目的是确保类型转换是一个有效完整转换类对象,因此当到基类转换(向上转换),dynamic_cast总是成功的。限制条件说明:
2013-03-06 15:26:47 1031
原创 Glib编程初步
1.学习GLib编程,首先了解其运行机制--基于事件(资源)循环分发处理机制,然后理解其三大数据结构: GSource 代表资源 ;GMainContext 代表资源容器 ;GMainLoop 代表资源容器管理者,最后其工作过程:资源管理器进行循环,查询资源容器有无准备好资源,如有准备好资源,处理相应资源,否则等待。下面看一例子:2.GLib编程实例#include #incl
2013-02-22 13:53:51 537
原创 重载,覆盖,隐藏
重载产生于一个类,实现不同定义,统一接口。覆盖产生与多个类,实现多态概念。隐藏多产生于继承或者派生,属于命名空间作用域范畴。当一个类调用存在多重继承时,调用函数和变量时:首先访问自己的作用域,在自己作用域不存在,访问父类,还不存在继续向上查找,直到全局命名空间(注意命名空间指名称,不包括参数,返回值)。如果查找到,就访问自己作用域。由此可见存在一个隐藏概念,自己作用域,隐藏父类作用
2012-11-12 17:28:20 217
转载 泛型
泛型:定义泛型类、泛型接口、类型通配符、泛型方法。/* *程序成功创建了一个特殊的List:strList,这个List集合只能保存字符串对象,不能保存其他类型的对象。创建这种特殊集合的方法是:在集合接口、类后增加尖括号后,尖括号里放一个数据类型,即表明这个集合接口、集合类型只能保存特定类型的对象。下面指出strList不是一个任意的List,而是一个String的List,写作:Li
2012-11-12 16:38:24 205
原创 单实例化两种实现方式
单实例,顾名思义就是产生一个类的对象(实例)。接下来我们想知道什么时候单实例情况?对于这个问题,我们可以这么想,单实例有什么好处?想能明白这个问题,可以借用多线程和单线程来理解。如何实现单实例化?C++单实例化两种实现方式: 需要保证,有且仅有调用一个接口,除此没有别的方式来生成类的实例并且只能产生一个实例, 下列情况可能造成产生多实例,请注意相同点: (1)屏蔽默认生成
2012-11-12 16:12:15 484
原创 C++编译思考---静态联编(static Binding)和动态联编(dynamic Binding)
静态联编(static Binding)和动态联编(dynamic Binding)C++中这两个词语感觉有点抽象,另外翻译之后也感觉有点别扭,所以更加给人感觉不好理解。静态联编和动态联编实际上就是对于调用函数的处理方式, 决定对象在编译阶段决定调用那个函数(静态联编),还是运行时决定调用那个函数方式(动态联编)。言外之意,编译阶段决定调用那个函数,当然可以由编译器来检查调用是
2012-11-10 22:11:32 144
原创 C++成员变量初始化
C++类中成员变量包括主要四种:普通成员变量,常量成员变量,静态成员变量,静态常量成员变量上述成员变量该如何初始化,注意不是赋值。由于普通成员变量和常量成员变量,每一个类实例化,都一份内存拷贝。C++规定成员变量在声明(注意声明与定义区别)时,不允许初始化,因此这些变量只能放在构造函数初始化列表中。静态成员变量所有类实例化,只有一份内存拷贝,不能放在构造函数中初始化, 因为共享
2012-11-09 16:59:30 1242
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人