内存虚拟化技术,具体的实现方法有哪两种?

引入内存虚拟化技术后,内存系统中存在3种地址。
机器地址(Machine Address,MA):真实硬件的机器地址,在地址总线上可以见到的地址信号。
虚拟机物理地址(Guest Physical Address,GPA):经过VMM抽象后虚拟机看到的伪物理地址。
虚拟地址(Virtual Address,VA):Guest OS提供给其应用程序使用的线性地址空间。



虚拟地址到虚拟机物理地址的映射关系,记作g
虚拟机物理地址到机器地址的映射关系,记作f


操作系统的内存管理单元(Memory Management Unit,MMU)只能完成一次虚拟地址到物理地址的映射,但获得的物理地址只是虚拟机物理地址而不是机器物理地址,所以需要VMM参与,以获得总线上可以使用的机器地址为实现虚拟地址到机器地址的高效转换,目前普遍采用的方法是由VMM根据映射f和g生成复合映射f·g并直接写入MMU,具体的实现方法有两种:


MMU半虚拟化(MMU Paravirtualization)


这种方式主要为Xen所用

<
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是书的光盘。共分为两个部分,这是第一部分。 本书由浅入深、循序渐进地介绍了Windows驱动程序的开发方法与调试技巧。本书共分23章,内容涵盖了 Windows操作系统的基本原理、NT驱动程序与WDM驱动程序的构造、驱动程序中的同步异步处理方法、驱 动程序中即插即用功能、驱动程序的各种调试技巧等。同时,还针对流行的PCI驱动程序、USB驱动程序 、虚拟串口驱动程序、摄像头驱动程序、SDIO驱动程序进行了详细的介绍,本书最大的特色在于每一节 的例子都是经过精挑细选的,具有很强的针对性。力求让读者通过亲自动手实验,掌握各类Windows驱动 程序的开发技巧,学习尽可能多的Windows底层知识。   本书适用于中、高级系统程序员,同时也可用做高校计算机专业操作系统实验课的补充教材。 原创经典,威盛一线工程师倾力打造。深入驱动核心,剖析操作系统底层运行机制,通过实例引导,快 速学习编译、安装、调试的方法。   从Windows最基本的两类驱动程序的编译、安装、调试入手讲解,非常容易上手,用实例详细讲解 PCI、USB、虚拟串口、虚拟摄像头、SDIO等驱动程序的开发,归纳了多种调试驱动程序的高级技巧,如 用WinDBG和VMWARE软件对驱动进行源码级调试,深入Windows操作系统的底层和内核,透析Windows驱动 开发的本质。 本书是作者结合教学和科研实践经验编写而成的,不仅详细介绍了Windows内核原理,而且介绍了编程技 巧和应用实例,兼顾了在校研究生和工程技术人员的实际需求,对教学、生产和科研有现实的指导意义 ,是一本值得推荐的专著。              ——中国工程院院士   院士推荐   目前,电子系统设计广泛采用通用操作系统,达到降低系统的设计难度和缩短研发周期。实现操作 系统与硬件快速信息交换是电子系统设计的关键。   通用操作系统硬件驱动程序的开发,编写者不仅需要精通硬件设备、计算机总线,而且需要Windows 操作系统知识以及调试技巧。学习和掌握Windows硬件驱动程序的开发是电子系统设计人员必备的能力。   本书是作者结合教学和科研实践经验编写而成的,不仅详细介绍了Windows内核原理,并且介绍了编 程技巧和应用实例,兼顾了在校研究生和工程技术人员的实际需求,对教学、生产和科研有现实的指导 意义,是一本值得推荐的专著。 第1篇 入门篇 第1章 从两个最简单的驱动谈起 本章向读者呈现两个最简单的Windows驱动程序,一个是NT式的驱动程序,另一个是WDM式的驱动程序。 这两个驱动程序没有操作具体的硬件设备,只是在系统里创建了虚拟设备。在随后的章节中,它们会作 为基本驱动程序框架,被本书其他章节的驱动程序开发所复用。笔者将带领读者编写代码、编译、安装 和调试程序。   1.1 DDK的安装   1.2 第一个驱动程序HelloDDK的代码分析    1.2.1 HelloDDK的头文件    1.2.2 HelloDDK的入口函数    1.2.3 创建设备例程    1.2.4 卸载驱动例程    1.2.5 默认派遣例程   1.3 HelloDDK的编译和安装    1.3.1 用DDK环境编译HelloDDK    1.3.2 用VC集成开发环境编译HelloDDK    1.3.3 HelloDDK的安装   1.4 第二个驱动程序HelloWDM的代码分析    1.4.1 HelloWDM的头文件    1.4.2 HelloWDM的入口函数    1.4.3 HelloWDM的AddDevice例程    1.4.4 HelloWDM处理PNP的回调函数    1.4.5 HelloWDM对PNP的默认处理    1.4.6 HelloWDM对IRP_MN_REMOVE_DEVICE的处理    1.4.7 HelloWDM对其他IRP的回调函数    1.4.8 HelloWDM的卸载例程   1.5 HelloWDM的编译和安装    1.5.1 用DDK编译环境编译HelloWDM    1.5.2 HelloWDM的编译过程    1.5.3 安装HelloWDM   1.6 小结  第2章 Windows操作驱动的基本概念  驱动程序被操作系统加载在内核模式下,它与Windows操作系统内核的其他组件进行密切交互。本章主 要介绍Windows操作系统内核的基本概念,同时还介绍应用程序和驱动程序之间的通信方法。   2.1 Windows操作系统概述    2.1.1 Windows家族    2.1.2 Windows特性    2.1.3 用户模式和内核模式    
计算机应用技术 实用手册 Xnllz 2011.7.29 目录 第一章COMS的设置 1 1.STANDARD CMOS SETUP(标准CMOS设定)用来设定日期、时间、软硬盘规格、工作类类型。 3 2.BIOS能功设定 5 3.Advanced Chipset Features(芯片组设定) 6 4.Integrated Peripherals(集成设备设定) 8 5.PNP/PCI Configurations 即插即用与PCI设备设定,一般为默认。 9 6.POwer Management Features(电源管理模式设定) 9 7.Frequency/voltage control 超频控制 11 8.LOAD FAIL——Save defaults 恢复出厂设置 11 第二章 分区软件的应用 12 1.PQ魔术分区:首先用GHOST安装光盘引导起计算机,选择PQ分区进入工作界面。 12 2.DM分区的应用:首先用GHOST安装光盘引导起计算机,选择DM分区进入工作界面。 16 第三章 CMOS密码的清出与系统密码的清出 23 1、跳线短接法 23 2、下电池短接 23 二.系统密码清除,把CMOS第一引导设为光驱引导,用GHOST安装光盘起动,选择系统登录密码破解按回车进入 24 第四章 局域网组建 24 1.常用网络命令: 25 2.网线的制作: 27 3.局域IP地址配置: 27 4.采用TP-LINK路由器连接上网: 27 第五章 系统常用命令及格式转换 30 1.Msconfig 系统的关闭起动项命 30 2.Dxdiag系统信息查看命令 30 3.Gpedit.msc计算机管理命令 31 4.格式之间的转换,使用winavi进行转换 32 5.常用的快捷键,使用快捷可以帮助我节约时间。 33 6.开机常按F8可以进入安全模式或是带DOS命令的安全模式。 33 第六章GHOST的备份与恢复 34 第七章 综合应用 44 一.文件的后缀名, *号任意的文件名 44 二.内存出错或是系统出错引起蓝屏 48 三.本机病毒删除不了,解决方法是把硬盘拆下来换到别台主机上进行杀毒,要求挂上去的主机要采用正版杀毒软件,升过级的才可以 49 四.识别常见病毒,病毒一般是以隐藏形式藏匿在计算机的文件中,要把文件的隐藏属性打开。每一盘都有工具这个选项,如下图所示: 49 五.常用DOS命令 60 第一章COMS的设置 开机画面现在有两种,一种为AMI公司开发的,一种为Phoenix-award两家公司合并共同开发的;下面这张图为Phoenix-award开机自画面: Phoenix-award workstation BIOS V6.00PC,An Energy star Ally copyright(c) 1984-2003,Phoenix Technologies,LTD 这句英语的意思是:Phoenix-award这两家COMS芯片开发公司合并后共同开发第6号BIOS版本,采用美国电工电器省电标准,Phoenix技术有限公司,版权1984-2003 RS482-M 03/16/2006 FOR Tongfang 清华同方电脑公司选用的BIOS芯片代号为RS482-M 日期为2006年3月16号 Main Processor : AMD Athlon™64 x2 dual core Processor 3600+ CPU为AMD3600+ 速龙64位双核酷睿技术 Memory Testing: 524288k ok with 32M shared memory 内存为512兆 32兆的二级缓存 IDE Channel 0 master : None IDE Channel 0 Slave : None IDE Channel 1 master : HL-DT-STDVD-ROM GDR8164B 0L06 IDE Channel 1 Slave : None IDE Channel 2 master : WDC WD800BD-00LRA0 06.01D06 IDE Channel 2 Slave : None IDE 1号接口检测到光驱,IDE 2号接口检测到希捷硬盘为80GB,其它为NONE表示检测没有设备连接到接口上。 Warning!! Now system is in safe mode. Please re-setting CPU frequency in CMOS setup. 警告:现在系统处在安全模式,从新进入CMOS 进行设置。 CMOS checksun error-del anlts loaded 或是CMOS检查出错。 出现上面两种错是CMOS电池没电了.解决方法:打开机箱,把主板上的一节纽扣电池取出,换上一节新的既可,或是CMOS被放电了,从新进入CMOS设置时间保存并退出就可解决此问题。 Press F1 tocontinue ,DEL to enter SETUP 按F1可以继续启动,按DEL进入CMOS 下面这张图为AMI公司开发的BIOS界面: AMI BIOS (C) 2006 American megatrends,INC.ASUS P5B-Delusxe ACPI BIOS Revision 0507 CPU: INTEL(R) CORE(TM)2 CPU 6400 @ 2.13GHz Speed :4.01GHz Count :2 AMI公司2006年开发的BIOS版本信息,华硕主板采用的CMOS并修正了 0507芯片,CPU 为 英特尔 酷睿技术双核 型号为6400 主频为2.13GHz,总共处理速度为4.01GHz Press DEL TO run Setup 按del进入CMOS Press f8 for bbs popup 按F8弹出BBS网页 Press ALT+F2 to boot from system Recovery 按ALT+F2进入根录进行设置 PC2-4300 Dual Channel interleaved 双通道技术 Initializing usb Controllers..done 装载USB控制 2048MB OK 内存为2GB 开启计算机或重新启动计算机后,听见自检通过的声音后,按 “Del”键就可以进入CMOS的设置界面;要注意的是,如果按得太晚,计算机将会启动系统,这时只有重新启动计算机了。大家可在开机后立刻按DEL键直到进入CMOS。进入后,你可以用方向键移动光标选择CMOS设置界面上的选项,然后按Enter进入副选单,用ESC键来返回上一级菜单,用PAGE UP和PAGE DOWN键来选择具体选项,F10键保留并退出BIOS设置。 1.STANDARD CMOS SETUP(标准CMOS设定)用来设定日期、时间、软硬盘规格、工作类类型。 列表中存在PRIMARY MASTER 第一组IDE主设备;PRIMARY SLAVE 第一组IDE从设备;SECONDARY MASTER 第二组IDE主设备;SECONDARY SLAVE 第二组IDE从设备。这里的IDE设备包括了IDE硬盘和IDE光驱,第一、第二组设备是指主板上的第一、第二根IDE数据线,一般来说靠近芯片的是第一组IDE设备,而主设备、从设备是指在一条IDE数据线上接的两个设备,大家知道每根数据线上可以接两个不同的设备,主、从设备可以通过硬盘或者光驱的后部跳线来调整。 后面是IDE设备的类型和硬件参数,TYPE用来说明硬盘设备的类型,我们可以选择AUTO、USER、NONE的工作模式,AUTO是由系统自己检测硬盘类型,在系统中存储了1-45类硬盘参数,在使用该设置值时不必再设置其它参数;如果我们使用的硬盘是预定义以外的,那么就应该设置硬盘类型为USER,然后输入硬盘的实际参数(这些参数一般在硬盘的表面标签上);如果没有安装IDE设备,我们可以选择NONE参数,这样可以加快系统的启动速度,在一些特殊操作中,我们也可以通过这样来屏蔽系统对某些硬盘的自动检查。 图中2部分是DRIVE A和DRIVE B软驱设置,如果没有A或B驱动器,那么就设置NONE驱动器。我们可以在这里选择我们的软驱类型,当然了绝大部分情况中我们不必修改这个设置。 右下方还有系统内存的参数:BASE MEMORY:基本内存;extended 扩展内存;other 其它内存;total MEMORY 全部内存。 2.BIOS能功设定 在用光盘安装系统时就需要对此部分进设置,第一驱动改为光驱引导(First Boot Device),否则光驱不会引导装系统。 Quick Power On Self Test(快速启动选择): 当设定为[Enabled](启动)时,这个项目在系统电源开启之后,可加速POST(Power On Self Test)的程序。BIOS会在POST过程当中缩短或是跳过一些检查项目,从而加速启动等待的时间! Hard Disk Boot Priority(硬盘引导顺序): 此项目可选择硬盘开机的优先级,按下<Enter>的按键,你可以进入它的子选单,它会显示出已侦测到可以让您选择开机顺序的硬盘,以用来启动系统。当然,这个选项要在你安装了两块或者两块以上的系统才能选择! HDD Change Message: 当设定为[Enabled](启动)时,如果你的系统中所安装的硬盘有更动,在POST的开机过程中,屏幕会出现一道提示讯息。 First Boot Device / Second Boot Device / Third Boot Device / Boot Other Device: 在[First Boot Device]、[Second Boot Device]以及[Third Boot Device]的项目当中选择要做为第一、第二以及第三顺序开机的装置。BIOS将会依据你所选择的开机装置,依照顺序来启动操作系统!其中可以选择的设备根据你安装的设备而定! BOOT UP FLOPPY SEEK(开机时是否自动检测软驱); BOOT UP NUMLOCK STATUS(开机时小键盘区情况设定) SECURITY OPTION(检测密码方式)如设定为SETUP,则每次打开机器时屏幕均会提示输入口令(普通用户口令或超级用户口令,普通用户无权修改BIOS设置),不知道口令则无法使用机器;如设定为SYSTEM则只有在用户想进入BIOS设置时才提示用户输入超级用户口令。 3.Advanced Chipset Features(芯片组设定) 芯片组设定也是Bios设置里面的一个重点设置,这里就详细说明一下! DRAM Timing Selectable(内存参数设置选项): 这个项目会视内存模块的不同,为接下来四个项目设定最佳的计时方式。默认值为「By SPD」。这个默认值会读取SPD (Serial Presence Detect) 装置的内容,并且依据SPD内容设定这四个项目。内存模块上的EEPROM (只读存储器) 储存有关模块的重要参数信息,例如内存类型、大小、速度、电压接口及模块储存区域。 CAS Latency Time: 这个项目可控制DRAM读取指令与数据成为真正可用的时间之间的延迟时间。较低的CAS周期能减少内存的潜伏周期以提高内存的工作效率。因此只要能够稳定运行操作系统,我们应当尽量把CAS参数调低,从而提高内存的运行速度。反过来,如果内存运行不稳定,可以将此参数设大,以提高内存稳定性。 Act to Precharge Delay: 这个项目控制了给DRAM参数使用之DRAM频率的数值。同理,数值小性能高,但是对内存的质量也要求严格! DRAM RAS# to CAS# Delay: 这个项目可控制DRAM作用指令与读取/写入指令之间的延迟时间,有2,3,4几种选择。数值越小,性能越好。 DRAM RAS# Precharge: 这个项目是用来控制当预充电(precharge)指令送到DRAM之后,频率等待启动的等待时间。预充电参数越小则内存读写速度就越快。 以上的内存参数设置一般可以不动!让默认的就可以了,但是超频玩者是肯定不会放过任何可以提高性能的东西的,所以如果你想在这里让你的电脑提升一点性能的话,就必须慢慢试验,选择一个适当的参数才能让你的计算机达到性能和稳定的最佳状态! Video BIOS Cacheable(影像快取): 如同系统BIOS的快取功能,启用影像BIOS的快取功能将允许存取影像BIOS自C0000H到C7FFFH具有快取功能,如果快取控制器也被启用。高速缓存的大小愈大,影像效能将会更快速。 Memory Hole At 15M-16M(扩展卡内存分配): 当设定为[Enabled](启动)时,将会有15M-16M的内存空间预留给特别需要此设定的ISA扩充卡。这会使得内存有15 MB以上的空间无法让系统使用,这个项目请使用系统的默认值。 Delay Prior to Thermal(激活延时设置): 此项目可用来选在择温探(Thermal)装置动作之前的延迟时间。 AGP Aperture Size(AGP卡槽内存分配设置): 这个项目可指定让AGP装置来使用的系统内存大小,这取用大小是PCI内存地址范围的一部份,可分配给图形内存的空间。 Init Display First: 这个项目可选择当系统开机时先行对AGP或是PCI插槽来做初始化的动作。 [AGP]:当系统开机时,它将会先对AGP插槽来做初始化的动作。 [PCI Slot]:当系统开机时,它将会先对PCI插槽来做初始化的动作。 AGP Data Transfer Rate(AGP速度设置): 这个项目允许你选择AGP装置的数据传输速率,更高的数据传输速率可对您的系统提供更快以及更佳的图形处理能力。请确认您的显示卡可以支持您所选择的模式,一般用默认的就可以。 4.Integrated Peripherals(集成设备设定) 这个是管理计算机的主板集成设备和端口的选项,具体项目因为主板不同,所以其中的设置会有所不同。 OnChip IDE Device: 主板IDE驱动接口控制 OnChip PCI Device 主板PCI接口控制 OnChip USB Controller: 这个选项开启或关闭USB端口。 USB 2.0 Controller: 这个选项开启或关闭USB 2.端口传输模式。 USB Keyboard Support Via: 此项目允许您去选择 [ENABLED],以让您在DOS环境下可以使用USB键盘,或是选择 [OS] 以在OS环境下使用。在默认情况下是关闭的即:[DISABLED],只有打开在DOS下才可以用。 USB Mouse Support Via: 此项目允许您去选择 [ENABLED],以让您在DOS环境下可以使用USB鼠标,或是选择 [OS] 以在OS环境下使用。在默认情况下是关闭的即:[DISABLED],只有打开在DOS下才可以用。 AC97 Audio 这个选项开启或关闭集成声卡设备。有时候在系统的任务栏你见不到小喇叭有可能在这里被关闭了,即:[DISABLED],遇到这种情况可从新进入COMS把此项打开即可,即:[ENABLED]。 SATA MODE 这个项目是对SATA接口控制,一般为RAID模式,如接上SATA接口的光驱就可改为IDE模式,这样才能正常工作。 VIA ONBOARD LAN主板网卡接口控制,一般为默认即可。 5.PNP/PCI Configurations 即插即用与PCI设备设定,一般为默认。 Resources Controlled By: 这个项目可对所有的开机以及即插即用之兼容装置进行组态的动作。 [Auto]: 系统将会自动地侦测所有的设定。 [Manual]: 在「IRQ Resources」选单中选择特定的IRQ资源。 IRQ Resources: 这个项目可设定各别系统的中断为[PCI Device]或是[Reserved]中之任一者。 PCI/VGA Palette Snoop: 这个项目可决定哪种MPEG ISA/VESA VGA卡可以(或是不能)与PCI/VGA一起运作。 [Enabled]: MPEG ISA/VESA VGA卡可以与PCI/VGA一起运作。 [Disabled]: MPEG ISA/VESA VGA卡不能与PCI/VGA一起运作。 6.POwer Management Features(电源管理模式设定) 选择APM Configuration进入设置界面 选择Hardware monltor进入设置界面 7.Frequency/voltage control 超频控制 超频的前提是主板要支持超频功能,并且CPU的风扇要换散热好的,否则就会烧坏CPU或是主板,此功能要慎用。 CPU HOST CLOCK CONTROL [DISABLED] 一般进入后是关闭的,把DISABLED改为ENABLED就可以改变主频的大小了,即:CPU HOST FREQUENCY(MHZ)[166]把中括号里的数字改变超就可以超频了。频即改变CPU主频的大小。 PCI/AGP Frequency(MHZ)[AUTO] PCI设备与显卡频率的控制。一般为自动。 DRAM COLCK (MHZ)[AUTO] 动态随机读取时钟信号,默认为自动。 CPU OVERVOLTAGE CONTROL [AUTO] CPU的额外工作电压,默认为自动。 AGP OVERVOLTAGE CONTROL [AUTO] 显卡的额外工作电压,默认为自动。 DIMM OVERVOLTAGE CONTROL [AUTO] 双列直插内存模块的额外工作电压,默认为自动。 8.LOAD FAIL——Save defaults 恢复出厂设置 在设置一些项后,又不清楚的情况下可,用此项恢复出厂设置恢复到原来出厂的样子。 9.LOAD Optimized defaults 优化设置。 10.SET superisor password CMOS密码设置 11.SET user password 用户密码设置 12.SAVE&EXIT SETUP 保存并退出 每次出了更改设置后都要保存,这样才起作用。 13.QUIT WITHOUT SAVING(Y/N) 退出不保存。 注意:在从起后,显示器上出现 Floppy drive A : ERROR 为A盘引导出错,要求按F1继续;此时进入CMOS把DRIVE A:改为 NONE 即可。如果出现:disk boot failure,insert system disk and press enter 种这信息为找不到硬盘或是系统坏掉了;解决办法:先从新装一次系统,如果从装系统问题还是一样,把机箱打开把硬盘的接口从接一个看看,看看线是否接好,是否有松动的地方,如果还是出现的话,把硬盘换到另外一台机子上试一试,这样做的目的是查看硬盘是不是好的,如果以上方法都试过后仍然出现错误提示,那么有很大的可能是硬盘坏了,只有换硬盘了。 第二章 分区软件的应用 现在主流的分区软件有三种,分别是PQ魔术分区、DM分区、FDISK分区;在这里我主要讲PQ和DM分区,FDISK分区在教材上有,在这里我就不多说了。 1.PQ魔术分区:首先用GHOST安装光盘引导起计算机,选择PQ分区进入工作界面。 没有分过区的硬盘在第一次分区是灰色的,如上图所示。在未分配上右击鼠标,点击建立,出现下图所,创建主要分区。 如果装2000版本的系统就采用NTFS格式,大小这一栏要根据硬盘的大小按一定比例划分,如是80G的硬盘,主分区也就是我们所常说的C盘最好分10000MB即10GB。 如果装XP版本的系统就采用FAT32格式,大小这一栏要根据硬盘的大小按一定比例划分 主分区建好后,剩下的硬盘空间全部分为逻辑分区,格式这一栏如果装2000版本的系统就采用NTFS格式,如果装XP版本的系统就采用FAT32格式。大小分配好后点确定。 把主分区设为设定为作用,相当于FDISK分区中的激活C盘。如果不把C盘激活,系统就装不上,出错信息为:OS ERROR! 在每个分区上点鼠标右键,先择格式化,最后确定。 从新启动计算机就可以装系统了。 2.DM分区的应用:首先用GHOST安装光盘引导起计算机,选择DM分区进入工作界面。 选择“(A)dvanced Options”进入二级菜单,然后选择“(A)dvanced Disk Installation”进行分区的工作。 此主题相关图片如下: 接着会显示硬盘的列表,直接回车即可 此主题相关图片如下: 如果你有多个硬盘,回车后会让你选择需要对哪个硬盘进行分区的工作。 此主题相关图片如下: 然后是分区格式的选择,一般来说我们选择FAT32的分区格式 此主题相关图片如下: 接下来是一个确认是否使用FAT32的窗口,这要说明的是FAT32跟DOS存在兼容性,也就是说在DOS下无法使用FAT32。 此主题相关图片如下: 这是一个进行分区大小的选择,DM提供了一些自动的分区方式让你选择,如果你需要按照自己的意愿进行分区,请选择“OPTION (C) Define your own”。 此主题相关图片如下: 接着就会让你输入分区的大小: 此主题相关图片如下: 首先输入的主分区的大小,然后输入其它分区的大小。这个工作是不断进行的,直到你硬盘所有的容量都被划分。 此主题相关图片如下: 完成分区数值的设定,会显示最后分区详细的结果。此时你如果对分区不满意,还可以通过下面一些提示的按键进行调整。例如“DEL”键删除分区,“N”键建立新的分区。 此主题相关图片如下: 设定完成后要选择“Save and Continue”保存设置的结果,此时会出现提示窗口,再次确认你的设置,如果确定按“Alt+C”继续,否则按任意键回到主菜单。 此主题相关图片如下: 接下来是提示窗口,询问你是否进行快速格式化,除非你的硬盘有问题,建议选择“(Y)ES”。 此主题相关图片如下: 接着还是一个询问的窗口,询问你分区是否按照默认的簇进行,选择“(Y)ES”。 此主题相关图片如下: 最后出现是最终确认的窗口,选择确认即可开始分区的工作。 此主题相关图片如下: 此时DM就开始分区的工作,速度很快,一会儿就可以完成,当然在这个过程中你要保证系统不要断电。 此主题相关图片如下: 完成分区工作会出现一个提示窗口,不用理会按任意键继续。 此主题相关图片如下: 面就会出现让你重新启动的提示 此主题相关图片如下: 这样就完成了硬盘分区工作.按CTRL+ALT+DEL重新起动,装系统。 第三章 CMOS密码的清出与系统密码的清出 一.在忘记系统密码和计算机不能启动的处理时经常提到的一个操作就是"CMOS放电"。 放电前一定要关闭计算机,并且拔掉机箱电源。 CMOS放电方法一般有2种 1、跳线短接法 主板后备电池的附近一般都有一个在跳线,旁边注有RESET CMOS、CLEAN CMOS、CMOS CLOSE、CMOS RAM RESET、CMOS Reset或Ext. Buttery等字样。 跳线开关一般为3脚,在1、2两脚上一般有一个跳接器,此时将其拔下接到2、3脚上短接数秒即可放电。 放电后,应记着将跳线或开关恢复到正常状态,否者计算机有可能不能启动甚至损坏机器。 在原装品牌机上也有将跳线做成DIP开关的,将CMOS开关拔到ON的位置与短接跳线的作用相同。 另外应该注意,几乎所有的主板都有清除CMOS的跳线和相关设置,但应厂商不能而各有所异,例如有的主板的CMOS清除设备并不是我们长见的跳线,而是很小的焊接锡点,使用金属短接一下同样可以达到目的。 此法关键之处在于找到相应的跳线(如果没有主板说明书,则难度就更大了),跳线一般在电池或CMOS芯片附近。 2、下电池短接 后备电池在主机断电期间是通过二级管向CMOS RAM提供电源的。用导线短接CMOS的VDD和地线形成放电回路进行放电即可清除CMOS中的数据(包括口令)。 在不能确定放电跳线位置时,可以将主板供电锂电池取出,然后用金属物件短接一下电池槽中的两个电极片,使存在电路电容中的残余电荷消失,重新装上锂电池,重新开机设置一下BIOS参数即可。 注意:取出电池后不作电极短接,会需很长时间才能使CMOS电路中残余的电荷放尽,残余电荷不放尽便重新装入电池,BIOS 随机参数便不会消除。 二.系统密码清除,把CMOS第一引导设为光驱引导,用GHOST安装光盘起动,选择系统登录密码破解按回车进入 [1] Choose logical drive 只清除逻辑驱动器的密码 [2] Search for ms sam datahbase(s) on all hard disk and logical drives 清除所有驱动器的密码。 [3] EXIT 退出 Your choice [2] 选择2按回车 继续按回车,接着每个数字都输入一次,每次输入后都按回车,按Y确认清除,再按回车确认。最后一直按键盘上的ESC键退到安装界面,从硬盘起动,密码清除。 第四章 局域网组建 TCP/IP(Transmission Control Protocol/Internet Protocol的简写,中文译名为传输控制协议/互联网络协议)协议是Internet最基本的协议,简单地说,就是由底层的IP协议和TCP协议组成的。 “传输控制协议”(TCP,Transsmission-Control Protocol)和“因特网协议”(IP,Internet Protocol)即TCP/IP协议。 IP地址分为网络地址和主机地址二个部分,A类地址前8位为网络地址,后24位为主机地址,B类地址16位为网络地址,后16位为主机地址,C类地址前24位为网络地址,后8位为主机地址,网络地址范围如下表所示: 种类 网络地址范围 A 1.0.0.0 到126.0.0.0有效 0.0.0.0 和127.0.0.0保留 B 128.1.0.0到191.254.0.0有效 128.0.0.0和191.255.0.0保留 C 192.0.1.0 到223.255.254.0有效 192.0.0.0和223.255.255.0保留 D 224.0.0.0到239.255.255.255用于多点广播 E 240.0.0.0到255.255.255.254保留 255.255.255.255用于广播 使用ADSL需要PC机、ADSL Modem、10M\100M自适应网卡和虚拟拨号软件 ADSL是一种非对称的DSL技术,所谓非对称是指用户线的上行速率与下行速率不同,上行速率低,下行速率高,特别适合传输多媒体信息业务,如视频点播(VOD)、多媒体信息检索和其他交互式业务。ADSL在一对铜线上支持上行速率512Kbps~1Mbps,下行速率1Mbps~8Mbps,有效传输距离在3~5公里范围以内。 ADSL的特点:   1.一条电话线可同时接听,拨打电话并进行数据传输,两者互不影响。   2.虽然使用的还是原来的电话线,但adsl传输的数据并不通过电话交换机。   3.adsl的数据传输速率是根据线路的情况自动调整的,它以“尽力而为”的方式进行数据传输。 1.常用网络命令: 在DOS下运用:Ping命令,例:Ping www.baidu.com / ping 127.0.0.1,这个命主要用于检测网络是否通,查看网络延时。 Ping 百度之后返回的结:IP地址为220.181.6.18 传输为32字节,TIME为时间,TTL为中转路由器个数,TTL=128-54。发送4帧,收到4帧,丢失为0,网络最小延时为88ms , 最大延时为89ms ,平均延时为88ms这样的数据才正常。 Ping 127.0.0.1为环路自检,查看本地网络是否正常。上图显示为正常。 Ipconfig IP地址查看命令,主要用于查看网络IP地址。 Ip address 192.168.1.100 IP地址,Subnet mask 255.255.255.0 子网掩码 default gateway 192.168.1.1网关。 2.网线的制作: 需要做线钳一把,RJ-45水晶头,超5类双绞线(5E),网络测试仪等。做线规则:①双机对联线做法:绿白、绿、橙白、蓝、蓝白、橙、棕白、棕;另一头做法:橙白、橙、绿白、蓝、蓝白、绿、棕白、棕 ②直连线做法,两头一样,即:橙白、橙、绿白、蓝、蓝白、绿、棕白、棕。 3.局域IP地址配置: 192.168.x.x, 其中经为1-254之间任意值,要注意的是在同一个段中网段的IP值要一样,主机名不能相同,192.168.x.x,如两台机子联机IP设为: 192.168.1.13 192.168.1.14 不难看出1这个值是网段,要相同;13与14是主机的值,不能相同。 4.采用TP-LINK路由器连接上网: 在地址栏中录入192.168.1.1按回车,如下图所示: 出现如下图所示的界面:点下一步; 选择ADSL虚拟拨号(pppoE),点下一步 输入上网账号和上网口令后点下一步 点完成,这样就完成上网设置。上网正常显示如下图所示: 第五章 系统常用命令及格式转换 1.Msconfig 系统的关闭起动项命 点击开始 运行 录入Msconfig按回车进入工作界面,如下图: 点起“启动” ctfmon 对应任务栏的输入法图标,avp对应的是卡巴斯基杀毒软件的起动图标 2.Dxdiag系统信息查看命令 3.Gpedit.msc计算机管理命令 4.格式之间的转换,使用winavi进行转换 当选择多个文件时,要创建成一个DVD目录,多个标题,即对应的英为:ONE DVDS,Separate titles Create separate DVDs 创建多个DVD目录;Merge into one title所有文件整合成一个目录。 如果Winavi转换不了的文件可配合Total Video Converter 使用,如下图所。 5.常用的快捷键,使用快捷可以帮助我节约时间。 CTRL+A 全选 CTRL+ C复制 CTRL+V粘贴,这两组组合键是选复制后粘贴。 CTRL+S保存 CTRL+O打开 CTRL+Z 撤消上一步操作 CTRL+X剪切 CTRL+N新建 ALT+F4快速关机 ALT+TAB强行跳出正在操作的界面 CTRL+ALT+DEL 重新起动 6.开机常按F8可以进入安全模式或是带DOS命令的安全模式。 有一些病毒我们在系统下是杀不掉的,这时我们可以进入带安全模式的系统下再用杀毒软件去扫描病毒,这样有可能把病毒清除掉。进入带DOS命令的安全模式我们可以用它来起动GHOST文件。 第六章GHOST的备份与恢复 1 重新启动计算机 用光盘引导,选择DOS工具进入DOS操作界面。 2 在电脑启动时 快速 连续 按键盘最上一排的 F8 3 按了后会显示 黑底白字的 系统选项 通常上面有6 个选项 4 此处我们需要了解的是1 正常模式 3 安全模式 6 进入DOS界面 5 ghost通常必须要在dos 运行 因此选取 6 进入dos 界面 按上下选择箭头 选定 6 回车 6 进入后会出现DOS 提示符 如 C:\> 此处意思为 现在显示的是C盘 7 在c:\> 后面输入d:此处的意思为进入D盘 输入后回车 出现d:\> 8 再在d:\>后面输入 g 此处意思为运行 g 程序 此处的g 实际上就是原有的 ghost 程序 9 输入后回车 就会进入GHOST 的操作界面 见 图一 附 DOS 下基本操作命令 每一个命令输入完毕后回车进入下一个操作 1 c : 进入C盘 同样的道理 D :进入D盘 E: F: 进入E盘F盘 2 dir 查看 查看目录下面的文件 如c:\> dir 是指查看 C盘里面的文件 3 cd 文件夹名字 打开文件夹 如cd 123 意思是说 打开123这个文件夹 4 exe 是程序的意思 如这ghost 改名字后为g 在dos下面就叫 g.exe 5 在dos下面 如果要执行程序的话 输入程序名字 回车即可 如 运行g.exe 输入g 回车 6 cd ..进入上一个目录 如此时是c:\>windows 是表示在C盘的windowd 中 如果说此时输入 cd .. 则会进入C盘 屏幕上显示出c:\> 三 打包 制作镜像文件 对于通常用户来说 仅仅只是使用GHOST里的分区备份功能 故此此处只讲解分区备份部分 1 按上所说处理好打包前的工作(系统状况最好 驱动安装好 相关软件安装好 清理垃圾文件 磁盘查错 磁盘碎片整理……) 后 重新启动 快速按F8 进入DOS界面 运行 G.exe 2 注意:若要使用备份分区功能 (如要备份C盘)必须有两个分区(最少要有C D二个分区)以上 而且C盘所用容量必须大于D盘的未用容量(通常C盘用了二GB 则D盘必定要有二GB以上的空间) 保证D盘上有足够的空间储存镜像 3 进入图一所示GHOST 界面后 由于是在DOS下 只能用键盘操作 按回车 进入下一个界面 4 DOS界面下 键盘操作:TAB键进行切换 回车键进行确认 方向键进行选择 如图二 用方向键选择 选择菜单 Local(本机)--Partition(分区)--To Image(到镜像) 通俗一点说就是1-2-2 先选中 1 再选取 弹出选项 2 再选取弹出选项 2  5 选中后回车 将出现如图三 选择硬盘 此处第一次是显示的第一个硬盘的信息 如果有二个硬盘的话 回车后会出现二个硬盘的信息选项 通常我们只一个硬盘 此处操作按回车  6 选中后回车 将出现下一个操作界面 如图四   选择要备份的分区 通常我们是选择C盘 也就是系统盘 此处操作 1 选择分区(可以用方向键上下选择 用TAB选择项目 )通常选择第一个就是C盘 分区 2 选定分区 回车确定 3 按一下TAB 再次确定 回车 就表示已经选定为 备份C盘 如果说您不能确定是不是备份的C盘 建议您在WINDOWS的时候 查看一下您的各个分区的大小 再对照就可以知道的 因此处是借鉴别的人的图 所以需要到您区别一下   7 选中后回车 将出现如图5 此处需要是输入备份文件名字 此处操作 1 按TAB选定到图片下面的输入名字的地方 在空格内输入您确定的名字 回车 2 此处选择的名字为 windows 当然您也可以选择别的名字的 3 后缀名为.gho 8 输入后回车 就会进入如下所示 见 图6 此处是提示您选择压缩模式 上面共有三个选择: No表示不压缩,Fast表示适量压缩,High高压缩 限于适用与速度 通常我们选择适量压缩 Fast 9 输入后回车 就会进入下一操作界面 见 图7 此处是提示您选择是否开始备份 共有二个选择 YES 是 NO 不 我们需要选定YES 此处操作 1 按左右方向键 选定YES 回车 10 输入后回车 就会进入下一个操作界面 见 图8 此处是提示GHOST根据您的指示 开始备份 此处操作 1 此处请不要做任意动作 您的任意动作都会带来不可预见之后果 请1 不要按键盘 2 不要关机 静心等待到进度条走完 11 进度条跑完后会进入到下一个 操作界面 见 图9 此处是提示GHOST根据您的指示 已经备份完毕 回车退出 此处操作 1 回车 备份完毕 重新启动就可以了  备份的文件以GHO后缀名储存在设定的目录中 如上所述 您的这个文件名叫 windows.gho 此文件在windows界面下是不显示什么的 在DOS下运行GHOST显示为黄色 您的这个 windows.gho 保存在D盘目录下 就是和 G.EXE 一个目录下 通常建议您将镜像文件复制一下 放在安全的地方防止误删除  三 解包 还原镜像文件 要提醒您注意的是在使用 GHSOT 软件恢复系统时,请勿中途中止!如果您在恢复过程中重新启动了计算机那么您的计算机将无法启动!必定要接双硬盘或用光盘系统启动才可恢复 在您的系统遇到以下的情况之一 怀疑或确定您的系统中了病毒或木马 系统运行了半个月以上 或出现无故死机 变慢 及相关类别 您需要还原您的系统镜像文件 以保证到系统的安全与良好运行 1 重新启动 快速按F8 进入DOS界面 运行G.exe 进入GHOST界面 回车 2 回车后 就会进入GHOST 的操作界面 见 图10 此处操作 选择菜单到 Local(本机)--Partition(分区)--From Image 通俗一点说就是1-2-3 先选中 1 再选弹出选项 2 再选项弹出选项 3 3 选定后回车 就会进入下一个操作界面 见 图11 此处是提示您 选择 需要还原的镜像文件 如上所述 我们打的包是 windows.gho 所以我们这里选择windows.gho 1 按上下方向键 选择好windows.gho 回车 4 输入后回车 就会进入下一个操作界面 见 图12 此处显示硬盘信息 不需要处理 直接回车 5 输入后回车 就会进入下一个操作界面 见 图13 此处显示硬盘信息 不需要处理 直接回车 6 输入后回车 就会进入下一个操作界面 见 图14 此处显示分区信息 提示您是需要还原到哪珍上分区 默认是还原第一个分区 也就是C盘系统盘 如果您是要还原到此分区 不需要处理 直接回车 此处操作按 回车 7 输入后回车 就会进入下一个操作界面 见 图15 此处显示信息 此处是为了防止误操作 再次提醒您是不是一定要还原镜像文件 您到了这一步 如果说没有十分的把握 这是最后一次机会 默认是NO 按下可以退出到起始界面 如果选择YES 将进行还原操作 此操作到了此处已经不可逆转 此处需要的是用左右方向键 选择YES 回车 8 输入后回车 就会进入GHOST 的操作界面 见 图16 此处是提示GHST根据您的指示 开始还原镜像文件 此时千万不要进行操作 1 此处请不要做任意动作 您的任意动作都会带来不可预见之后果 包括系统不能启动 请 1 不要按键盘 2 不要关机 静心等待到进度条走完 9 输入后回车 就会进入下一个操作界面 见 图17 此处是提示GHST根据您的指示 已经备份完毕 给出的二个选择 一 默认为重新启动 二 以后再重新启动 此处需要的是重新启动 至此 您已经成功的还原了您的系统镜像 您的系统又和原来最最良好的时候是一样的了 恭喜您的电脑有了百毒不侵 之身 有了可以防止误操作的万事无忧之方法 有了以上的说明 在通常的情况下 您可以随时随地将您的系统还原到最良好运行之境地 第七章 综合应用 一.文件的后缀名, *号任意的文件名 1. *.bmp格式是微软制定的图形标准,最大的优点就是在pc上兼容度一流,就算不装任何看图软件,用windows的画图程序一样可以看。储存为bmp格式的图形不会失真,但容量会很大。 2. *.jpg格式是目前网络上最流行的图形格式,它可以把文件容量压缩到最小的格式。用Photoshop图形处理软件处理jpg格式的图像,它支持不同程度的压缩比,您可以视情况调整压缩倍率,压缩比越大,品质就越低;相反地,压缩比越小,品质就越好。不过要注意的一点是,这种压缩法属于失真型压缩,文件的压缩会使得图形品质下降。 3. *.doc为Word文档,一般看见后缀名为doc的文件就要用Word应用程序才能打开。 4.*.xls为Excel文档,一般看见后缀名为xls的文件就要用Excel应用程序才能打开。 5. *.ppt为Powerpoint文档也就是幻灯片文档,一般看见后缀名为ppt的文件就要用Powerpoint应用程序才能打开。 6.*.txt为文本文档,一般看见后缀名为txt的文件就要用记事本应用程序才能打开。 7.*.pdf便携文档格式 (PDF) 由 Adobe 发明,已成为全世界各种标准组织用来进行更加安全可靠的电子文档分发和交换的出版规范。如今,PDF日益成为一种流行的格式,许多政府及官方媒体的文档,都以 Adobe PDF 作为标准格式。Adobe Reader 8.0 可以浏览 PDF, 但不能创建 PDF! 8. *.mp3 MP3全称是动态影像专家压缩标准音频层面3(Moving Picture Experts Group Audio Layer III)。是当今较流行的一种数字音频编码和有损压缩格式,它设计用来大幅度地降低音频数据量,而对于大多数用户来说重放的音质与最初的不压缩音频相比没有明显的下降。它是在1991年由位于德国埃尔朗根的研究组织Fraunhofer-Gesellschaft的一组工程师发明和标准化的。 简单的说,MP3就是一种音频压缩技术,由于这种压缩方式的全称叫MPEG Audio Layer3,所以人们把它简称为MP3。 9.*.ini 文件是windows的系统配置文件,统管windows的各项配置,一般用户就用windows提供的各项图形化管理界面就可实现相同的配置了;在Windows系统中,INI文件是很多,最重要的就是“System.ini”、“System32.ini”和“Win.ini”。该文件主要存放用户所做的选择以及系统的各种参数。一般ini为后缀名的文件不能删除哟! 10.*.bat是批处理文件,是windows32底下的应用程序,可以同时按条件处理一批文件。 这里有个例子: 在电脑屏幕的左下角按“开始→程序→附件→记事本”,把下面的文字复制进去,点“另存为”,路径选“桌面”,保存类型为“所有文件”,文件名为“清除系统yjh.bat”,就完成了。记住后缀名一定要是.bat,ok!你的垃圾清除器就这样制作成功了! 双击它就能很快地清理垃圾文件,大约一分钟不到。 @echo off echo 正在清除系统垃圾文件,请稍等...... del /f /s /q %systemdrive%\*.tmp del /f /s /q %systemdrive%\*._mp del /f /s /q %systemdrive%\*.log del /f /s /q %systemdrive%\*.gid del /f /s /q %systemdrive%\*.chk del /f /s /q %systemdrive%\*.old del /f /s /q %systemdrive%\recycled\*.* del /f /s /q %windir%\*.bak del /f /s /q %windir%\prefetch\*.* rd /s /q %windir%\temp & md %windir%\temp del /f /q %userprofile%\cookies\*.* del /f /q %userprofile%\recent\*.* del /f /s /q "%userprofile%\Local Settings\Temporary Internet Files\*.*" del /f /s /q "%userprofile%\Local Settings\Temp\*.*" del /f /s /q "%userprofile%\recent\*.*" echo 清除系统LJ完成! echo. & pause 以后只要双击运行该文件,当屏幕提示“清除系统LJ完成!就还你一个“苗条”的系统了!!到时候再看看你的电脑,是不是急速如飞呢? 11.*.RMVB主要用于网络视频格,即电影格式,其特点是比AVI格式小,图像清析,便于网络传输;所谓RMVB格式,是在流媒体的RM影片格式上升级延伸而来。VB即VBR,是Variable Bit Rate(可改变之比特率)的英文缩写。我们在播放以往常见的RM格式电影时,可以在播放器左下角看到225Kbps字样,这就是比特率。影片的静止画面和运动画面对压缩采样率的要求是不同的,如果始终保持固定的比特率,会对影片质量造成浪费。   而RMVB则打破了原先RM格式那种平均压缩采样的方式,在保证平均压缩比的基础上,设定了一般为平均采样率两倍的最大采样率值。将较高的比特率用于复杂的动态画面(歌舞、飞车、战争等),而在静态画面中则灵活地转为较低的采样率,合理地利用了比特率资源,使RMVB在牺牲少部分你察觉不到的影片质量情况下最大限度地压缩了影片的大小,最终拥有了近乎完美的接近于DVD品质的视听效果。可谓体积与清晰度“鱼与熊掌兼得”,其发展前景不容小觑。 12.*.AVI——Audio Video Interleave,即音频视频交叉存取格式。最早由Microsoft公司于1992年推出。在AVI文件中,运动图像和伴音数据是以交织的方式存储,并独立于硬件设备。构成一个AVI文件的主要参数包括视像参数、伴音参数和压缩参数等。而且由于AVI本身的开放性,获得了众多编码技术研发商的支持,不同的编码使得AVI不断被完善。而随着MPEG的崛起,当前流行的AVI格式一般采用DviX5以及Xvid的MPEG4编码器压制,视频的画质和体积都得到了很好的控制。举个例子,一部高品质的DVD电影的容量一般为4-5GB,但经过DivX或XviD编码后的大小只有650-700MB,仅仅为原DVD容量的八分之一,图像品质却与DVD相当使得AVI格式成为电影发烧友的首选格式之一。 13.*.FLV流媒体格式是一种新的视频格式,全称为Flash Video,Macromedia为了尽早用FLV格式来垄断Web Video应用,短短两三年的时间,FLV就成为了目前最主流的在线视频播放格式,随着被新一代的视频播客网站YouTube、土豆等网站的广泛采用,以及Google、百度、新浪、腾讯、猫扑、Maxthon、雅虎等国际国内著名互联网公司的相继投入与看好,还有国际资本大量进入视频播客领域,FLV格式被极大的推广。 14.*.3gp与*.mp4这两种格的文件主要是在手机上应用的比较广泛,其特点是图像小,但在压缩的过程中有损耗,图像不清析,只是适用像手机这样的小屏幕。 15.*.EXE为可执行文件,如果没有可执行文件哪么应用程就运行不了。一般全名为:setup.exe 16. *.gho 为GHSOT生成的镜像文件,主要是系统的备份文件。 17.*.dll为系统的动态库连接文件,静态连接所需要做的工作是多少(假设按windwos来说他有上千个这样的函数,一共有100多个程序来使用,那静态连接需要100000次的更新,动态连接只需要1000次),从而也节省了内存的空间。动态连接库不一定是DLL扩展名的,也可以是ocx、vbx、exe、drv 等等 二.内存出错或是系统出错引起蓝屏 电脑开机就出现的蓝色屏幕内容如下: “ A problem has been detected and windows has been shut down to prevent damage to your computer. If this is the first time you've seen this stop error screen,restart your computer. If this screen appears again, follow these steps: 1.Check to make sure you have adeguate disk space , if a driver is identified in the stop message ,disable the driver or check with the waufacturer for driver updates try changing video adapters . 2.Check with your hardware vendor for any bios updates ,disable bios memoryor options such as caching or shadowing 。 if you need to use safe mode to remove or disable computers,restart your computer 3.Press F8 to select;advanced star up options,and the select safe mode。 Technical information: *** stop:0x0000007E(0x0000005,0xF7711EC5,0xF78A21A4,0xF78A1EA0) ***partMgr.SYS, Adress F7711ECS base at F770F000, Date stamp 480253b0 大致意思是:出现蓝问题是WINDOWS系统自动关闭,阻止计算机被毁坏;如果是第一次出,从新启动计算机,从启后还是一样出现的话,照着下面的步骤: 1.检查硬盘空间,看是否足够装系统; 2.检查内存,看内存是否有问题; 3.按F8进安全模式看看是否能进带安全模式的系统。 出现这种问题般解决办是从装系统,如是不能,把内存拿下来用湿毛巾擦下再用干毛巾擦干,再卡回主机,看问题能否解决;都有能解决哪么把内存拿到其它正常的主机上看看内存是不是好的。如果是内存坏了,哪就要换内存了。 三.本机病毒删除不了,解决方法是把硬盘拆下来换到别台主机上进行杀毒,要求挂上去的主机要采用正版杀毒软件,升过级的才可以 如果是要从新装系统哪么要求这样做:先格式化C盘,如果要装GHOST版本的系统,D盘也要格式化掉,因为GHOST版本的系统有些文件要装到D盘上去,这样是避免系统感染上病毒,系统装好后用光盘装杀毒软件,或是用U盘拷贝过来装,前提是保正U盘和所拷贝的杀毒软件没得病毒哟。注:除了格式化过的盘可以点击,其它盘一律不能点哟,不然的话就白辛苦了。装好杀毒软件并升过级,全盘扫苗过后才能点其它盘。 四.识别常见病毒,病毒一般是以隐藏形式藏匿在计算机的文件中,要把文件的隐藏属性打开。每一盘都有工具这个选项,如下图所示: 1、什么是计算机病毒: 计算机病毒,是指编制或者在计算机程序中插入的破坏计算机功能或者毁坏数据,影响计算机使用,并能自我复制的一组计算机指令或者程序代码。 2、常见病毒的特征及防治方法 如果双击文件图标打不开,哪么就是感染病毒了。 ①新欢乐时光 病毒现象:当您选择“文件夹选项”,并且选择“显示所有文件”的时候,您可以在很多目录中看到原先是隐藏的folder.htt和desktop.ini文件,而且当你打开原先没有这两个文件的文件夹时会自动在这个文件夹里生成这两个文件,这时你的电脑就很可能是被新欢乐时光(Vb.Script)感染了。被病毒感染后系统运行速度明显下降,偶尔弹出错误消息框,严重的可能导致死机甚至无法进入系统。 防治方法:不要随便在其他微机上使用u盘及软盘,在必须的情况下应在自己的电脑中先对其进行查毒再使用。如果系统已经感染了此病毒,则可以在瑞星及江民的网站上下载专杀工具vb.kj可以有效的杀除此种病毒。 ②冲击波、震荡波。 病毒现象:此类病毒常见于windows2000较早的版本,病毒运行时会利用RPC缓冲区漏洞攻击该系统,导致电脑运行变慢,不断死机或开机后立即倒数一分钟重启。 防治方法:发现感染此病毒后,应首先断开与局域网的连接,进入安全模式,使用瑞星的专杀工具进行杀毒(Rs_blaster),然后将系统打上rpc漏洞补丁,可以彻底清除此种病毒。 ③QQ类病毒。 病毒现象:QQ类病毒多数为木马型及蠕虫型混合病毒,目的是窃取你计算机上的密码,有些破坏力强大的病毒可能造成很大的威胁,可能导致OFFICE软件、任务管理器、注册表编辑器等程序无法使用,该病毒还会破坏资源管理器,只要用户打开四层以上的目录,病毒就会自动关闭“资源管理器”。该病毒还会干掉含有“杀毒”字样的窗口,因此会造成一些反病毒软件及病毒专杀工具无法使用、一些反病毒公司的主页无法登陆等现象。另外该病毒还会修改用户电脑的系统配置,导致用户重启系统时无法进入“我的电脑”。 防治方法:不要随便接收别人从QQ上传递的文件,尤其是可执行文件(.exe文件),接收的文件要先查毒再打开。如果感染此类病毒可以进入安全模式进行查杀。 ④灰鸽子木马。 灰鸽子是一种功能极为强大的木马病毒,可以完全控制监控,甚至在你的电脑上安装软件盗取密码,而且除了具有语音监听、语音发送,还有远程视频监控功能,只有远程计算机有摄像头,且正常打开没有被占用,那么你可以看到,远程摄像头捕获的图片!还可以把远程摄像头捕获的画面存为Mpeg-1格式.远程语音也可以录制成Wav声音文件。你的电脑没有任何隐私了,可以从你电脑上下载软件,把坏东西复制上去,可以从新安装非病毒类远程控制,这样你就无法摆脱。电脑感染这种木马后没有什么特别的症状,只有通过杀毒软件才能发现自己已经中毒了。 防治方法:1、打开注册表编辑器(点击“开始”→“运行”,输入“Regedit.exe”,确定),打开 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services注册表项。 2、点击菜单“编辑”→ “查找”,“查找目标”输入“game.exe”,点击确定,我们就可以找到灰鸽子的服务项(此例为Game_Server)。 3、删除整个Game_Server项。 灰鸽子的变种很多,所以不仅限于以上的病毒名称。防止感染灰鸽子要注意不要浏览不安全的网站,经常杀毒,并养成良好上网习惯。 常用专杀工具下载链接 1.新欢乐时光专杀工具vbs.kj http://www8.pconline.com.cn/download/swdetail.phtml?id=7910 2.震荡波(Worm.Sasser)”病毒专杀工具. http://it.rising.com.cn/service/technology/RS_sasser.htm 3.“冲击波(Worm.Blaster)”病毒专杀工具 http://it.rising.com.cn/service/technology/RS_blaster.htm 4. “QQ病毒”专杀工具 http://it.rising.com.cn/service/technology/RS_QQMsender.htm 5. “MSN病毒(Worm.msn.funny)”专杀工具 http://it.rising.com.cn/service/technology/RS_MSN.htm 6“Zotob蠕虫(Worm.Zotob)”病毒专杀工具 http://it.rising.com.cn/service/technology/rav_Zotob.htm 有些深点的蠕虫病毒用瑞星、卡巴斯基、超级兔子等杀毒软件都是杀不出来的,有些即使你杀出来了也删除不了,删除了过下子又来了,或电脑重启又出现了。对于这种病毒,首先你必须要知道哪些东东被中了,哪些东东被感染了,比如IE上的主页被改了,IE有时会自动关闭,电脑“进程”里运行了很多不是系统相关的东东(如.dll的库文件和.exe的可执行文件。)这时候必须重启电脑,一直按f8进入安全模式(如电脑设有多个账号的,要用管理员账号登录,也就是Adminstrator),找到可凝的文件一个一个进行手动删除,并在注册表里找到与此病毒相关的文件进行删除(一般电脑中了这种毒,注册表项里就会恶意被修改,并增加很多新的注册项。),电脑硬盘里带毒的文件必须一一彻底删,还有注册表里的一样必须一一彻底清除或更正。深的蠕虫病毒还会感染每个硬盘及一些相关的文件和软件。 注册表进入命令:regedit 查看电脑启动项命令:msconfig 在电脑的“开始”---“运行”,打开运行对话框输入以上命令。 电脑C盘(系统盘)最容易也最常隐藏病毒的文件夹有下: C:\Documents and Settings\qsk\Local Settings\Temp (这个目录是常常隐藏病毒的地方) 上面的“qsk”是我电脑登录的账号名,如果你登录电脑时的账号名是“abc”那么文件夹路径就是: C:\Documents and Settings\abc\Local Settings\Temp C:\Program Files\Common Files 这个文件夹下常常会隐藏产新生成写病毒文件及病毒文件夹。 C:\Program Files\Internet Explorer(这个也常会隐藏病毒文件,主要病毒文件都跟IE有关。) 病毒文件如:C:\Program Files\Internet Explorer\1.exe C:\WINDOWS (这个目录下常常会藏中毒文件,甚至会新建些中毒文件及相关文件夹) 如:新建一个“down”的文件夹,形成C:\WINDOWS\down 并会在该文件夹(down)下隐世藏一个rundll32.exe 可执行文件。(rundll32.exe是系统文件,真正的rundll32.exe是在C:\WINDOWS\system32 目录下。) C:\WINDOWS\system32 (这个目录也是常常隐病毒的地方) 一般IE中了老弹出窗口,如色情类的网站IE窗口,娱乐类的网站IE窗口病毒都会在此目录下隐藏病毒。会新生成一些如.com 、.exe 、 .dll的病毒文件。.com的文件在查看是否是病毒时,请按照此文件的属性的时间进行查看,假如你电脑系统安装的时间是2006年1月1日,而当前时间是2006年12月15日,如果.com文件的属性时间是2006年12月15日或者14日或更前几天的,那么这种大部份都是病毒文件,可进入安全模式手动删除。系统.com的文件如:edit.com,format.com等.com系统文件一般属性时间显示的都是:创建时间:2005年7月20日, 0:00:00 修改时间:2005年7月20日, 0:00:00(系统的.com文件属性显示的时间都是比你安装系统时的时间更早的。而.com病毒文件属性显示的时间都是在电脑安装系统时间后面的。 电脑常见病毒(这是我电脑上经常中的一些病毒): 病毒名:rundll32.exe 症状:此病毒会调用其它模块病毒文件 路径:C:\WINDOWS\down\rundll32.exe 注:C:\WINDOWS\system32rundll32.exe 不可删,这是正确的系统文件。 病毒名:1.exe 症状:打开IE时老弹出窗口 路径:C:\Program Files\Internet Explorer\1.exe 病毒名:logo 1.exe (此病毒是蠕虫病毒) 症状:占用CPU资源,使电脑运行速度慢,并生成很多可执行文件,在电脑上进行感染、网络感染、下载网络木马或其它病毒的复合型病毒,病毒运行后将自身伪装成系统正常文件。 路径: c:\windows\Logo1_.exe 主要生成病毒文件有下: c:\windows\rundl132.exe(注意:注意,此病毒文件名是rundl132.exe与系统system32目录下的系统文件rundll32.exe 相差一个字,病毒文件是132.exe 而系统文件是l32.exe,凡电脑上出现的rundl132.exe 的文件都是病毒。) c:\windows\0Sy.exe c:\windows\vDll.dll c:\windows\1Sy.exe c:\windows\2Sy.exe c:\windows\rundll32.exe (注意:此目下的此rundll32.exe也是病毒文件,正确的是在system32目录下。) c:\windows\3Sy.exe c:\windows\5Sy.exe c:\windows\1.com c:\window*\**erouter.exe c:\window*\**P10RER.com c:\windows\finders.com c:\windows\Shell.sys c:\windows\sms*.**e c:\windows\kill.exe c:\windows\sws.dll c:\windows\sws32.dll 病毒名:service.exe 路径:C:\WINNT\SYSTEM32\Service.exe(注意:该目录下的services.exe不可删,是系统文件) “特洛依木马”病毒   何谓特洛依木马?特洛依木马其实是一种骗子程序,提供某些功能作为诱饵引诱你,确在背地里摧毁你的计算机系统。记得希腊神话中关于特洛依木马的故事吗?典故就是从那儿来的。中了木马时有什么反应?很难说,因为它们发作时的情况多种多样。   病毒诊断   但是如果你的计算机有以下表现时,就很可能染上特洛依木马这种病毒了。   计算器有时死机,有时又重新激活;在没有执行什么操作的时候,却在拼命读写硬盘;系统莫明其妙地对软驱进行搜索;没有运行大的程序,而系统的速度越来越慢,系统资源占用很多;用Ctrl+Alt+Del调出任务表,发现有多个名字相同的程序在运行,而且可能会随时间的增加而增多(可是,有一些程序是不会出现在这个列表里的。懂得编程的朋友应该知道这不难做到,借助PVIEW95就可以看到)。特别是在连入Internet网或是局域网后,如果你的机器有这些现象,就应小心了,当然也有可能是一些其它的病毒在作怪。   病毒防治   一般中了木马程序最简单的解决办法就是用杀毒软件清除,如金山毒霸、瑞星等。如果对系统熟悉也可以手动清除,首先应该按照Win9x下程序自激活的方法中所述的情况检查一下是否有可疑程序(最好的情况是你熟悉你的系统正常时的这些项,用系统自带的regedit程序查看 /修改注册表)。发现可疑程序将其连同该注册表项一起删除即可,重启系统则木马就已经被清除了。不过这里要提醒大家一点,在做删除操作和注册表修改操作前一定要先备份。   “泡沫小子”病毒   泡沫小子是一种通过Outlook广泛传播的蠕虫病毒。它是第一个不需要从电子邮件打开附件就能被激活的蠕虫病毒。   病毒诊断   一般泡沫小子发送一封主题为“BubblleBoy is back!”(泡沫小子来了!)的HTML电子邮件。如果你的IE5.0的安全保护设置级别置为中、低级,则该HTML页隐含着(植入)VBS程序代码,在未提示用户的情况下就会被执行。   病毒防治   这种病毒在你眼前,要采取哪些简便的方法防范它呢?   首先要做到1.不要开启匿名邮件附件,只打开已知附件,以及可信资源建立链接关系。2.关闭自动打开附件功能。3.执行*.EXE、*.HTA、*.VBS和其它可执行附件时要谨慎。4.打开*.DOC、*.XLS、*.PPT文件时要小心。5.不要在本地邮件列表中保存别名为“ALL-Company”的邮件。6.将Internet Explorer4.x或以上版本的安全级别设定成“高级”;终止Active X和Active Scripting。7.Outlook Express:终止打开和/或预览窗口,在对话框下面,不要选中预览窗口。8.Netscape:终止JavaScript在菜单栏中选取编辑/参数,在对话框左边,点击高级,在对话框右边,不要启用邮件和新闻的JavaScript,停止JavaScript浏览最高安全级别。9.其它邮件用户:终止Visual Basic Scripting或JavaScript。   尼姆达(概念)病毒   尼姆达(概念)病毒,是近日来被发现的一种恶性邮件病毒。该病毒利用微软IE浏览器解释Outlook邮件MIME头的漏洞感染和传播,其速度之快,不可等闲视之。   病毒诊断   尼姆达(概念)感染特征和发现方法其实很简单,当感染“概念”病毒之后,它会在执行时将自身复制到临时目录下,再运行在临时目录中的副本。病毒复制到临时目录下的副本(有两个文件,文件名为???????.tmp.exe),在系统下次启动时,病毒会将他们删除(修改 wininit.ini文件)。同时该病毒还会在Windows的system目录中生成load.exe文件,修改system.ini中的shell,把shell=explorer.exe改为explorer.exe load.exe –dontrunold,从而使病毒在下次系统启动时仍能被激活。另外,在system目录下,该病毒还会生成一个副本:riched20.dll。riched20.dll目录在Windows系统中就存在,它就会把它覆盖掉了。   为了通过邮件将自己传播出去,该病毒使用了MAPI函数读取用户的E-mail并从中读取SMTP地址和E-mail地址。病毒还在Windows的临时目录下生成一个eml 格式的临时文件,大小为79225字节,该文件已经用BASE64编码将病毒包含进去。然后,病毒就用取得的地址将带毒邮件发送出去。   病毒防治   由于尼姆达(概念)病毒借助的是IE浏览器的漏洞来传播的,所以堵住漏洞可以说是防护的第一步。以下的方法都可以有效的弥补这个IE的漏洞:   1.添加微软官方的补丁   SP2微软官方已经就Windows 2000系统目前发现的漏洞做了个“十全大补”的补丁,可以弥补绝大部分的Windows 2000漏洞。 SP2共100M左右,可以到以下网址下载: http://www.microsoft.com/windows2000/downloads/critical/q269862/default.asp   2.利用漏洞检测与修复系统   如果大家嫌SP2太大、太麻烦,可以用天网防火墙个人版自带的漏洞检测与修复系统可以检查出Windows中严重的系统漏洞,并自动修复它。目前的天网个人版(测试版)中所带的漏洞检测与修复系统已经可以检查和修复“概念”病毒赖以传染和传播的 IE浏览器漏洞,所以对于防护“概念”病毒而言,是一个不可多得的顺手工具。经过了漏洞检测与修复系统修复之后,“概念”病毒就无法直接在用户的机器上自动运行了。   该防火墙可以到以下网站下载,网址为:http://www.sky.net.cn/在修补完浏览器的漏洞之后,即使是收邮件的时候遇见携带有“概念”病毒的邮件,它也不能顺利的潜入用户的计算机。这时它会出现一个下载提示框。切记不要按“确定”,只要取消它就行了。或者按“确定”之后,你可以得到一个“概念”病毒的本体程序 Readme.exe。另一种防护方法是:不要用Outlook 收邮件,找其它的邮件客户端软件吧。   3.利用杀毒软件清除   如果在成功免疫前,你的计算机中了这个病毒,可以下载最近的防病毒软件进行清除,如金山毒霸、Norton等防病毒软件都已经推出了能够清除“概念”的最新病毒包。但是如果你需要根治这个漏洞,还是得按照以上的方法进行“免疫”。 解决U盘常见病毒的方法! 最近发现u盘病毒的传播方式发现已经不是当初简单了,在U盘根目录下会生成一个autorun.inf的引导文件那么简单了。如果是单纯地利用aoturun.inf传播,那么切记:打开U盘时要通过点击鼠标右键=》资源管理器的方式打开,千万不要双击,否则病毒立即会执行!然后把资源管理器的不隐藏系统文件的勾打开,再双击打开autorun.inf查看病毒路径,然后一并删除即可。但最新的U盘病毒变种已经不采取这种简单的方式了,其方式有三种:第一种是把U盘下所有文件夹隐藏,并把自己复制成与原文件夹名称相同的具有文件夹图标的文件,当你点击时病毒会执行并且该病毒会打开该名称的文件夹。当然按照上述的方式把隐藏属性去掉你可以看到这种景象。第二种是在U盘的所有可执行文件里插入病毒本身,这种情况比较恶劣。一般你必须用杀毒软件或其他分离软件才能把你能用的那部分提取出来。第三种是直接在每一个文件夹下面生成一个与该文件夹同名的exe文件,跟第一种相似,但更具有混淆性。所以大家一般时候不要什么东西都往U盘里放,轻者被插入病毒,重者资料被更改或破坏导致重要信息无法恢复;如果要在U盘里放东西事先一定要在电脑里做备份哦!另外大家买U盘时一定要买那种有写保护的,如果在别人电脑上使用,但只是读取信息,就把写保护打开,如果他电脑有病毒,或许你会发现有弹出提示的信息,就说明他电脑有病毒了。目前已经发现的有固定名称的病毒如下: autorun.inf AdobeR.exe bittorrent.exe copy.exe desktop.exe desktop2.exe folder.exe host.exe msinfmgr.exe msvcr71.dll RavMonE.exe RavMonLog RECYCLER\*.* RECYCLER SHE.exe sxs.exe SYSTEM.VER toy.exe setup.pif 如果大家发现U盘下面有这些文件,那么基本上可以确定是病毒了。 当然目前给大家的简单的解决方法如下:把下面的东东保存为*.bat文件,放在桌面上,当你感觉U盘有病毒时就双击一下,或许能帮你解决一部分负担。 ----------------------------从下面开始----------------------------------- @echo off attrib -r -h -s -a j:\*.*\ del /f/s/q/a j:\autorun.inf del /f/s/q/a j:\AdobeR.exe del /f/s/q/a j:\bittorrent.exe del /f/s/q/a j:\copy.exe del /f/s/q/a j:\desktop.exe del /f/s/q/a j:\desktop2.exe del /f/s/q/a j:\folder.exe del /f/s/q/a j:\host.exe del /f/s/q/a j:\msinfmgr.exe del /f/s/q/a j:\msvcr71.dll del /f/s/q/a j:\RavMonE.exe del /f/s/q/a j:\RavMonLog del /f/s/q/a j:\RECYCLER\*.* del /f/s/q/a j:\RECYCLER del /f/s/q/a j:\SHE.exe del /f/s/q/a j:\sxs.exe del /f/s/q/a j:\SYSTEM.VER del /f/s/q/a j:\toy.exe del /f/s/q/a j:\setup.pif taskkill /F /im explorer.exe explorer.exe j:\ ----------------------------到这里结束----------------------------------- 五.常用DOS命令 1.Format 命令,用于格式化硬盘;例如:Format C: 2.MD 创建文件夹命令 例如: MD空格+文件夹名 3.DIR 查看文件夹命令,比较常用哟。例如:DIR空格+文件夹名 4.CD..回到上一级目录 5.FDISK 硬盘分区命令 例如:FDISK 6.DELETE 删除文件命令 例如:DELETE *.TXT 7.CD进入文件夹命令 例如: CD空格+文件夹名 附录:
这是书的光盘。共分为两部分,这是第二部分。 本书由浅入深、循序渐进地介绍了Windows驱动程序的开发方法与调试技巧。本书共分23章,内容涵盖了Windows操作系统的基本原理、NT驱动程序与WDM驱动程序的构造、驱动程序中的同步异步处理方法、驱动程序中即插即用功能、驱动程序的各种调试技巧等。同时,还针对流行的PCI驱动程序、USB驱动程序、虚拟串口驱动程序、摄像头驱动程序、SDIO驱动程序进行了详细的介绍,本书最大的特色在于每一节的例子都是经过精挑细选的,具有很强的针对性。力求让读者通过亲自动手实验,掌握各类Windows驱动程序的开发技巧,学习尽可能多的Windows底层知识。   本书适用于中、高级系统程序员,同时也可用做高校计算机专业操作系统实验课的补充教材。 原创经典,威盛一线工程师倾力打造。深入驱动核心,剖析操作系统底层运行机制,通过实例引导,快速学习编译、安装、调试的方法。   从Windows最基本的两类驱动程序的编译、安装、调试入手讲解,非常容易上手,用实例详细讲解PCI、USB、虚拟串口、虚拟摄像头、SDIO等驱动程序的开发,归纳了多种调试驱动程序的高级技巧,如用WinDBG和VMWARE软件对驱动进行源码级调试,深入Windows操作系统的底层和内核,透析Windows驱动开发的本质。 本书是作者结合教学和科研实践经验编写而成的,不仅详细介绍了Windows内核原理,而且介绍了编程技巧和应用实例,兼顾了在校研究生和工程技术人员的实际需求,对教学、生产和科研有现实的指导意义,是一本值得推荐的专著。              ——中国工程院院士   院士推荐   目前,电子系统设计广泛采用通用操作系统,达到降低系统的设计难度和缩短研发周期。实现操作系统与硬件快速信息交换是电子系统设计的关键。   通用操作系统硬件驱动程序的开发,编写者不仅需要精通硬件设备、计算机总线,而且需要Windows操作系统知识以及调试技巧。学习和掌握Windows硬件驱动程序的开发是电子系统设计人员必备的能力。   本书是作者结合教学和科研实践经验编写而成的,不仅详细介绍了Windows内核原理,并且介绍了编程技巧和应用实例,兼顾了在校研究生和工程技术人员的实际需求,对教学、生产和科研有现实的指导意义,是一本值得推荐的专著。 第1篇 入门篇 第1章 从两个最简单的驱动谈起 本章向读者呈现两个最简单的Windows驱动程序,一个是NT式的驱动程序,另一个是WDM式的驱动程序。这两个驱动程序没有操作具体的硬件设备,只是在系统里创建了虚拟设备。在随后的章节中,它们会作为基本驱动程序框架,被本书其他章节的驱动程序开发所复用。笔者将带领读者编写代码、编译、安装和调试程序。   1.1 DDK的安装   1.2 第一个驱动程序HelloDDK的代码分析    1.2.1 HelloDDK的头文件    1.2.2 HelloDDK的入口函数    1.2.3 创建设备例程    1.2.4 卸载驱动例程    1.2.5 默认派遣例程   1.3 HelloDDK的编译和安装    1.3.1 用DDK环境编译HelloDDK    1.3.2 用VC集成开发环境编译HelloDDK    1.3.3 HelloDDK的安装   1.4 第二个驱动程序HelloWDM的代码分析    1.4.1 HelloWDM的头文件    1.4.2 HelloWDM的入口函数    1.4.3 HelloWDM的AddDevice例程    1.4.4 HelloWDM处理PNP的回调函数    1.4.5 HelloWDM对PNP的默认处理    1.4.6 HelloWDM对IRP_MN_REMOVE_DEVICE的处理    1.4.7 HelloWDM对其他IRP的回调函数    1.4.8 HelloWDM的卸载例程   1.5 HelloWDM的编译和安装    1.5.1 用DDK编译环境编译HelloWDM    1.5.2 HelloWDM的编译过程    1.5.3 安装HelloWDM   1.6 小结  第2章 Windows操作驱动的基本概念  驱动程序被操作系统加载在内核模式下,它与Windows操作系统内核的其他组件进行密切交互。本章主要介绍Windows操作系统内核的基本概念,同时还介绍应用程序和驱动程序之间的通信方法。   2.1 Windows操作系统概述    2.1.1 Windows家族    2.1.2 Windows特性    2.1.3 用户模式和内核模式    2.1.4 操作系统与应用程序   2.2 操作系统分层    2.2.1 Windows操作系统总体架构    2.2.2 应用程序与Win32子系统    2.2.3 其他环境子系统    2.2.4 Native API    2.2.5 系统服务    2.2.6 执行程序组件    2.2.7 驱动程序    2.2.8 内核    2.2.9 硬件抽象层    2.2.10 Windows与微内核   2.3 从应用程序到驱动程序   2.4 小结  第3章 Windows驱动编译环境配置、安装及调试  本章将带领读者一步步对驱动程序进行编译、安装和简单的调试工作。这些步骤虽然简单,但往往困惑着初次接触驱动程序的开发者。  3.1 用C语言还是用C++语言    3.1.1 调用约定    3.1.2 函数的导出名    3.1.3 运行时函数的调用   3.2 用DDK编译环境编译驱动程序    3.2.1 编译版本    3.2.2 nmake工具    3.2.3 build工具    3.2.4 makefile文件    3.2.5 dirs文件    3.2.6 sources文件    3.2.7 makefile.inc文件    3.2.8 build工具的环境变量    3.2.9 build工具的命令行参数   3.3 用VC编译驱动程序    3.3.1 建立驱动程序工程    3.3.2 修改编译选项    3.3.3 修改链接选项    3.3.4 其他修改    3.3.5 VC编译小结   3.4 查看调试信息    3.4.1 打印调试语句    3.4.2 查看调试语句   3.5 手动加载NT式驱动   3.6 编写程序加载NT式驱动    3.6.1 SCM组件和Windows服务    3.6.2 加载NT驱动的代码    3.6.3 卸载NT驱动的代码    3.6.4 实验   3.7 WDM式驱动的加载    3.7.1 WDM的手动安装    3.7.2 简单的INF文件剖析   3.8 WDM设备安装在注册表中的变化    3.8.1 硬件子键    3.8.2 类子键    3.8.3 服务子键   3.9 小结  第4章 驱动程序的基本结构  本章首先对Windows驱动程序的两个重要数据结构进行介绍,分别是驱动对象和设备对象数据结构。另外还要介绍NT驱动程序和WDM驱动程序的入口函数、卸载例程、各种IRP派遣上函数等。   4.1 Windows驱动程序中重要的数据结构    4.1.1 驱动对象(DRIVER_OBJECT)    4.1.2 设备对象(DEVICE_OBJECT)    4.1.3 设备扩展   4.2 NT式驱动的基本结构    4.2.1 驱动加载过程与驱动入口函数(DriverEntry)    4.2.2 创建设备对象    4.2.3 DriverUnload例程    4.2.4 用WinObj观察驱动对象和设备对象    4.2.5 用DeviceTree观察驱动对象和设备对象   4.3 WDM式驱动的基本结构    4.3.1 物理设备对象与功能设备对象    4.3.2 WDM驱动的入口程序    4.3.3 WDM驱动的AddDevice例程    4.3.4 DriverUnload例程    4.3.5 对IRP_MN_REMOVE_DEVICE IRP的处理    4.3.6 用Device Tree查看WDM设备对象栈   4.4 设备的层次结构    4.4.1 驱动程序的垂直层次结构    4.4.2 驱动程序的水平层次结构    4.4.3 驱动程序的复杂层次结构   4.5 实验    4.5.1 改写HelloDDK查看驱动结构    4.5.2 改写HelloWDM查看驱动结构   4.6 小结  第5章 Windows内存管理   本章围绕着驱动程序中的内存操作进行了介绍。在驱动程序开发中,首先要注意分页内存和非分页内存的使用。同时,还需要区分物理内存地址和虚拟内存地址这两个概念。   5.1 内存管理概念    5.1.1 物理内存概念(Physical Memory Address)    5.1.2 虚拟内存地址概念(Virtual Memory Address)    5.1.3 用户模式地址和内核模式地址    5.1.4 Windows驱动程序和进程的关系    5.1.5 分页与非分页内存    5.1.6 分配内核内存   5.2 在驱动中使用链表    5.2.1 链表结构    5.2.2 链表初始化    5.2.3 从首部插入链表    5.2.4 从尾部插入链表    5.2.5 从链表删除    5.2.6 实验   5.3 Lookaside结构    5.3.1 频繁申请内存的弊端    5.3.2 使用Lookaside    5.3.3 实验   5.4 运行时函数    5.4.1 内存间复制(非重叠)    5.4.2 内存间复制(可重叠)    5.4.3 填充内存    5.4.4 内存比较    5.4.5 关于运行时函数使用的注意事项    5.4.6 实验   5.5 使用C++特性分配内存   5.6 其他    5.6.1 数据类型    5.6.2 返回状态值    5.6.3 检查内存可用性    5.6.4 结构化异常处理(try-except块)    5.6.5 结构化异常处理(try-finally块)    5.6.6 使用宏需要注意的地方    5.6.7 断言   5.7 小结 第6章 Windows内核函数  本章介绍了Windows内核模式下的一些常用内核函数,这些函数在驱动程序的开发中将会经常用到。   6.1 内核模式下的字符串操作    6.1.1 ASCII字符串和宽字符串    6.1.2 ANSI_STRING字符串与UNICODE_STRING字符串    6.1.3 字符初始化与销毁    6.1.4 字符串复制    6.1.5 字符串比较    6.1.6 字符串转化成大写    6.1.7 字符串与整型数字相互转换    6.1.8 ANSI_STRING字符串与UNICODE_STRING字符串相互转换   6.2 内核模式下的文件操作    6.2.1 文件的创建    6.2.2 文件的打开    6.2.3 获取或修改文件属性    6.2.4 文件的写操作    6.2.5 文件的读操作   6.3 内核模式下的注册表操作    6.3.1 创建关闭注册表    6.3.2 打开注册表    6.3.3 添加、修改注册表键值    6.3.4 查询注册表    6.3.5 枚举子项    6.3.6 枚举子键    6.3.7 删除子项    6.3.8 其他   6.4 小结  第7章 派遣函数   本章重点介绍了驱动程序中的处理IRP请求的派遣函数。所有对设备的操作最终将转化为IRP请求,这些IRP请求会被传送到派遣函数处理。   7.1 IRP与派遣函数    7.1.1 IRP    7.1.2 IRP类型    7.1.3 对派遣函数的简单处理    7.1.4 通过设备链接打开设备    7.1.5 编写一个更通用的派遣函数    7.1.6 跟踪IRP的利器IRPTrace   7.2 缓冲区方式读写操作    7.2.1 缓冲区设备    7.2.2 缓冲区设备读写    7.2.3 缓冲区设备模拟文件读写   7.3 直接方式读写操作    7.3.1 直接读取设备    7.3.2 直接读取设备的读写   7.4 其他方式读写操作    7.4.1 其他方式设备    7.4.2 其他方式读写   7.5 IO设备控制操作    7.5.1 DeviceIoControl与驱动交互    7.5.2 缓冲内存模式IOCTL    7.5.3 直接内存模式IOCTL    7.5.4 其他内存模式IOCTL   7.6 小结 第2篇 进阶篇  第8章 驱动程序的同步处理  本章介绍了驱动程序中常用的同步处理办法,并且将内核模式下的同步处理方法和用户模式下的同步处理方法做了比较。另外,本章还介绍了中断请求级、自旋锁等同步处理机制。   8.1 基本概念    8.1.1 问题的引出    8.1.2 同步与异步   8.2 中断请求级    8.2.1 中断请求(IRQ)与可编程中断控制器(PIC)    8.2.2 高级可编程控制器(APIC)    8.2.3 中断请求级(IRQL)    8.2.4 线程调度与线程优先级    8.2.5 IRQL的变化    8.2.6 IRQL与内存分页    8.2.7 控制IRQL提升与降低   8.3 自旋锁    8.3.1 原理    8.3.2 使用方法   8.4 用户模式下的同步对象    8.4.1 用户模式的等待    8.4.2 用户模式开启多线程    8.4.3 用户模式的事件    8.4.4 用户模式的信号灯    8.4.5 用户模式的互斥体    8.4.6 等待线程完成   8.5 内核模式下的同步对象    8.5.1 内核模式下的等待    8.5.2 内核模式下开启多线程    8.5.3 内核模式下的事件对象    8.5.4 驱动程序与应用程序交互事件对象    8.5.5 驱动程序与驱动程序交互事件对象    8.5.6 内核模式下的信号灯    8.5.7 内核模式下的互斥体    8.5.8 快速互斥体   8.6 其他同步方法    8.6.1 使用自旋锁进行同步    8.6.2 使用互锁操作进行同步    8.7 小结  第9章 IRP的同步  本章详细地介绍了IRP的同步处理方法和异步处理方法。另外,本章还介绍了StartIO例程、中断服务例程、DPC服务例程。   9.1 应用程序对设备的同步异步操作    9.1.1 同步操作与异步操作原理    9.1.2 同步操作设备    9.1.3 异步操作设备(方式一)    9.1.4 异步操作设备(方式二)   9.2 IRP的同步完成与异步完成    9.2.1 IRP的同步完成    9.2.2 IRP的异步完成    9.2.3 取消IRP   9.3 StartIO例程    9.3.1 并行执行与串行执行    9.3.2 StartIO例程    9.3.3 示例   9.4 自定义的StartIO    9.4.1 多个串行化队列    9.4.2 示例   9.5 中断服务例程    9.5.1 中断操作的必要性    9.5.2 中断优先级    9.5.3 中断服务例程(ISR)   9.6 DPC例程    9.6.1 延迟过程调用例程(DPC)    9.6.2 DpcForISR   9.7 小结  第10章 定时器  本章总结了在内核模式下的四种等待方法,读者可以利用这些方法灵活地用在自己的驱动程序中。最后本章还介绍了如何对IRP的超时情况进行处理。   10.1 定时器实现方式一    10.1.1 I/O定时器    10.1.2 示例代码   10.2 定时器实现方式二    10.2.1 DPC定时器    10.2.2 示例代码   10.3 等待    10.3.1 第一种方法:使用KeWaitForSingleObject    10.3.2 第二种方法:使用KeDelayExecutionThread    10.3.3 第三种方法:使用KeStallExecutionProcessor    10.3.4 第四种方法:使用定时器   10.4 时间相关的其他内核函数    10.4.1 时间相关函数    10.4.2 示例代码   10.5 IRP的超时处理    10.5.1 原理    10.5.2 示例代码   10.6 小结  第11章 驱动程序调用驱动程序 本章主要介绍了如何在驱动程序中调用其他驱动程序。比较简单的方法是将被调用的驱动程序以文件的方式操作。比较高级的方法是构造各种IRP,并将这些IRP传送到被调用的驱动程序中。   11.1 以文件句柄形式调用其他驱动程序    11.1.1 准备一个标准驱动    11.1.2 获得设备句柄    11.1.3 同步调用    11.1.4 异步调用方法一    11.1.5 异步调用方法二    11.1.6 通过符号链接打开设备   11.2 通过设备指针调用其他驱动程序    11.2.1 用IoGetDeviceObjectPointer获得设备指针    11.2.2 创建IRP传递给驱动的派遣函数    11.2.3 用IoBuildSynchronousFsdRequest创建IRP    11.2.4 用IoBuildAsynchronousFsdRequest创建IRP    11.2.5 用IoAllocateIrp创建IRP   11.3 其他方法获得设备指针    11.3.1 用ObReferenceObjectByName获得设备指针    11.3.2 剖析IoGetDeviceObjectPointer    11.4 小结  第12章 分层驱动程序   本章主要介绍了分层驱动的概念。分层驱动可以将功能复杂的驱动程序分解为多个功能简单的驱动程序。多个分层的驱动程序形成一个设备堆栈,IRP请求首先发送到设备堆栈的顶层,然后依次穿越每层的设备堆栈,最终完成IRP请求。   12.1 分层驱动程序概念    12.1.1 分层驱动程序的概念    12.1.2 设备堆栈与挂载    12.1.3 I/O堆栈    12.1.4 向下转发IRP    12.1.5 挂载设备对象示例    12.1.6 转发IRP示例    12.1.7 分析    12.1.8 遍历设备栈   12.2 完成例程    12.2.1 完成例程概念    12.2.2 传播Pending位    12.2.3 完成例程返回STATUS_SUCCESS    12.2.4 完成例程返回STATUS_MORE_PROCESSING_REQUIRED   12.3 将IRP分解成多个IRP    12.3.1 原理    12.3.2 准备底层驱动    12.3.3 读派遣函数    12.3.4 完成例程    12.3.5 分析   12.4 WDM驱动程序架构    12.4.1 WDM与分层驱动程序    12.4.2 WDM的加载方式    12.4.3 功能设备对象    12.4.4 物理设备对象    12.4.5 物理设备对象与即插即用   12.5 小结  第13章 让设备实现即插即用  本章首先介绍即插即用的概念和驱动程序支持即插即用功能的必要性。另外,本章还介绍如何利用WDM驱动程序开发框架设计支持即插即用功能的驱动程序。   13.1 即插即用概念    13.1.1 历史原因    13.1.2 即插即用的目标    13.1.3 Windows中即插即用相关组件    13.1.4 遗留驱动程序   13.2 即插即用IRP    13.2.1 即插即用IRP的功能代码    13.2.2 处理即插即用IRP的派遣函数   13.3 通过设备接口寻找设备    13.3.1 设备接口    13.3.2 WDM驱动中设置接口    13.3.3 应用程序寻找接口    13.3.4 查看接口设备   13.4 启动和停止设备    13.4.1 为一个实际硬件安装HelloWDM    13.4.2 启动设备    13.4.3 转发并等待    13.4.4 获得设备相关资源    13.4.5 枚举设备资源    13.4.6 停止设备   13.5 即插即用的状态转换    13.5.1 状态转换图    13.5.2 IRP_MN_QUERY_STOP_DEVICE    13.5.3 IRP_MN_QUERY_REMOVE_DEVICE   13.6 其他即插即用IRP    13.6.1 IRP_MN_FILTER_RESOURCE_REQUIREMENTS    13.6.2 IRP_MN_QUERY_CAPABILITIES   13.7 小结  第14章 电源管理  本章主要介绍了如何在WDM驱动程序中进行电源处理。电源处理主要是处理好电源状态和设备状态。   14.1 WDM电源管理模型    14.1.1 概述    14.1.2 热插拔    14.1.3 电源状态    14.1.4 设备状态    14.1.5 状态转换   14.2 处理IRP_MJ_POWER   14.3 处理IRP_MN_QUERY_CAPABILITIES    14.3.1 DEVICE_CAPABILITIES    14.3.2 一个试验   14.4 小结 第3篇 实用篇  第15章 I/O端口操作  本章总结了多种I/O端口操作的方法。这些方法本质上是一样的,都是将端口输入输出的汇编指令运行在内核模式中。   15.1 概述    15.1.1 从DOS说起    15.1.2 汇编实现    15.1.3 DDK实现   15.2 工具软件WinIO    15.2.1 WinIO简介    15.2.2 使用方法   15.3 端口操作实现方法一    15.3.1 驱动端程序    15.3.2 应用程序端程序   15.4 端口操作实现方法二    15.4.1 驱动端程序    15.4.2 应用程序端程序   15.5 端口操作实现方法三    15.5.1 驱动端程序    15.5.2 应用程序端程序   15.6 端口操作实现方法四    15.6.1 原理    15.6.2 驱动端程序    15.6.3 应用程序端程序   15.7 驱动PC喇叭    15.7.1 可编程定时器    15.7.2 PC喇叭    15.7.3 操作代码   15.8 操作并口设备    15.8.1 并口设备简介    15.8.2 并口寄存器    15.8.3 并口设备操作   15.9 小结 第16章 PCI设备驱动 本章主要介绍PCI设备的驱动开发。首先介绍了PCI总线协议。作为驱动程序员,开发PCI驱动程序首先要了解PCI配置空间。根据读取PCI配置空间,可以得到PCI设备的所有资源。另外,本章还总结了四种获取PCI配置空间的方法。   16.1 PCI总线协议    16.1.1 PCI总线简介    16.1.2 PCI配置空间简介   16.2 访问PCI配置空间方法一    16.2.1 两个重要寄存器    16.2.2 示例   16.3 访问PCI配置空间方法二    16.3.1 DDK函数读取配置空间    16.3.2 示例   16.4 访问PCI配置空间方法三    16.4.1 通过即插即用IRP获得PCI配置空间    16.4.2 示例   16.5 访问PCI配置空间方法四    16.5.1 创建IRP_MN_READ_CONFIG    16.5.2 示例   16.6 PCI设备驱动开发示例    16.6.1 开发步骤    16.6.2 中断操作    16.6.3 操作设备物理内存    16.6.4 示例   16.7 小结 第17章 USB设备驱动  本章首先介绍了USB总线协议的基本框架,其中包括USB总线的拓扑结构,USB通信的流程,还有USB的四种传输模式。另外,本章介绍了如何编写USB总线设备的驱动程序。   17.1 USB总线协议    17.1.1 USB设备简介    17.1.2 USB连接拓扑结构    17.1.3 USB通信的流程    17.1.4 USB四种传输模式   17.2 Windows下的USB驱动    17.2.1 观察USB设备的工具    17.2.2 USB设备请求    17.2.3 设备描述符    17.2.4 配置描述符    17.2.5 接口描述符    17.2.6 端点描述符   17.3 USB驱动开发实例    17.3.1 功能驱动与物理总线驱动    17.3.2 构造USB请求包    17.3.3 发送USB请求包    17.3.4 USB设备初始化    17.3.5 USB设备的插拔    17.3.6 USB设备的读写   17.4 小结  第18章 SDIO设备驱动 本章首先介绍了SDIO协议,讲述了SD内存卡和SDIO卡的兼容问题。然后介绍了SDIO协议中的发送命令、回应命令、传送数据等相关协议。随后,本章又介绍了Windows中,DDK提供的对SDIO卡设备的支持。然后介绍了如何利用总线驱动,使SDIO设备初始化,接收中断,发送和接收数据等操作。   18.1 SDIO协议    18.1.1 SD内存卡概念    18.1.2 SDIO卡概念    18.1.3 SDIO总线    18.1.4 SDIO令牌    18.1.5 SDIO令牌格式    18.1.6 SDIO的寄存器    18.1.7 CMD52命令    18.1.8 CMD53命令   18.2 SDIO卡驱动开发框架    18.2.1 SDIO Host Controller驱动    18.2.2 SDIO卡的初始化    18.2.3 中断回调函数    18.2.4 获得和设置属性    18.2.5 CMD52    18.2.6 CMD53   18.3 SDIO开发实例   18.4 小结  第19章 虚拟串口设备驱动  本章介绍了串口开发的框架模型,在串口的AddDevice例程中需要暴露出一个串口的符号连接,另外在相应的注册表中需要进行设置。在串口与应用程序的通信中,主要是一组DDK定义的IO控制码,这些IO控制码负责由应用程序向驱动发出请求。   19.1 串口简介   19.2 DDK串口开发框架    19.2.1 串口驱动的入口函数    19.2.2 应用程序与串口驱动的通信    19.2.3 写的实现    19.2.4 读的实现   19.3 小结  第20章 摄像头设备驱动程序  本章主要介绍了微软提供的摄像头驱动框架。在该框架中,微软提供了类驱动和小驱动的概念。对于驱动程序员的任务就是编写小驱动程序。   20.1 WDM摄像头驱动框架    20.1.1 类驱动与小驱动    20.1.2 摄像头的类驱动与小驱动    20.1.3 编写小驱动程序    20.1.4 小驱动的流控制   20.2 虚拟摄像头开发实例    20.2.1 编译和安装    20.2.2 虚拟摄像头入口函数    20.2.3 对STREAM_REQUEST_BLOCK的处理函数    20.2.4 打开视频流    20.2.5 对视频流的读取   20.3 小结 第4篇 提高篇  第21章 再论IRP  本章将相关IRP的操作做了进一步的总结。首先是转发IRP,归纳了几种不同的方式。其次总结了创建IRP的几种不同方法。创建IRP总的来说分为创建同步IRP和创建异步IRP。对于创建同步IRP,操作比较简单,I/O管理器会负责回收IRP的相关内存,但是使用不够灵活。对于创建异步IRP,操作比较复杂,程序员需要自己负责对IRP及相关内存回收,但使用十分灵活。   21.1 转发IRP    21.1.1 直接转发    21.1.2 转发并且等待    21.1.3 转发并且设置完成例程    21.1.4 暂时挂起当前IRP    21.1.5 不转发IRP   21.2 创建IRP    21.2.1 IoBuildDeviceIoControlRequest    21.2.2 创建有超时的IOCTL IRP    21.2.3 用IoBuildSynchronousFsdRequest创建IRP    21.2.4 关于IoBuildAsynchronousFsdRequest    21.2.5 关于IoAllocateIrp   21.3 小结 第22章 过滤驱动程序  本章主要介绍WDM和NT式过滤驱动程序开发。过滤驱动程序开发十分灵活,可以修改已有驱动程序的功能,也可以对数据进行过滤加密。另外,利用过滤驱动程序还能编写出很多具有相当功能强大的程序来。  22.1 文件过滤驱动程序   22.1.1 过滤驱动程序概念   22.1.2 过滤驱动程序的入口函数   22.1.3 U盘过滤驱动程序   22.1.4 过滤驱动程序加载方法一   22.1.5 过滤驱动程序加载方法二   22.1.6 过滤驱动程序的AddDevice例程   22.1.7 磁盘命令过滤  22.2 NT式过滤驱动程序   22.2.1 NT式过滤驱动程序   22.2.2 NT过滤驱动的入口函数   22.2.3 挂载过滤驱动   22.2.4 过滤键盘读操作  22.3 小结  第23章 高级调试技巧  本章将介绍一些Windows开发驱动的高级调试技巧。有一些高级驱动程序调试技巧,可以帮助程序员找出驱动程序中的Bug。另外,利用一些第三方工具软件,也可以帮助程序员找到驱动程序中的漏洞,从而提高开发效率。  23.1 一般性调试技巧   23.1.1 打印调试信息   23.1.2 存储dump信息   23.1.3 使用WinDbg调试工具  23.2 高级内核调试技巧   23.2.1 安装VMWare   23.2.2 在虚拟机上加载驱动程序   23.2.3 VMWare和WinDbg联合调试驱动程序  23.3 用IRPTrace调试驱动程序  23.4 小结
文将对 Linux™ 程序员可以使用的内存管理技术进行概述,虽然关注的重点是 C 语言,但同样也适用于其他语言。文中将为您提供如何管理内存的细节,然后将进一步展示如何手工管理内存,如何使用引用计数或者内存池来半手工地管理内存,以及如何使用垃圾收集自动管理内存。 为什么必须管理内存 内存管理是计算机编程最为基本的领域之一。在很多脚本语言中,您不必担心内存是如何管理的,这并不能使得内存管理的重要性有一点点降低。对实际编程来说,理解您的内存管理器的能力与局限性至关重要。在大部分系统语言中,比如 C 和 C++,您必须进行内存管理。本文将介绍手工的、半手工的以及自动的内存管理实践的基本概念。 追溯到在 Apple II 上进行汇编语言编程的时代,那时内存管理还不是个大问题。您实际上在运行整个系统。系统有多少内存,您就有多少内存。您甚至不必费心思去弄明白它有多少内存,因为每一台机器的内存数量都相同。所以,如果内存需要非常固定,那么您只需要选择一个内存范围并使用它即可。 不过,即使是在这样一个简单的计算机中,您也会有问题,尤其是当您不知道程序的每个部分将需要多少内存时。如果您的空间有限,而内存需求是变化的,那么您需要一些方法来满足这些需求: 确定您是否有足够的内存来处理数据。 从可用的内存中获取一部分内存。 向可用内存池(pool)中返回部分内存,以使其可以由程序的其他部分或者其他程序使用。 实现这些需求的程序库称为 分配程序(allocators),因为它们负责分配和回收内存。程序的动态性越强,内存管理就越重要,您的内存分配程序的选择也就更重要。让我们来了解可用于内存管理的不同方法,它们的好处与不足,以及它们最适用的情形。 回页首 C 风格的内存分配程序 C 编程语言提供了两个函数来满足我们的三个需求: malloc:该函数分配给定的字节数,并返回一个指向它们的指针。如果没有足够的可用内存,那么它返回一个空指针。 free:该函数获得指向由 malloc 分配的内存片段的指针,并将其释放,以便以后的程序或操作系统使用(实际上,一些 malloc 实现只能将内存归还给程序,而无法将内存归还给操作系统)。 物理内存和虚拟内存 要理解内存在程序中是如何分配的,首先需要理解如何将内存操作系统分配给程序。计算机上的每一个进程都认为自己可以访问所有的物理内存。显然,由于同时在运行多个程序,所以每个进程不可能拥有全部内存。实际上,这些进程使用的是 虚拟内存。 只是作为一个例子,让我们假定您的程序正在访问地址为 629 的内存。不过,虚拟内存系统不需要将其存储在位置为 629 的 RAM 中。实际上,它甚至可以不在 RAM 中 —— 如果物理 RAM 已经满了,它甚至可能已经被转移到硬盘上!由于这类地址不必反映内存所在的物理位置,所以它们被称为虚拟内存操作系统维持着一个虚拟地址到物理地址的转换的表,以便计算机硬件可以正确地响应地址请求。并且,如果地址在硬盘上而不是在 RAM 中,那么操作系统将暂时停止您的进程,将其他内存转存到硬盘中,从硬盘上加载被请求的内存,然后再重新启动您的进程。这样,每个进程都获得了自己可以使用的地址空间,可以访问比您物理上安装的内存更多的内存。 在 32-位 x86 系统上,每一个进程可以访问 4 GB 内存。现在,大部分人的系统上并没有 4 GB 内存,即使您将 swap 也算上, 每个进程所使用的内存也肯定少于 4 GB。因此,当加载一个进程时,它会得到一个取决于某个称为 系统中断点(system break)的特定地址的初始内存分配。该地址之后是未被映射的内存 —— 用于在 RAM 或者硬盘中没有分配相应物理位置的内存。因此,如果一个进程运行超出了它初始分配的内存,那么它必须请求操作系统“映射进来(map in)”更多的内存。(映射是一个表示一一对应关系的数学术语 —— 当内存的虚拟地址有一个对应的物理地址来存储内存内容时,该内存将被映射。) 基于 UNIX 的系统有两个可映射到附加内存中的基本系统调用: brk: brk() 是一个非常简单的系统调用。还记得系统中断点吗?该位置是进程映射的内存边界。 brk() 只是简单地将这个位置向前或者向后移动,就可以向进程添加内存或者从进程取走内存。 mmap: mmap(),或者说是“内存映像”,类似于 brk(),但是更为灵活。首先,它可以映射任何位置的内存,而不单单只局限于进程。其次,它不仅可以将虚拟地址映射到物理的 RAM 或者 swap,它还可以将它们映射到文件和文件位置,这样,读写内存将对文件中的数据进行读写。不过,在这里,我们只关心 mmap 向进程添加被映射的内存的能力。 munmap() 所做的事情与 mmap() 相反。 如您所见, brk() 或者 mmap() 都可以用来向我们的进程添加额外的虚拟内存。在我们的例子中将使用 brk(),因为它更简单,更通用。 实现一个简单的分配程序 如果您曾经编写过很多 C 程序,那么您可能曾多次使用过 malloc() 和 free()。不过,您可能没有用一些时间去思考它们在您的操作系统中是如何实现的。本节将向您展示 malloc 和 free 的一个最简化实现的代码,来帮助说明管理内存时都涉及到了哪些事情。 要试着运行这些示例,需要先 复制本代码清单,并将其粘贴到一个名为 malloc.c 的文件中。接下来,我将一次一个部分地对该清单进行解释。 在大部分操作系统中,内存分配由以下两个简单的函数来处理: void *malloc(long numbytes):该函数负责分配 numbytes 大小的内存,并返回指向第一个字节的指针。 void free(void *firstbyte):如果给定一个由先前的 malloc 返回的指针,那么该函数会将分配的空间归还给进程的“空闲空间”。 malloc_init 将是初始化内存分配程序的函数。它要完成以下三件事:将分配程序标识为已经初始化,找到系统中最后一个有效内存地址,然后建立起指向我们管理的内存的指针。这三个变量都是全局变量: 清单 1. 我们的简单分配程序的全局变量 int has_initialized = 0; void *managed_memory_start; void *last_valid_address; 如前所述,被映射的内存的边界(最后一个有效地址)常被称为系统中断点或者 当前中断点。在很多 UNIX® 系统中,为了指出当前系统中断点,必须使用 sbrk(0) 函数。 sbrk 根据参数中给出的字节数移动当前系统中断点,然后返回新的系统中断点。使用参数 0 只是返回当前中断点。这里是我们的 malloc 初始化代码,它将找到当前中断点并初始化我们的变量: 清单 2. 分配程序初始化函数 /* Include the sbrk function */ #include void malloc_init() { /* grab the last valid address from the OS */ last_valid_address = sbrk(0); /* we don't have any memory to manage yet, so *just set the beginning to be last_valid_address */ managed_memory_start = last_valid_address; /* Okay, we're initialized and ready to go */ has_initialized = 1; } 现在,为了完全地管理内存,我们需要能够追踪要分配和回收哪些内存。在对内存块进行了 free 调用之后,我们需要做的是诸如将它们标记为未被使用的等事情,并且,在调用 malloc 时,我们要能够定位未被使用的内存块。因此, malloc 返回的每块内存的起始处首先要有这个结构: 清单 3. 内存控制块结构定义 struct mem_control_block { int is_available; int size; }; 现在,您可能会认为当程序调用 malloc 时这会引发问题 —— 它们如何知道这个结构?答案是它们不必知道;在返回指针之前,我们会将其移动到这个结构之后,把它隐藏起来。这使得返回的指针指向没有用于任何其他用途的内存。那样,从调用程序的角度来看,它们所得到的全部是空闲的、开放的内存。然后,当通过 free() 将该指针传递回来时,我们只需要倒退几个内存字节就可以再次找到这个结构。 在讨论分配内存之前,我们将先讨论释放,因为它更简单。为了释放内存,我们必须要做的惟一一件事情就是,获得我们给出的指针,回退 sizeof(struct mem_control_block) 个字节,并将其标记为可用的。这里是对应的代码: 清单 4. 解除分配函数 void free(void *firstbyte) { struct mem_control_block *mcb; /* Backup from the given pointer to find the * mem_control_block */ mcb = firstbyte - sizeof(struct mem_control_block); /* Mark the block as being available */ mcb->is_available = 1; /* That's It! We're done. */ return; } 如您所见,在这个分配程序中,内存的释放使用了一个非常简单的机制,在固定时间内完成内存释放。分配内存稍微困难一些。以下是该算法的略述: 清单 5. 主分配程序的伪代码 1. If our allocator has not been initialized, initialize it. 2. Add sizeof(struct mem_control_block) to the size requested. 3. start at managed_memory_start. 4. Are we at last_valid address? 5. If we are: A. We didn't find any existing space that was large enough -- ask the operating system for more and return that. 6. Otherwise: A. Is the current space available (check is_available from the mem_control_block)? B. If it is: i) Is it large enough (check "size" from the mem_control_block)? ii) If so: a. Mark it as unavailable b. Move past mem_control_block and return the pointer iii) Otherwise: a. Move forward "size" bytes b. Go back go step 4 C. Otherwise: i) Move forward "size" bytes ii) Go back to step 4 我们主要使用连接的指针遍历内存来寻找开放的内存块。这里是代码: 清单 6. 主分配程序 void *malloc(long numbytes) { /* Holds where we are looking in memory */ void *current_location; /* This is the same as current_location, but cast to a * memory_control_block */ struct mem_control_block *current_location_mcb; /* This is the memory location we will return. It will * be set to 0 until we find something suitable */ void *memory_location; /* Initialize if we haven't already done so */ if(! has_initialized) { malloc_init(); } /* The memory we search for has to include the memory * control block, but the users of malloc don't need * to know this, so we'll just add it in for them. */ numbytes = numbytes + sizeof(struct mem_control_block); /* Set memory_location to 0 until we find a suitable * location */ memory_location = 0; /* Begin searching at the start of managed memory */ current_location = managed_memory_start; /* Keep going until we have searched all allocated space */ while(current_location != last_valid_address) { /* current_location and current_location_mcb point * to the same address. However, current_location_mcb * is of the correct type, so we can use it as a struct. * current_location is a void pointer so we can use it * to calculate addresses. */ current_location_mcb = (struct mem_control_block *)current_location; if(current_location_mcb->is_available) { if(current_location_mcb->size >= numbytes) { /* Woohoo! We've found an open, * appropriately-size location. */ /* It is no longer available */ current_location_mcb->is_available = 0; /* We own it */ memory_location = current_location; /* Leave the loop */ break; } } /* If we made it here, it's because the Current memory * block not suitable; move to the next one */ current_location = current_location + current_location_mcb->size; } /* If we still don't have a valid location, we'll * have to ask the operating system for more memory */ if(! memory_location) { /* Move the program break numbytes further */ sbrk(numbytes); /* The new memory will be where the last valid * address left off */ memory_location = last_valid_address; /* We'll move the last valid address forward * numbytes */ last_valid_address = last_valid_address + numbytes; /* We need to initialize the mem_control_block */ current_location_mcb = memory_location; current_location_mcb->is_available = 0; current_location_mcb->size = numbytes; } /* Now, no matter what (well, except for error conditions), * memory_location has the address of the memory, including * the mem_control_block */ /* Move the pointer past the mem_control_block */ memory_location = memory_location + sizeof(struct mem_control_block); /* Return the pointer */ return memory_location; } 这就是我们的内存管理器。现在,我们只需要构建它,并在程序中使用它即可。 运行下面的命令来构建 malloc 兼容的分配程序(实际上,我们忽略了 realloc() 等一些函数,不过, malloc() 和 free() 才是最主要的函数): 清单 7. 编译分配程序 gcc -shared -fpic malloc.c -o malloc.so 该程序将生成一个名为 malloc.so 的文件,它是一个包含有我们的代码的共享库。 在 UNIX 系统中,现在您可以用您的分配程序来取代系统的 malloc(),做法如下: 清单 8. 替换您的标准的 malloc LD_PRELOAD=/path/to/malloc.so export LD_PRELOAD LD_PRELOAD 环境变量使动态链接器在加载任何可执行程序之前,先加载给定的共享库的符号。它还为特定库中的符号赋予优先权。因此,从现在起,该会话中的任何应用程序都将使用我们的 malloc(),而不是只有系统的应用程序能够使用。有一些应用程序不使用 malloc(),不过它们是例外。其他使用 realloc() 等其他内存管理函数的应用程序,或者错误地假定 malloc() 内部行为的那些应用程序,很可能会崩溃。ash shell 似乎可以使用我们的新 malloc() 很好地工作。 如果您想确保 malloc() 正在被使用,那么您应该通过向函数的入口点添加 write() 调用来进行测试。 我们的内存管理器在很多方面都还存在欠缺,但它可以有效地展示内存管理需要做什么事情。它的某些缺点包括: 由于它对系统中断点(一个全局变量)进行操作,所以它不能与其他分配程序或者 mmap 一起使用。 当分配内存时,在最坏的情形下,它将不得不遍历 全部进程内存;其中可能包括位于硬盘上的很多内存,这意味着操作系统将不得不花时间去向硬盘移入数据和从硬盘中移出数据。 没有很好的内存不足处理方案( malloc 只假定内存分配是成功的)。 它没有实现很多其他的内存函数,比如 realloc()。 由于 sbrk() 可能会交回比我们请求的更多的内存,所以在堆(heap)的末端会遗漏一些内存。 虽然 is_available 标记只包含一位信息,但它要使用完整的 4-字节 的字。 分配程序不是线程安全的。 分配程序不能将空闲空间拼合为更大的内存块。 分配程序的过于简单的匹配算法会导致产生很多潜在的内存碎片。 我确信还有很多其他问题。这就是为什么它只是一个例子! 其他 malloc 实现 malloc() 的实现有很多,这些实现各有优点与缺点。在设计一个分配程序时,要面临许多需要折衷的选择,其中包括: 分配的速度。 回收的速度。 有线程的环境的行为。 内存将要被用光时的行为。 局部缓存。 簿记(Bookkeeping)内存开销。 虚拟内存环境中的行为。 小的或者大的对象。 实时保证。 每一个实现都有其自身的优缺点集合。在我们的简单的分配程序中,分配非常慢,而回收非常快。另外,由于它在使用虚拟内存系统方面较差,所以它最适于处理大的对象。 还有其他许多分配程序可以使用。其中包括: Doug Lea Malloc:Doug Lea Malloc 实际上是完整的一组分配程序,其中包括 Doug Lea 的原始分配程序,GNU libc 分配程序和 ptmalloc。 Doug Lea 的分配程序有着与我们的版本非常类似的基本结构,但是它加入了索引,这使得搜索速度更快,并且可以将多个没有被使用的块组合为一个大的块。它还支持缓存,以便更快地再次使用最近释放的内存。 ptmalloc 是 Doug Lea Malloc 的一个扩展版本,支持多线程。在本文后面的 参考资料部分中,有一篇描述 Doug Lea 的 Malloc 实现的文章。 BSD Malloc:BSD Malloc 是随 4.2 BSD 发行的实现,包含在 FreeBSD 之中,这个分配程序可以从预先确实大小的对象构成的池中分配对象。它有一些用于对象大小的 size 类,这些对象的大小为 2 的若干次幂减去某一常数。所以,如果您请求给定大小的一个对象,它就简单地分配一个与之匹配的 size 类。这样就提供了一个快速的实现,但是可能会浪费内存。在 参考资料部分中,有一篇描述该实现的文章。 Hoard:编写 Hoard 的目标是使内存分配在多线程环境中进行得非常快。因此,它的构造以锁的使用为中心,从而使所有进程不必等待分配内存。它可以显著地加快那些进行很多分配和回收的多线程进程的速度。在 参考资料部分中,有一篇描述该实现的文章。 众多可用的分配程序中最有名的就是上述这些分配程序。如果您的程序有特别的分配需求,那么您可能更愿意编写一个定制的能匹配您的程序内存分配方式的分配程序。不过,如果不熟悉分配程序的设计,那么定制分配程序通常会带来比它们解决的问题更多的问题。要获得关于该主题的适当的介绍,请参阅 Donald Knuth 撰写的 The Art of Computer Programming Volume 1: Fundamental Algorithms 中的第 2.5 节“Dynamic Storage Allocation”(请参阅 参考资料中的链接)。它有点过时,因为它没有考虑虚拟内存环境,不过大部分算法都是基于前面给出的函数。 在 C++ 中,通过重载 operator new(),您可以以每个类或者每个模板为单位实现自己的分配程序。在 Andrei Alexandrescu 撰写的 Modern C++ Design 的第 4 章(“Small Object Allocation”)中,描述了一个小对象分配程序(请参阅 参考资料中的链接)。 基于 malloc() 的内存管理的缺点 不只是我们的内存管理器有缺点,基于 malloc() 的内存管理器仍然也有很多缺点,不管您使用的是哪个分配程序。对于那些需要保持长期存储的程序使用 malloc() 来管理内存可能会非常令人失望。如果您有大量的不固定的内存引用,经常难以知道它们何时被释放。生存期局限于当前函数的内存非常容易管理,但是对于生存期超出该范围的内存来说,管理内存则困难得多。而且,关于内存管理是由进行调用的程序还是由被调用的函数来负责这一问题,很多 API 都不是很明确。 因为管理内存的问题,很多程序倾向于使用它们自己的内存管理规则。C++ 的异常处理使得这项任务更成问题。有时好像致力于管理内存分配和清理的代码比实际完成计算任务的代码还要多!因此,我们将研究内存管理的其他选择。 回页首 半自动内存管理策略 引用计数 引用计数是一种 半自动(semi-automated)的内存管理技术,这表示它需要一些编程支持,但是它不需要您确切知道某一对象何时不再被使用。引用计数机制为您完成内存管理任务。 在引用计数中,所有共享的数据结构都有一个域来包含当前活动“引用”结构的次数。当向一个程序传递一个指向某个数据结构指针时,该程序会将引用计数增加 1。实质上,您是在告诉数据结构,它正在被存储在多少个位置上。然后,当您的进程完成对它的使用后,该程序就会将引用计数减少 1。结束这个动作之后,它还会检查计数是否已经减到零。如果是,那么它将释放内存。 这样做的好处是,您不必追踪程序中某个给定的数据结构可能会遵循的每一条路径。每次对其局部的引用,都将导致计数的适当增加或减少。这样可以防止在使用数据结构时释放该结构。不过,当您使用某个采用引用计数的数据结构时,您必须记得运行引用计数函数。另外,内置函数和第三方的库不会知道或者可以使用您的引用计数机制。引用计数也难以处理发生循环引用的数据结构。 要实现引用计数,您只需要两个函数 —— 一个增加引用计数,一个减少引用计数并当计数减少到零时释放内存。 一个示例引用计数函数集可能看起来如下所示: 清单 9. 基本的引用计数函数 /* Structure Definitions*/ /* Base structure that holds a refcount */ struct refcountedstruct { int refcount; } /* All refcounted structures must mirror struct * refcountedstruct for their first variables */ /* Refcount maintenance functions */ /* Increase reference count */ void REF(void *data) { struct refcountedstruct *rstruct; rstruct = (struct refcountedstruct *) data; rstruct->refcount++; } /* Decrease reference count */ void UNREF(void *data) { struct refcountedstruct *rstruct; rstruct = (struct refcountedstruct *) data; rstruct->refcount--; /* Free the structure if there are no more users */ if(rstruct->refcount == 0) { free(rstruct); } } REF 和 UNREF 可能会更复杂,这取决于您想要做的事情。例如,您可能想要为多线程程序增加锁,那么您可能想扩展 refcountedstruct,使它同样包含一个指向某个在释放内存之前要调用的函数的指针(类似于面向对象语言中的析构函数 —— 如果您的结构中包含这些指针,那么这是 必需的)。 当使用 REF 和 UNREF 时,您需要遵守这些指针的分配规则: UNREF 分配前左端指针(left-hand-side pointer)指向的值。 REF 分配后左端指针(left-hand-side pointer)指向的值。 在传递使用引用计数的结构的函数中,函数需要遵循以下这些规则: 在函数的起始处 REF 每一个指针。 在函数的结束处 UNREF 第一个指针。 以下是一个使用引用计数的生动的代码示例: 清单 10. 使用引用计数的示例 /* EXAMPLES OF USAGE */ /* Data type to be refcounted */ struct mydata { int refcount; /* same as refcountedstruct */ int datafield1; /* Fields specific to this struct */ int datafield2; /* other declarations would go here as appropriate */ }; /* Use the functions in code */ void dosomething(struct mydata *data) { REF(data); /* Process data */ /* when we are through */ UNREF(data); } struct mydata *globalvar1; /* Note that in this one, we don't decrease the * refcount since we are maintaining the reference * past the end of the function call through the * global variable */ void storesomething(struct mydata *data) { REF(data); /* passed as a parameter */ globalvar1 = data; REF(data); /* ref because of Assignment */ UNREF(data); /* Function finished */ } 由于引用计数是如此简单,大部分程序员都自已去实现它,而不是使用库。不过,它们依赖于 malloc 和 free 等低层的分配程序来实际地分配和释放它们的内存。 在 Perl 等高级语言中,进行内存管理时使用引用计数非常广泛。在这些语言中,引用计数由语言自动地处理,所以您根本不必担心它,除非要编写扩展模块。由于所有内容都必须进行引用计数,所以这会对速度产生一些影响,但它极大地提高了编程的安全性和方便性。以下是引用计数的益处: 实现简单。 易于使用。 由于引用是数据结构的一部分,所以它有一个好的缓存位置。 不过,它也有其不足之处: 要求您永远不要忘记调用引用计数函数。 无法释放作为循环数据结构的一部分的结构。 减缓几乎每一个指针的分配。 尽管所使用的对象采用了引用计数,但是当使用异常处理(比如 try 或 setjmp()/ longjmp())时,您必须采取其他方法。 需要额外的内存来处理引用。 引用计数占用了结构中的第一个位置,在大部分机器中最快可以访问到的就是这个位置。 在多线程环境中更慢也更难以使用。 C++ 可以通过使用 智能指针(smart pointers)来容忍程序员所犯的一些错误,智能指针可以为您处理引用计数等指针处理细节。不过,如果不得不使用任何先前的不能处理智能指针的代码(比如对 C 库的联接),实际上,使用它们的后果通实比不使用它们更为困难和复杂。因此,它通常只是有益于纯 C++ 项目。如果您想使用智能指针,那么您实在应该去阅读 Alexandrescu 撰写的 Modern C++ Design 一书中的“Smart Pointers”那一章。 内存内存池是另一种半自动内存管理方法内存池帮助某些程序进行自动内存管理,这些程序会经历一些特定的阶段,而且每个阶段中都有分配给进程的特定阶段的内存。例如,很多网络服务器进程都会分配很多针对每个连接的内存 —— 内存的最大生存期限为当前连接的存在期。Apache 使用了池式内存(pooled memory),将其连接拆分为各个阶段,每个阶段都有自己的内存池。在结束每个阶段时,会一次释放所有内存。 在池式内存管理中,每次内存分配都会指定内存池,从中分配内存。每个内存池都有不同的生存期限。在 Apache 中,有一个持续时间为服务器存在期的内存池,还有一个持续时间为连接的存在期的内存池,以及一个持续时间为请求的存在期的池,另外还有其他一些内存池。因此,如果我的一系列函数不会生成比连接持续时间更长的数据,那么我就可以完全从连接池中分配内存,并知道在连接结束时,这些内存会被自动释放。另外,有一些实现允许注册 清除函数(cleanup functions),在清除内存池之前,恰好可以调用它,来完成在内存被清理前需要完成的其他所有任务(类似于面向对象中的析构函数)。 要在自己的程序中使用池,您既可以使用 GNU libc 的 obstack 实现,也可以使用 Apache 的 Apache Portable Runtime。GNU obstack 的好处在于,基于 GNU 的 Linux 发行版本中默认会包括它们。Apache Portable Runtime 的好处在于它有很多其他工具,可以处理编写多平台服务器软件所有方面的事情。要深入了解 GNU obstack 和 Apache 的池式内存实现,请参阅 参考资料部分中指向这些实现的文档的链接。 下面的假想代码列表展示了如何使用 obstack: 清单 11. obstack 的示例代码 #include #include /* Example code listing for using obstacks */ /* Used for obstack macros (xmalloc is a malloc function that exits if memory is exhausted */ #define obstack_chunk_alloc xmalloc #define obstack_chunk_free free /* Pools */ /* Only permanent allocations should go in this pool */ struct obstack *global_pool; /* This pool is for per-connection data */ struct obstack *connection_pool; /* This pool is for per-request data */ struct obstack *request_pool; void allocation_failed() { exit(1); } int main() { /* Initialize Pools */ global_pool = (struct obstack *) xmalloc (sizeof (struct obstack)); obstack_init(global_pool); connection_pool = (struct obstack *) xmalloc (sizeof (struct obstack)); obstack_init(connection_pool); request_pool = (struct obstack *) xmalloc (sizeof (struct obstack)); obstack_init(request_pool); /* Set the error handling function */ obstack_alloc_failed_handler = &allocation_failed; /* Server main loop */ while(1) { wait_for_connection(); /* We are in a connection */ while(more_requests_available()) { /* Handle request */ handle_request(); /* Free all of the memory allocated * in the request pool */ obstack_free(request_pool, NULL); } /* We're finished with the connection, time * to free that pool */ obstack_free(connection_pool, NULL); } } int handle_request() { /* Be sure that all object allocations are allocated * from the request pool */ int bytes_i_need = 400; void *data1 = obstack_alloc(request_pool, bytes_i_need); /* Do stuff to process the request */ /* return */ return 0; } 基本上,在操作的每一个主要阶段结束之后,这个阶段的 obstack 会被释放。不过,要注意的是,如果一个过程需要分配持续时间比当前阶段更长的内存,那么它也可以使用更长期限的 obstack,比如连接或者全局内存。传递给 obstack_free() 的 NULL 指出它应该释放 obstack 的全部内容。可以用其他的值,但是它们通常不怎么实用。 使用池式内存分配的益处如下所示: 应用程序可以简单地管理内存内存分配和回收更快,因为每次都是在一个池中完成的。分配可以在 O(1) 时间内完成,释放内存池所需时间也差不多(实际上是 O(n) 时间,不过在大部分情况下会除以一个大的因数,使其变成 O(1))。 可以预先分配错误处理池(Error-handling pools),以便程序在常规内存被耗尽时仍可以恢复。 有非常易于使用的标准实现。 池式内存的缺点是: 内存池只适用于操作可以分阶段的程序。 内存池通常不能与第三方库很好地合作。 如果程序的结构发生变化,则不得不修改内存池,这可能会导致内存管理系统的重新设计。 您必须记住需要从哪个池进行分配。另外,如果在这里出错,就很难捕获该内存池。 回页首 垃圾收集 垃圾收集(Garbage collection)是全自动地检测并移除不再使用的数据对象。垃圾收集器通常会在当可用内存减少到少于一个具体的阈值时运行。通常,它们以程序所知的可用的一组“基本”数据 —— 栈数据、全局变量、寄存器 —— 作为出发点。然后它们尝试去追踪通过这些数据连接到每一块数据。收集器找到的都是有用的数据;它没有找到的就是垃圾,可以被销毁并重新使用这些无用的数据。为了有效地管理内存,很多类型的垃圾收集器都需要知道数据结构内部指针的规划,所以,为了正确运行垃圾收集器,它们必须是语言本身的一部分。 收集器的类型 复制(copying): 这些收集器将内存存储器分为两部分,只允许数据驻留在其中一部分上。它们定时地从“基本”的元素开始将数据从一部分复制到另一部分。内存新近被占用的部分现在成为活动的,另一部分上的所有内容都认为是垃圾。另外,当进行这项复制操作时,所有指针都必须被更新为指向每个内存条目的新位置。因此,为使用这种垃圾收集方法,垃圾收集器必须与编程语言集成在一起。 标记并清理(Mark and sweep):每一块数据都被加上一个标签。不定期的,所有标签都被设置为 0,收集器从“基本”的元素开始遍历数据。当它遇到内存时,就将标签标记为 1。最后没有被标记为 1 的所有内容都认为是垃圾,以后分配内存时会重新使用它们。 增量的(Incremental):增量垃圾收集器不需要遍历全部数据对象。因为在收集期间的突然等待,也因为与访问所有当前数据相关的缓存问题(所有内容都不得不被页入(page-in)),遍历所有内存会引发问题。增量收集器避免了这些问题。 保守的(Conservative):保守的垃圾收集器在管理内存时不需要知道与数据结构相关的任何信息。它们只查看所有数据类型,并假定它们 可以全部都是指针。所以,如果一个字节序列可以是一个指向一块被分配的内存的指针,那么收集器就将其标记为正在被引用。有时没有被引用的内存会被收集,这样会引发问题,例如,如果一个整数域中包含一个值,该值是已分配内存的地址。不过,这种情况极少发生,而且它只会浪费少量内存。保守的收集器的优势是,它们可以与任何编程语言相集成。 Hans Boehm 的保守垃圾收集器是可用的最流行的垃圾收集器之一,因为它是免费的,而且既是保守的又是增量的,可以使用 --enable-redirect-malloc 选项来构建它,并且可以将它用作系统分配程序的简易替代者(drop-in replacement)(用 malloc/ free 代替它自己的 API)。实际上,如果这样做,您就可以使用与我们在示例分配程序中所使用的相同的 LD_PRELOAD 技巧,在系统上的几乎任何程序中启用垃圾收集。如果您怀疑某个程序正在泄漏内存,那么您可以使用这个垃圾收集器来控制进程。在早期,当 Mozilla 严重地泄漏内存时,很多人在其中使用了这项技术。这种垃圾收集器既可以在 Windows® 下运行,也可以在 UNIX 下运行。 垃圾收集的一些优点: 您永远不必担心内存的双重释放或者对象的生命周期。 使用某些收集器,您可以使用与常规分配相同的 API。 其缺点包括: 使用大部分收集器时,您都无法干涉何时释放内存。 在多数情况下,垃圾收集比其他形式的内存管理更慢。 垃圾收集错误引发的缺陷难于调试。 如果您忘记将不再使用的指针设置为 null,那么仍然会有内存泄漏。 回页首 结束语 一切都需要折衷:性能、易用、易于实现、支持线程的能力等,这里只列出了其中的一些。为了满足项目的要求,有很多内存管理模式可以供您使用。每种模式都有大量的实现,各有其优缺点。对很多项目来说,使用编程环境默认的技术就足够了,不过,当您的项目有特殊的需要时,了解可用的选择将会有帮助。下表对比了本文中涉及的内存管理策略。 表 1. 内存分配策略的对比 策略 分配速度 回收速度 局部缓存 易用性 通用性 实时可用 SMP 线程友好 定制分配程序 取决于实现 取决于实现 取决于实现 很难 无 取决于实现 取决于实现 简单分配程序 内存使用少时较快 很快 差 容易 高 否 否 GNU malloc 中 快 中 容易 高 否 中 Hoard 中 中 中 容易 高 否 是 引用计数 N/A N/A 非常好 中 中 是(取决于 malloc 实现) 取决于实现 池 中 非常快 极好 中 中 是(取决于 malloc 实现) 取决于实现 垃圾收集 中(进行收集时慢) 中 差 中 中 否 几乎不 增量垃圾收集 中 中 中 中 中 否 几乎不 增量保守垃圾收集 中 中 中 容易 高 否 几乎不 参考资料 您可以参阅本文在 developerWorks 全球站点上的 英文原文。 Web 上的文档 GNU C Library 手册的 obstacks 部分 提供了 obstacks 编程接口。 Apache Portable Runtime 文档 描述了它们的池式分配程序的接口。 基本的分配程序 Doug Lea 的 Malloc 是最流行的内存分配程序之一。 BSD Malloc 用于大部分基于 BSD 的系统中。 ptmalloc 起源于 Doug Lea 的 malloc,用于 GLIBC 之中。 Hoard 是一个为多线程应用程序优化的 malloc 实现。 GNU Memory-Mapped Malloc(GDB 的组成部分) 是一个基于 mmap() 的 malloc 实现。 池式分配程序 GNU Obstacks(GNU Libc 的组成部分)是安装最多的池式分配程序,因为在每一个基于 glibc 的系统中都有它。 Apache 的池式分配程序(Apache Portable Runtime 中) 是应用最为广泛的池式分配程序。 Squid 有其自己的池式分配程序。 NetBSD 也有其自己的池式分配程序。 talloc 是一个池式分配程序,是 Samba 的组成部分。 智能指针和定制分配程序 Loki C++ Library 有很多为 C++ 实现的通用模式,包括智能指针和一个定制的小对象分配程序。 垃圾收集器 Hahns Boehm Conservative Garbage Collector 是最流行的开源垃圾收集器,它可以用于常规的 C/C++ 程序。 关于现代操作系统中的虚拟内存的文章 Marshall Kirk McKusick 和 Michael J. Karels 合著的 A New Virtual Memory Implementation for Berkeley UNIX 讨论了 BSD 的 VM 系统。 Mel Gorman's Linux VM Documentation 讨论了 Linux VM 系统。 关于 malloc 的文章 Poul-Henning Kamp 撰写的 Malloc in Modern Virtual Memory Environments 讨论的是 malloc 以及它如何与 BSD 虚拟内存交互。 Berger、McKinley、Blumofe 和 Wilson 合著的 Hoard -- a Scalable Memory Allocator for Multithreaded Environments 讨论了 Hoard 分配程序的实现。 Marshall Kirk McKusick 和 Michael J. Karels 合著的 Design of a General Purpose Memory Allocator for the 4.3BSD UNIX Kernel 讨论了内核级的分配程序。 Doug Lea 撰写的 A Memory Allocator 给出了一个关于设计和实现分配程序的概述,其中包括设计选择与折衷。 Emery D. Berger 撰写的 Memory Management for High-Performance Applications 讨论的是定制内存管理以及它如何影响高性能应用程序。 关于定制分配程序的文章 Doug Lea 撰写的 Some Storage Management Techniques for Container Classes 描述的是为 C++ 类编写定制分配程序。 Berger、Zorn 和 McKinley 合著的 Composing High-Performance Memory Allocators 讨论了如何编写定制分配程序来加快具体工作的速度。 Berger、Zorn 和 McKinley 合著的 Reconsidering Custom Memory Allocation 再次提及了定制分配的主题,看是否真正值得为其费心。 关于垃圾收集的文章 Paul R. Wilson 撰写的 Uniprocessor Garbage Collection Techniques 给出了垃圾收集的一个基本概述。 Benjamin Zorn 撰写的 The Measured Cost of Garbage Collection 给出了关于垃圾收集和性能的硬数据(hard data)。 Hans-Juergen Boehm 撰写的 Memory Allocation Myths and Half-Truths 给出了关于垃圾收集的神话(myths)。 Hans-Juergen Boehm 撰写的 Space Efficient Conservative Garbage Collection 是一篇描述他的用于 C/C++ 的垃圾收集器的文章。 Web 上的通用参考资料 内存管理参考 中有很多关于内存管理参考资料和技术文章的链接。 关于内存管理和内存层级的 OOPS Group Papers 是非常好的一组关于此主题的技术文章。 C++ 中的内存管理讨论的是为 C++ 编写定制的分配程序。 Programming Alternatives: Memory Management 讨论了程序员进行内存管理时的一些选择。 垃圾收集 FAQ 讨论了关于垃圾收集您需要了解的所有内容。 Richard Jones 的 Garbage Collection Bibliography 有指向任何您想要的关于垃圾收集的文章的链接。 书籍 Michael Daconta 撰写的 C++ Pointers and Dynamic Memory Management 介绍了关于内存管理的很多技术。 Frantisek Franek 撰写的 Memory as a Programming Concept in C and C++ 讨论了有效使用内存的技术与工具,并给出了在计算机编程中应当引起注意的内存相关错误的角色。 Richard Jones 和 Rafael Lins 合著的 Garbage Collection: Algorithms for Automatic Dynamic Memory Management 描述了当前使用的最常见的垃圾收集算法。 在 Donald Knuth 撰写的 The Art of Computer Programming 第 1 卷 Fundamental Algorithms 的第 2.5 节“Dynamic Storage Allocation”中,描述了实现基本的分配程序的一些技术。 在 Donald Knuth 撰写的 The Art of Computer Programming 第 1 卷 Fundamental Algorithms 的第 2.3.5 节“Lists and Garbage Collection”中,讨论了用于列表的垃圾收集算法。 Andrei Alexandrescu 撰写的 Modern C++ Design 第 4 章“Small Object Allocation”描述了一个比 C++ 标准分配程序效率高得多的一个高速小对象分配程序。 Andrei Alexandrescu 撰写的 Modern C++ Design 第 7 章“Smart Pointers”描述了在 C++ 中智能指针的实现。 Jonathan 撰写的 Programming from the Ground Up 第 8 章“Intermediate Memory Topics”中有本文使用的简单分配程序的一个汇编语言版本。 来自 developerWorks 自我管理数据缓冲区内存 (developerWorks,2004 年 1 月)略述了一个用于管理内存的自管理的抽象数据缓存器的伪 C (pseudo-C)实现。 A framework for the user defined malloc replacement feature (developerWorks,2002 年 2 月)展示了如何利用 AIX 中的一个工具,使用自己设计的内存子系统取代原有的内存子系统。 掌握 Linux 调试技术 (developerWorks,2002 年 8 月)描述了可以使用调试方法的 4 种不同情形:段错误、内存溢出、内存泄漏和挂起。 在 处理 Java 程序中的内存漏洞 (developerWorks,2001 年 2 月)中,了解导致 Java 内存泄漏的原因,以及何时需要考虑它们。 在 developerWorks Linux 专区中,可以找到更多为 Linux 开发人员准备的参考资料。 从 developerWorks 的 Speed-start your Linux app 专区中,可以下载运行于 Linux 之上的 IBM 中间件产品的免费测试版本,其中包括 WebSphere® Studio Application Developer、WebSphere Application Server、DB2® Universal Database、Tivoli® Access Manager 和 Tivoli Directory Server,查找 how-to 文章和技术支持。 通过参与 developerWorks blogs 加入到 developerWorks 社区。 可以在 Developer Bookstore Linux 专栏中定购 打折出售的 Linux 书籍。 关于作者 Jonathan Bartlett 是 Programming from the Ground Up 一书的作者,这本书介绍的是 Linux 汇编语言编程。Jonathan Bartlett 是 New Media Worx 的总开发师,负责为客户开发 Web、视频、kiosk 和桌面应用程序。您可以通过 [email protected] 与 Jonathan 联系。
《系统虚拟化:原理与实现pdf》是一本介绍系统虚拟化的相关理论和实践的书籍。在计算机技术快速发展的今天,系统虚拟化这一概念已经成为了一种重要的技术手段,可以有效提高计算机的利用率、降低管理成本,为云计算、大数据等新兴领域的发展提供支持。 该书主要介绍了系统虚拟化的概念、原理和实现方法。首先,它介绍了虚拟化技术的发展历程和背景,说明了为什么需要虚拟化技术以及虚拟化技术的优点。接着,它详细介绍了系统虚拟化两种实现方法:全虚拟化和半虚拟化,分析了它们的优缺点,同时也讲解了其他虚拟化技术的特点。 在具体实现方面,该书详细介绍了系统虚拟化的基础技术,包括虚拟化的CPU、内存、磁盘、网络等硬件资源的管理方法虚拟机的创建、启动和销毁等操作。此外,还介绍了虚拟机监控器(VMM)的工作原理和虚拟机的调度策略。 除了基础技术,该书还介绍了针对特定应用场景的系统虚拟化技术,如云计算、容器化等。通过对各种实际应用场景的案例分析,读者可以更加深入地理解系统虚拟化的实际应用。 总之,《系统虚拟化:原理与实现pdf》是一本非常实用和具有参考价值的书籍,介绍了系统虚拟化技术的基础知识和实现方法,对于从事虚拟化相关研究和应用的从业人员以及对虚拟化技术感兴趣的读者都具有很高的参考价值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值