历史上的今天
返回首页

历史上的今天

今天是:2025年01月21日(星期二)

正在发生

2020年01月21日 | ARM平台的虚拟化介绍

2020-01-21 来源:eefocus

本篇博文主要介绍虚拟化的基本思想以及在arm平台如何做虚拟化,arm提供的硬件feature等等。

虚拟化技术简介

虚拟化技术

虚拟化是一个概念,单从这个概念的角度来看,只要是用某一种物品去模拟另一种物品都可以称为虚拟化,甚至于有些饭店用豆腐做出肉的味道,我认为这也可以称为一种虚拟化。但是这里我们主要讨论的是计算机领域的虚拟化,我们这样定义虚拟化“虚拟化是将单一物理设备模拟为相互隔离的多个虚拟设备,同时保证这些虚拟设备的高效性”。这个概念的定义里还包含了对虚拟化的要求,也就是这里的隔离性(isolated)和有效性(efficient)。我们常说的hypervisor,有些书也把它称为VMM(virtual machine monitor)则是一个直接运行在物理硬件上的软件,它的功能就是管理物理硬件,以便在不同的虚拟机之间共享这些物理资源(cpu,内存,外设等等),既然hypervisor直接给物理外设打交道,那它当然需要运行在特权模式了,在过去没有virtualization extesion的情况下,guest os和guest application只能都运行在de-privileged模式,如下图所示。

Popek和Goldberg有一篇虚拟化的经典论文,把需要在特权模式下执行的指令分成了两类:

  • sensitive instructions(敏感指令):这些指令试图去更改系统资源的配置信息,或者它的执行结果依赖于系统的状态。

  • privileged instructions(特权指令):这些指令在非特权模式下会trap(产生异常,陷入中断向量表),在特权模式下可以正常执行。

Popek和Goldberg提出构建hypervisor的要求:敏感指令是特权指令的子集。这种标准现在被称为classically virtualized(经典可虚拟化模型),虽然在不满足这个要求的情况下也可以做虚拟化(二进制翻译技术,后面会介绍),但是如果满足这个要求,实现起来会容易很多。下面介绍现有的虚拟化技术:

  • Pure virtualization(完全虚拟化):完全虚拟化要求硬件架构是可虚拟化的(符合经典可虚拟化模型),当trap进入hypervisor后,由hypervisor去模拟敏感指令的执行,这项技术也被称为trap-and-emulate。当一个guest os想要去访问特权资源(物理外设),就会产生一个trap唤醒hypervisor,hypervisor去模拟这个访问,然后返回到guest os的下一条指令去继续执行。如下图所示,红色箭头表示一个trap。可以看出,每一条特权指令都需要很多条指令去仿真,所以这种trap-and-emulate开销非常大,对系统性能有很大影响。

  • Binary rewriting(二进制重写):二进制重写就是当硬件架构不可虚拟化(不符合经典可虚拟化模型)采用的方法。它可以分为静态的和动态的,静态的二进制重写是通过扫描ELF文件,把所有的敏感指令替换成一个trap指令(系统调用指令),或者用一些非敏感指令去仿真执行这条敏感指令,动态的二进制重写对敏感指令的处理和静态的类似,只不过它是在运行时去逐条分析指令,其实这种方法更不好,因为不管是不是敏感指令,都需要逐条分析才能确定,非常耗时,静态方法在运行时的性能要好过动态方法,但是经常出现一些莫名其妙的错误,因为运行时状态非常复杂,静态修改很难预料到所有情况。上述过程如下图所示。

  • para-virtualization(类虚拟化):这种虚拟化方法,很多书都把它译为半虚拟化,其实这种译法是不准确的,半虚拟化(partial-virtualization)是一个早已存在的技术,它只虚拟化部分外设来满足某些专门的软件的执行环境,但是不能运行所有可能运行在物理机上的软件。如果读者对此有疑问,请参阅《系统虚拟化:原理与实现》,intel开源技术中心和复旦大学并行处理研究所著,书中1.3节对此有讨论。其实想解释清楚这部分内容是很难的,还要理解各种各样的虚拟化漏洞。简单来说,类虚拟化通过修改guest os的源码(API级),使得guest os避免这些难以虚拟化的指令(虚拟化漏洞)。操作系统通常会使用到处理器提供的全部功能,例如特权级别、地址空间和控制寄存器等。类虚拟化首先要解决的问题就是如何陷入VMM。典型的做法是修改guest os的相关代码,让os主动让出特权级别,而运行在次一级特权上。这样,当guest os试图去执行特权指令时,保护异常被触发,从而提供截获点供VMM来模拟(也可以采用hypercall的方式,下面介绍)。既然内核代码已经需要修改,类虚拟化还可以进一步优化I/O。也就是说,类虚拟化不是去模拟真实世界中的设备,因为太多的寄存器模拟会降低性能。相反,类虚拟化可以自定义出高度优化的I/O协议,这种I/O协议完全基于事物,可以达到近乎物理机的速度。
    其实OKL4用的类虚拟化就是修改hypervisor提供给guest os的API(不同于底层硬件),同时修改guest os的源码,把那些敏感指令换成hypercall(calls into hypervisor)。下图展示的是,对于pure virtualization,硬件和hypervisor的API是相同的,但是对于para-virtualization是不同的。

