Windows内部概述-1-

进程:

进程是一个程序的运行实例的控制和管理对象。一般的程序员所说进程运行,这样的说法是不对的,因为进程不能运行程序,进程只能管理该程序运行。线程才是真正的执行代码的东西。

一个进程应该具备以下的内容:

1: 对于一种可执行程序而言,进程包含了执行代码的所需要的初始代码和数据。

2: 每个进程有一个虚拟地址空间,用来给代码分配内存

3: 一个主令牌对象用来存储进程的默认安全内容,该对象被进程中的线程执行代码来使用。

4: 一个指向执行对象的专用句柄表,如事件、信号量和文件。

5: 一个进程可以有一个或多个线程来执行代码。一个普通的用户态的进程被一个线程创建(执行经典的main/WinMain 函数来创建)。一个没有线程的普通用户进程是没有用的。

一个进程由一个唯一的进程ID来标识,是唯一的。一旦一个进程被摧毁,它的进程ID可以被新的进程所获取。需要注意的是:可执行文件并不能唯一标识进程,只有进程ID可以。例如:我可以通过QQ.EXE这个可执行文件开多个QQ来使用。

每个进程有自己的内存空间,有自己的线程,自己的进程ID,是完全独立的。

总结:可执行程序和进程、线程的关系可以好比如面向对象的关系,可执行程序是类,进程是对象,线程的对象里面可以具体执行的函数。可执行程序运行必须实例化成进程,但是进程也不能运行,进程是靠进程内部的线程来具体运行代码的,每个进程和进程是完全独立开的,有唯一的进程ID可以标识。可以和面向对象来对比记忆。

虚拟内存

每个进程有自己虚拟的、线性的、单独的内存空间。这段内存空间从0开始(或者接近0,因为可执行模块和ntdll.dll是第一个被映射的,接着是更多的子系统DLL)。一旦一个可执行程序的第一个线程开始了,内存就开始被分配了,用来加载更多的DLL。

这段内存是私有的,意味着其它进程是无法访问这段内存的。这段内存的范围从0开始(虽然从技术角度来说前面的64KB地址空间是不能被任何办法来分配和使用的,这是系统自动添加的),然后一直到最大值,最大值由操作系统的位数来取决,取决办法如下(注:这里说的是用户的进程地址空间):

1 当32位的进程在32位操作系统上时:进程地址空间默认为2G。

2 当32位进程在32位操作系统上且使用了地址增长空间设置(也就是在PE头中设置了LARGEADDRESSAWARE这个标志位),该进程的地址空间可以达到3G(具体的看设置)

3 当64位进程在64位操作系统上时,地址空间可以有8TB,Windows8.1及以后有128TB.

4 当32位进程在64位OS(操作系统)上时,如果链接器设置了LARGEADDRESSAWARE地址空间有4G,否则还是2GB.(通常都是4G)

每个进程有自己的地址空间,但是这只是相对的,并不是绝对的。例如:当你要访问0x40000这个地址的数据的时候,你必须选择是在那个进程里面访问,不然这样是不行。

每个进程的内存被成为虚拟内存,这意味着,它和真实存在物理内存存在间接的联系:进程的缓冲区内容可能被直接映射到了物理内存里面,也有可能被临时存储在了文件里面(硬盘)。”虚拟“这个术语只有在针对执行来说才有效果,不需要知道虚拟内存是否在物理内存中真实存在因为如果虚拟内存中的内容有映射到物理内存里面,那么CPU可以直接通过物理内存来访问,如果没有CPU就会引起页错误异常,这会引发内存管理器的页错误处理程序将从适当的文件中获取数据再将其复制到内存里面,然后再在映射缓冲区的页面表条目中进行所需的更改,然后再给CPU发指令让它再次获取。

内存管理的单位被称为页。一个页面的大小是由CPU来决定的(当然也可以配置),在任何情况下,内存管理器必须遵守页的大小,通常在所有窗口都支持的页面大小为4KB(这也被称为小页面大小)。