虚拟化技术的比较

Pure virtualization and binary rewriting

pure virtualization和binary rewriting都是不修改机器的API的,所以任何guest os都可以直接运行在虚拟化环境。但是,由于所有的特权指令都会导致trap,所以在虚拟环境下特权指令的执行开销要远远高于在native环境下。以前,x86和ARM都不符合classically virtualized时,VMWare采用binary rewriting在x86架构上实现虚拟化,经过优化后的性能开销小于10%,但是这项技术十分复杂。由于实现起来的复杂,就会增加运行在特权模式下的代码,这会增加attack surface和hypervisor出现bug的几率,所以会降低整个系统的安全性和隔离性。

Para-virtualization

Para-virtualization虽然是一个新词,在2002年中的Denali virtual machine monitor被提出来。但是这种设计理念早在1970的IBM的CMS系统就出现了,当时使用DIAG指令调用到hypervisor里去,并且一直到现在还有很多研究机构在使用这种理念,如Mach,Xen和L4。
Para-virtualization相比于pure virtualization可以提供更好的性能,因为它直接使用各种API而不是通过trap->decode->hardware emulation的过程来实现仿真。当然,它的缺点我也在之前的博客中提到过,那就是必须修改源码,让guest os使用新的API,这不仅是一项繁重的任务,同时对于一些非开源的操作系统,我们必须采用其他方法,除非这些非开源操作系统的厂商愿意与我们合作。

Virtual memory in virtualization environment

为什么要把内存管理部分单独拿出来讨论一下呢?因为这部分很复杂,其实之前我们讨论的内容主要都是cpu运行的问题,比如各种指令和各种模式之间的切换。关于内存,我们先讨论没有引入guest os时的虚拟内存管理,然后再讨论引入guest os之后的变化。
虚拟内存管理涉及的内容很多,这里不讨论各种内存分配算法,如何降低缺页率等等,只分析虚拟地址如何转换成物理地址。我们知道,ARM架构是通过MMU+TLB来完成从VA(virtual address,虚拟地址)到PA(physical address,物理地址)的转换,对于页表的访问实际上是由硬件自动完成的(如果不缺页的话)。但是加入了虚拟化之后,这个转换就复杂了,guest page table不完成从va到pa的转换,只是负责从guest va到guest pa的转换,而由hypervisor完成由guest pa到实际物理地址的转换,这个转换过程如下图所示。

这个图表现的很清晰,但是想实现是非常难的,因为只有一个页表基址寄存器,所以硬件无法识别是从guest va到guest pa的转换还是va到pa的转换,在没有硬件支持的情况下,只能通过影子页表才能实现,影子页表的原理也是把两步转换(guest va->guest pa->pa)转换为一步,中间的同步用hash来做。影子页表在构建的时候,每次对guest page table的访问都需要trap,由hypervisor把guest pa转换成实际物理地址。如果读者想了解这一块内容,我建议深入学习一下KVM以前关于影子页表的实现(由于x86的硬件支持,目前KVM已经放弃影子页表),这里我们没办法深入探讨影子页表,但了解它大致是怎么一回事儿之后,我们可以分析以下它的性能。首先,它的性能一定非常不好,因为每次对guest page table的访问都需要trap,而且每次guest page table的修改还需要同步到影子页表上面,虽然用hash的方式能提速,但是相比于native环境性能差距比较大(NOVA做过一个实验,光访问页表的性能损失大约是23%),而且实现起来非常复杂。Intel和ARM对这一部分都提供了硬件支持,由硬件来完成这里提到的两级页表转换。其实根据程序运行时的局部性原理,如果每次访问都能TLB hit的话,这种二级页表转换和一级页表转换差别不大,但是当TLB miss的时候,需要访问two stage的页表访问的性能还是差别比较大的,尽管这部分由硬件来做。举个例子,比如KVM在Linux-64位的情况下,是4级页表转换,从va到pa需要访问5次页表,那么引入two stage之后,就需要5*5=25次访问页表,读者可以思考一下这里为什么是相乘的关系。