除了默认支持的4KB页面大小(小页面大小),Windows还支持大页面,这个页面的大小由2MB(x86/64/ARM64)和4MB(ARM)。大页面基于使用了Page Directory Entry(PDE)来映射而不是采用页面映射表。有了大页面就会让与内存直接处理的内容更快。

页状态

状态  
空闲(free) 内存页不可用
保留(Reserve) 内存页被预定了,但还未做物理内存做映射,还是不可以
提交(Commit) 内存被分配,并且与物理内存进行了映射,进程可以使用了

系统内存

进行的地址空间只有下半部是供进行使用的,当某个线程正在执行时,从地址0到上限地址都是可以直接看到的。但是操作系统也必须在进程空占有空间:操作系统在一个进程中占有高地址的地址空间(通常是直接占有一半的高地址地址空间)。如下所示:

1 对于32位OS系统占用2GB以上的虚拟内存空间地址从0x80000000到0xFFFFFFFF,和前面的进程空间向对应互相采用2G的虚拟空间

2 在32位OS且开启了额外的进程地址空间相对应进程的1GB高地址空间

3 在64位操作系统上,Windows8之前的占有8TB的寻地址内存空间,在WIndows8之后的占用128TB以上的虚拟内存空间

系统的空间和进程并没有关系,毕竟对于进程来说都是在相同的系统上,相同的内核驱动上,且相同地系统为每个进程提供的服务驱动程序,因此系统中的任何地址空间都是相对的,并不是绝对的。因为从每个进程来看都是一样的,也可以理解为每个进程都有共享的相同系统进程地址。从用户进程切换到系统进程是违规的。

系统空间是内核本身的、硬件抽象层(HAL)和内核驱动程序的位置一旦加载后就不会变了。因此内核驱动程序是自动受保护的,不会受用户模式来访问的。所以内核驱动如果有问题就是至关重要的了。

虚拟内存总结:

对于不同位的进程和不同位的操作系统有不同的解释:但是相同的是每个进程只有操作系统位数一部分的地址空间,还有一部分的地址空间是属于系统进程的,系统进程的内容是唯一的大家都是一样的,但是不能用普通进程来访问操作系统进程。例如一个32位的进程只有2GB的进程空间,操作系统还有2GB的进程空间,每个进程的内存空间是独立的,如果要用的时候会通过映射或者从文件读取来使用,内存的单位是页,最通常的页的大小是4KB。

Windows内核开发-Windows内部概述-1-的更多相关文章

  1. Windows内核开发-Windows内部概述-2-

    Windows内部概述-2- 线程: 执行代码的实体是线程.一个线程的包含在进程里面的,线程使用进程提供的资源来运行代码. 一个线程拥有以下的内容: 1:明确的运行模式,用户态或者内核态. 2:执行的 ...

  2. Windows内核开发-2-开始内核开发-2-内核开发入门

    Windows内核开发-2-开始内核开发-2- 第一个驱动程序: 直接采用vs2019中的Empty WDM Driver 模块创建: 初始的项目文件夹中有一个Driver Files里面会有一个.i ...

  3. Windows内核开发-3-内核编程基础

    Windows内核开发-3-内核编程基础 这里会深入讲解kernel内核的API.结构体.和一些定义.考察代码在内核驱动中运行的机制.最后把所有知识合在一起写一个有用的驱动. 本章学习要点: 1:通用 ...

  4. Windows内核开发-6-内核机制 Kernel Mechanisms

    Windows内核开发-6-内核机制 Kernel Mechanisms 一部分Windows的内核机制对于驱动开发很有帮助,还有一部分对于内核理解和调试也很有帮助. Interrupt Reques ...

  5. Windows内核开发-9-32位和64位的区别

    Windows内核开发-9-32位和64位的区别 32位的应用程序可以完美再64位的电脑上运行,而32位的内核驱动无法再64位的电脑上运行,或者64位的驱动无法在32位的应用程序上运行.这是为什么呢. ...

  6. windows内核开发环境的简易搭建

    一.windows内核开发需要的软件 1.WDK 2.WinDbg 3.virtualKD 4.DebugView 5.Visual C++ 6.0 6.VMware Workstation 二.wi ...

  7. Windows内核开发-4-内核编程基础

    Windows内核开发-4-内核编程基础 这里会构建一个简单但是完整的驱动程序和一个客户端,部署内核执行一些平时user下无法执行的操作. 将通过以下内容进行讲解: 1 介绍 2 驱动初始化 3 Cr ...

  8. Windows内核开发-5-(2)-内核模式调试

    Windows内核开发-5-(2)-内核模式调试 普通用户模式的调试,采取的是给进程添加一个线程来挂起断点,作为一个调试器的线程在进程中使用.照这样来类推,对操作系统调试相当于添加一个进程来限制操作系 ...

  9. Windows内核开发-10-监听对象

    Windows内核开发-10-监听对象 Windows内核除了可以监听进程,线程.dll还可以监听特定的对象和注册表.这里先讲一下监听对象. 监听对象 内核提供了一种可以监听对特定的对象类型的句柄进行 ...