ARM介绍

我们首先介绍ARM架构里的各个部分,介绍它们的目的是为了理解当arm引入virtualization extension之后对它们的影响。

ARM总体介绍

arm是一种精简指令集(reduced instruction set computer,RISC)架构,精简(reduced)的意思是每条汇编指令独自完成所有的工作,而与之相对的复杂指令集则不是,它的一条汇编指令可能会翻译成好几条机器指令。大部分精简指令集的指令都在单个时钟周期内完成,它采用一种读取和存储分开的架构(load-store architecture),数据处理指令和I/O指令是分开的,数据处理指令是操作一个寄存器的值,和复杂指令集不同,关于复杂指令集的对应操作读者请自行查阅资料。现在arm已经推出v8架构,关于v8架构我还不太熟,所以这里以v7作为介绍(后续有时间我会研究下v8,在这里进行补充)。v7架构包含16个32bit的通用寄存器,还有一些寄存器是和特定的处理器模式相关的,还有各种协处理器的寄存器,这些寄存器将会在后面展开叙述。

ARM协处理器介绍

ARM协处理器是ARM架构的重要扩展,ARM架构允许最多16个协处理器,其中cp15被保留完成各种控制。cp15作用非常强大,它控制整个系统配置,cache和TLB的管理,MMU的控制和系统性能监控,我们这里主要讨论cp15的内存管理功能。
当cpu想要访问一个虚拟地址的时候,它首先去TLB里面查这个虚拟地址和ASID,都匹配的话就可以直接返回物理地址,cpu通过物理地址去访问物理内存就行了。如果TLB miss,MMU就会去访问页表,然后找到这个虚拟地址对应的物理地址,把这个虚拟地址、当前进程的PID、物理地址加入到TLB中去,然后返回物理地址给cpu去访问内存。这里面涉及的很多细节这里不讨论了,建议读者去参看ARM官方介绍。

处理器模式和TrustZone

ARM v7包含8种处理器模式(在v8已经变成4种exception level了,从EL0到El3),其中包含1种非特权模式和7种特权模式:

  • 特权模式:FIQ、IRQ、supervisor、monitor、abort、undefined、system;

  • 非特权模式:user。

显然,除了应用程序运行在user模式以外,其他全部运行在特权模式。ARM的virtualization extension需要处理器支持TrustZone extension,我们来看一下TrustZone是什么。TrustZone将处理器的执行状态分为两个世界:

  • secure world:用于运行可信软件;

  • non-secure world:用于运行不可信软件。

这里的两个世界和处理器模式是重叠的,软件可以在任何模式、任何世界上运行。那么secure world和non-secure world的区别在哪呢?这里的secure又从何而来?是这样的,secure world有自己独有的内存和外设,这部分内容只有运行在secure world的软件可以访问,运行在non-secure world的软件是不可以访问的。这里引入了一个新的处理器模式,monitor mode,它运行在secure world,被用于做双系统(secure and non-secure world)之间的切换,如下图所示。

我们可以基于TrustZone去做虚拟化,因为它能够隔离内存、中断并且确保non-secure world的特权软件也不可能访问或者修改运行在secure world的软件的配置信息。然后这样做的缺陷是,在non-secure world只能运行一个guest os,在secure world运行一个hypervisor。Green Hill的INTEGRITY就是这样做的,感兴趣的读者可以去Google一下。

中断控制器

GIC(generic interrupt controller)是ARM里的中断控制器,现在也已经支持virtualization extension。GIC可以分为两部分:

  • Distributor(分发器):分发器负责接收中断,设置这个中断是否enable和它的优先级,之后把它送到对应的cpu interface上去。

  • CPU interface(中断接口):这部分负责屏蔽低优先级中断(相对于正在处理的中断的优先级),让高优先级的中断抢占cpu。

当外设产生中断的时候,这个中断首先发送给Distributor,Distributor将这个中断发送给对应的cpu interface。当cpu interface接受到这个中断的时候,它会检查这个中断是否enable,如果enable再去比较这个中断的优先级和当前正在处理的中断的优先级,进而决定处理器是否立即处理这个中断。

Virtualization Issues with the ARM Architecture

标准的ARM架构是不符合可虚拟化模型的,有很多敏感指令在非特权模式下执行却不会产生trap。比如CPS指令,这条指令的作用是改变处理器状态,当这条指令在用户态执行时不会产生trap,甚至没有任何效果,可以认为是简单的跳过。即使所有的敏感指令都会产生trap,在ARM架构上用上述的trap-and-emulate技术也是很困难的,因为ARM的敏感指令非常多,只要和特权资源交互的指令都是敏感指令,比如虚拟内存子系统,中断控制子系统和协处理器,用上述方式的话开销太大,对系统性能有很大冲击。比如,arm-v7架构不支持页表访问的虚拟化,那么就需要影子页表,每次访问guest pa都需要trap,同样地,中断控制器也需要被仿真,当中断很频繁的时候(timer tick),这种仿真的开销也是非常大的,为了克服这种种弊端,ARM推出了virtualization extension。

ARM对虚拟化的硬件支持

在讨论arm新增加的virtualization extension之前,我们知道对硬件虚拟化的支持主要有intel的VT-x和AMD的AMD-V,它们两个十分类似,所以这里我们只介绍VT-x,看看它对虚拟化做了怎样的支持(为后面做对比)。

  • 将cpu的模式分为hypervisor(VMX root operation)和guest(VMX non-root operation)。

  • 可以配置一些敏感指令和事件,让它们产生或者不产生trap。

  • (新增)提供扩展页表(EPT,extended page table),通过这个页表在硬件上完成second-stage of translation,其实就是常说的二级页表翻译。

  • (新增)在TLB上新增加了VM tag去标识每一个虚拟机,这样可以避免每次VM-entry和VM-exit时的TLB flush操作(其实还增加了VPID,去标识VM里虚拟进程的进程id)。

  • (新增)在Intel的 VT-d里增加了对DMA操作的支持,而且是一种安全的DMA(具体怎么实现的安全读者可以自己分析下)。

接下来我们看看ARM对虚拟化的支持,这里讨论的虚拟化支持主要是针对v7架构,并且需要实现上文提到的TrustZone。利用硬件扩展实现pure virtualization的总体架构如下图所示:

  • hypervisor运行在non-secure world里的hyp mode,这个hyp mode使hypervisor可以管理non-secure world里其他所有的模式(user mode和kernel mode)里运行的软件。

  • guest os运行在non-secure world的特权模式(kernel mode),guest application运行在non-secure world的user mode。

上述内容是对虚拟化扩展的一个总体介绍,具体来说,ARM新增了以下几个feature:

  • hyp mode:hyp mode是运行在non-secure world的最高特权级模式,如上图所示。它负责管理guest os,hypervisor运行在这个新的模式里。这个模式将hypervisor和运行中的guest os分开,guest os运行在non-secure的kernel mode。

  • Second-stage of translation:由hypervisor负责把所有的gust pa转换成实际物理地址,其实就是从物理上支持两级页表转换,而不需要使用影子页表。

  • 中断控制:这部分后面展开叙述。

  • 仿真支持:当trap进hypervisor时,硬件向hypervisor提供一些额外的信息,消除了hypervisor取指令然后decode的开销。因为对外设的模拟需要采用trap-and-emulate技术,削减这项技术的开销可以有效的提升性能。

  • trap配置:不是所有的敏感指令或特权操作都需要trap进hypervisor进行处理,我们可以配置指令或操作是否trap,这样可以减少不必要的trap,从而减少开销,提升性能。

读者可以自行对比Intel和ARM对虚拟化支持的相同点和不同点,分析他们为什么这样做。接下来展开叙述上文提到的中断控制部分。

中断控制