随机推荐

  1. 手写一个最简单的IOC容器,从而了解spring的核心原理

    从事开发工作多年,spring源码没有特意去看过.但是相关技术原理倒是背了不少,毕竟面试的那关还是得过啊! 正所谓面试造火箭,工作拧螺丝.下面实现一个最简单的ioc容器,供大家参考. 1.最终结果 2 ...

  2. python 键盘中断子线程及graceful exiting方案

    最近需要实现一个服务程序的graceful exiting,保证在退出前关闭所有已创建的子线程 python借助KeyboardInterrupted异常响应键盘中断,因此首先尝试在子线程中try-c ...

  3. OO随笔之追求完美的第三单元——初试JML

    前言 这一章的JML比较简单,那么大家的关注点自然地移到了性能优化上.于是大家一股脑地去利用各种数据结构去做时间上的优化(当然很多人最后还是倒在了正确性上),故称追求完美的一单元.当然这也是得益于JM ...

  4. .NET平台系列8 .NET Core 各版本新功能

    系列目录     [已更新最新开发文章,点击查看详细] .NET Core 自2016年6月27日发布第一个正式版本以来,它主打的跨平台和高性能特效吸引了许多开发者,包括Java.PHP等语言的开发者 ...

  5. Spring Cloud 升级之路 - 2020.0.x - 5. 理解 NamedContextFactory

    spring-cloud-commons 中参考了 spring-cloud-netflix 的设计,引入了 NamedContextFactory 机制,一般用于对于不同微服务的客户端模块使用不同的 ...

  6. 1小时快速搭建基于Azure Custom Vision和树莓派的鸟类分类和识别应用

    1. 引言 最近在微软Learn平台学习Azure认知服务相关的内容,看到了一个有关"使用自定义视觉对濒危鸟类进行分类"的专题,该专题的主要内容就是使用 Azure Custom ...

  7. X Sever —— Xorg

    X Sever -- Xorg  发表于 2020-03-20 分类于 系统服务 , Xorg 阅读次数:39 阅读次数:48 本文字数: 7k 阅读时长 ≈ 6 分钟 Xorg:基于X11协议的服务 ...

  8. ActiveMQ FileServer漏洞(详细)

    半个月前,巡检时发现服务器出现不明进程,对其进行了处理,由于当时没有做详细记录,在这里把大致过程描述一下. 症状: ps命令发现出现几个不明进程, 1.于/tmp下运行的,名称随机的进程.占用CPU高 ...

  9. Linux如何查看文件的创建、修改时间?

    Linux如何查看文件的创建.修改时间? 利用stat指令查看文件信息 三种时间的介绍 ATime --文件的最近访问时间 只要读取时间,ATime就会更新 MTime --文件的内容最近修改的时间 ...

  10. 9.10 nohup:用户退出系统进程继续工作

    nohup命令 可以将程序以忽略挂起信号的方式运行起来,被运行程序的输出信息将不会显示到终端.        无论是否将nohup命令的输出重定向到终端,输出都将写入到当前目录的nohup.out文件 ...