ARM创建了一个新的硬件模块,virtual CPU interface,类比我们前面在介绍GIC时提到过的CPU interface,这个硬件模块可以直接被map到guest os里,从而避免使用trap-and-emulate去仿真CPU interface,guest os可以直接操作这个virtual CPU interface,例如开、关中断。当然关于GIC的另一个部分,Distributor,我们仍然需要通过trap-and-emulate去仿真,但是它对性能的影响不大,因为它只是在初始化的时候负责enable中断,之后就不再修改了。
当中断到来时,所有的中断都首先被送到hypervisor里进行处理,由hypervisor通过virtual CPU interface发送给当前正在执行的guest os。虚拟中断可以和物理中断进行映射,这样guest os就可以直接操作物理中断而不需要通过hypervisor了。下图所示是一个中断处理流程:

  1. 外设产生一个中断发送到Distributor

  2. Distributor把这个中断发送给CPU interface

  3. CPU interface告诉hypervisor去处理这个中断

  4. hypervisor对这个中断进行检查,发现这个中断是送给guest os处理的,它会设置一个虚拟中断,将物理中断和虚拟中断连接在一起,把这个虚拟中断加入到virtual CPU interface。

  5. virtual CPU interface会根据hypervisor加入的虚拟中断向guest os发送一个中断

  6. guest os通过virtual CPU interface发来的中断进行处理,处理之后返回

  7. virtual CPU interface发现这个虚拟中断来自于一个物理中断,就会在Dirtributor上清除这个物理中断(表示处理完毕),整个虚拟中断处理过程结束。

这里面还涉及一个硬件扩展,论文上把它称为“priority drop”。正常情况下,当一个中断正在处理的时候,低优先级的中断是不能够抢占处理器的,但是在虚拟化环境却不是这样,比方说有两个guest os,我们暂且称之为os1和os2,假设os1正在处理一个高优先级中断,这时又有一个中断是给os2处理的,这个中断的优先级低于os1的中断的优先级,但是它们应该互不影响才对。ARM加入这个硬件扩展就是为了处理上述问题,每个guest os都有自己的优先级屏蔽策略,互不影响。

推荐阅读

史海拾趣

Alpha-Micro Electronics公司的发展小趣事

Alpha-Micro Electronics是一家提供嵌入式系统解决方案的公司,专注于设计和制造微控制器、传感器和其他嵌入式设备。以下是关于Alpha-Micro Electronics公司发展的五个相关故事:

  1. 公司成立:Alpha-Micro Electronics公司成立于1982年,总部位于德国斯图加特。公司的创始人是一群电子工程师,他们致力于为各种应用领域提供高性能的嵌入式系统解决方案。

  2. 技术创新:在公司创立之初,Alpha-Micro Electronics就开始致力于技术创新。他们不断投资于研发,推出了一系列先进的微控制器和传感器产品,以满足客户对功能强大和性能稳定的需求。

  3. 解决方案定制:Alpha-Micro Electronics公司注重与客户的紧密合作,提供定制化的解决方案。他们的工程团队具有丰富的经验和专业知识,能够根据客户的具体要求设计和制造符合其需求的嵌入式系统。

  4. 国际扩展:随着业务的不断发展,Alpha-Micro Electronics逐渐拓展了国际市场。除了在德国的总部和研发中心外,公司还在全球范围内建立了销售和服务网络,包括在美国、亚洲和欧洲的分支机构和合作伙伴。

  5. 行业合作与创新:Alpha-Micro Electronics公司积极参与行业合作和创新项目,与其他企业、研究机构和学术界合作,共同推动嵌入式技术的发展。通过与行业领先者合作,公司不断探索新的技术和应用领域,为客户提供更具竞争力的解决方案。

这些故事展示了Alpha-Micro Electronics公司在技术创新、解决方案定制、国际扩展和行业合作方面的发展历程,以及其在电子行业中的重要地位和影响力。

DAPAudio公司的发展小趣事

随着公司产品的不断成熟和市场的逐渐扩大,DAPAudio开始将目光投向国际市场。通过与国际知名品牌的合作和自身的市场拓展努力,DAPAudio的产品逐渐进入欧美等发达国家和地区的市场。在国际市场上,DAPAudio凭借其卓越的产品性能和优质的服务赢得了广泛的赞誉和认可。

Epitex Inc公司的发展小趣事

Epitex一直将品质管理作为公司的核心竞争力之一。他们建立了严格的质量管理体系,从原材料采购到生产过程的每一个环节都进行严格的控制。同时,Epitex还不断引进先进的生产设备和检测技术,确保产品的稳定性和可靠性。

此外,Epitex还非常重视员工的培训和素质提升。他们定期组织员工进行技能培训和质量意识教育,提高员工的专业素养和工作质量。这种持续改进的精神使得Epitex的产品质量得到了客户的高度认可。

长运通(CYT)公司的发展小趣事

作为一家有社会责任感的企业,长运通始终关注环境保护和社会公益事业。公司积极推广绿色、环保的LED照明产品,致力于降低能源消耗和减少环境污染。同时,长运通也积极参与各种社会公益活动,为社会做出自己的贡献。这些举措不仅提升了公司的社会形象,也为公司的可持续发展奠定了基础。

请注意,以上故事仅为概述,具体的细节和内容可能需要根据实际情况进行补充和调整。

BERGQUIST公司的发展小趣事

随着产品技术的不断成熟和市场的逐步认可,BERGQUIST公司开始积极拓展市场。公司不仅在国内市场取得了显著成绩,还积极开拓国际市场,与众多知名电子企业建立了长期合作关系。通过不断提升产品质量和服务水平,BERGQUIST成功树立起了自己的品牌形象,成为热管理领域的佼佼者。

DAQ Electronics LLC公司的发展小趣事

在DAQ Electronics LLC公司的发展历程中,质量一直是其坚守的核心原则。公司建立了严格的质量控制体系,从原材料采购到产品生产、检测、包装等各个环节都进行严格把控。这种对质量的坚持,使得DAQ Electronics LLC公司的产品在市场上获得了良好的口碑和信誉。客户对公司的产品和服务给予了高度评价,也为公司的持续发展提供了有力保障。

问答坊 | AI 解惑

简易数控直流电源

简易数控直流电源  94年的题, 谁会做啊, 我想了解以下他的原理几过程. 我的邮箱,cf2928@163.com 要不谁告诉我那有我去下也行,谢了.…

查看全部问答>

传输线和反射的经典文章

传输线和反射的经典文章…

查看全部问答>

VC如何发彩信,已经实现ATDT*99***1#这一步了,下一步应该是什么,内容打包?如果打包?

VC如何发彩信,已经实现ATDT*99***1#这一步了,下一步应该是什么,内容打包?如果打包? ATE AT+CMGF=0 AT+CIMI   AT+CIMI获得IMSI  IMSI 国际移动用户识别码(IMSI) international mobile subscriber identity 国际上为唯一识别 ...…

查看全部问答>

新手请教winCE初级 问题

在VS2005环境里可以创建wince的项目 我现在想用C#在vs2005开发一个应用软件用的是Access数据库 。下载wince下面有哪些方面的要求吗 。 比如说我要做一个类似表格的界面 在输入数据以后点击按钮就保存到数据库里面去了 然后文本框清空,  & ...…

查看全部问答>

2812 flash不能烧写

问题是这样的:我用flash烧写了一个控制电机的程序,不能运行,就把代码改了一下,再进行烧程序的时候就烧不进去啦,我也没有动“lock”和密码(在flash烧写的时候一直很小心的),怎么会锁住呢?很是不解。请EEWORLD老师和各位高手解答一下,谢谢 ...…

查看全部问答>

OLED_12896_GR_Lib函数(三) ——LINE函数的实现

首先向大家说声抱歉,因为自己的不小心,上次的PSET函数中出现了一些失误,且在测试程序中也没有测试出来,这次在编写LINE函数时发现并修改过来了。现把修改的地方罗列如下:1、 缓冲数组的定义,这是一个非常低级的失误,在定义数组的时候, ...…

查看全部问答>

C题智能小车群

本帖最后由 paulhyde 于 2014-9-15 08:55 编辑 109197413  …

查看全部问答>

.一个初中生是如何成为嵌入式工程师的

我是一个只有初中毕业没有读过多少书的人从小就爱好无线电记得很小的时候当通讯兵的父亲带回来几本电子方面的书籍从此就迷上了无线电那种痴迷程度决不亚于现在的小孩迷恋游戏机至今仍然清楚的记得曾经因为装成功一台6管收音机而兴奋的几天几夜没睡 ...…

查看全部问答>

wince dm9000驱动代码流程分析

从dm9000.def文件中可以看到dm9000的驱动程序(dm9000.dll)exports的函数只有DriverEntry。从名字上也可以看出这是该dll文件入口。      下面详细看下这个入口函数(在driver.cpp中实现):在这个函数中主要有一个NdisMInit ...…

查看全部问答>

jlink的RTT功能好强大~

最近使用JLINKV8调试中发现V4.9以上驱动有个RTT功能,可以很方便快捷的通过JLINK输出信息岛PC,大家有兴趣的可以搜搜相关的资料,如果需要晚些时候做个简单的教程~…

查看全部问答>