内核开发知识第二讲,编写Kerner 程序中注意的问题.
一丶函数多线程的安全问题
什么是函数多线程安全. 简单来说就是 ,一个函数在调用过程中.还没有返回的时候.再次被其他线程调用了.但是函数执行的结果是可靠的.就可以了说这个函数是安全的.
比如我们在用户层编写程序.用到多线程的时候.都会注意同步问题. 因为这样我们的线程才是安全的.
在内核中其实是一样的.但是我们要注意.
1.可能运行在多线程中的函数.必须保证线程安全. 而如果运行在单线程中.那么不需要线程安全性.因为没有操作线程.
2.如果 A 调用B B 调用C. 而C的所有调用者(A B)都运行在同一单线程中. 那么C也要保证运行在单线程中.
3.如果 A -> B -> C 而 BC可能在多线程环境中. 那么函数A也可能运行在多线程环境中. 意思就是说 有可能多线程调用A了.但是A会调用BC.所以BC在多线程环境中.
4.A - > B -> C 如果B运行在多线程环境中.那么都有多线程序列化诚单线程的强制措施.在函数B是运行在单线程中.
上面所说,就是内核程序中的"多线程序列化诚单线程的强制措施" 互斥体.自旋锁.
5.只是用函数内部资源.不使用全局变量.静态变量.或者其他全局性资源的函数.是多线程安全的.
6.如果使用全局,静态.等变量.那么我们需要使用同步函数来进行同步.
二丶中断级别.
总的来说这篇博客讲的理论偏多.都是注意的问题.在内核中. Kerner API 都有中断级别一说.
在用户层,代码都是同级别运行.所以不需要关心.但是在Kerner内核中.就需要关心一下.否则可能一个问题.导致一直出问题.
现在中断级别有两个级别
1.Passive 级别.
2.Dispatch级别.
关于两种级别.在内核博客中的刚开始两课有简单的说过本质.其实我们只需要知道两种界别注意一下就行.
简单的函数运行在Dispatch级别中. 所以我们在调用任何一个kernerAPI之前,都要查询一下中断级别.
Dispatch级别比 Passive级别高.
怎么判断?
调用路径: A - B - C 那么 C的调用路径就是A 跟 B.因为是一条线.
调用源: A - B - C 那么一次一次的递推.一直到A. 那么 C的调用源则是A
判断:
1.调用路径上没有特殊情况.(特殊情况指 导致中断级的提高或者降低) 那么则这个函数执行时的中断级和它的调用源级别相同,
2.如果调用路径上面有获取自旋锁.则中断级别随之提高.如果有释放自旋锁.那么中断级别降低.
内核中中断级别.
|
调用源 |
级别 |
|
DriverEntry DriverUnload |
Passive级别 |
|
各种分发函数 |
Passive 级别 |
|
完成函数 |
Dispatch 级别 |
|
各种NDIS回调函数 |
Dispatch 级别. |
如果我们查询下Kerner API 那么也会发现有说明这个API是在什么级别使用.
例如:

可以看到中断级别是 <= DISPATHCH级别的.
疑问?
如果当前代码运行在DISPATCH中,但是又必须调用PASSIVE级别的API怎么办.可以利用内核API降低当前中断级别吗?
答:
不可以.Windows代码都是在规范的级别上运行的.任意的降低或者提高都会影响代码的执行.所以我们要调用这种API的时候.可以创建一个专门的线程来执行PASSIVE级别的代码.
解决方法很多.不止这些. 可以网络上搜下资料. 博主也是自学.所以暂时还没接触到.
三丶内核中宏代码代表的意思
在内核中我们看API的时候.可以看到好多宏.而这些宏都是空宏, 是用来说明的.
比如:
IN
OUT
一个参数前边加上IN 代表这个参数是传递进去的.
一个参数前边带有OUT 代表这个参数是传出参数.
__in_bcount(StatusBuffsize) IN PVOID statusBuffer;
这里的参数代表了. statusBuffer的大小依赖于StatusBuffsize这个参数来制定的.
四丶指定函数位置的预编译指令.
本来这个小主题可以放到第三个问题中说.单独说说明有点重要.
#pragma alloc_text()
上面这个宏表示我们的函数的可执行代码编译出来之后再.sys文件中的位置.
什么意思那..sys文件本质上其实就是PE文件.我们知道PE文件都有段.也有节.不同的节加载到内存中会有不同的处理情况.
而我们需要关心的有三种.
1.INIT节. 这个节的特点就是初始化完毕之后就会释放.不在占用内存空间.
2.PAGE节 这个节的特点是可以进行分页交换的内存空间.什么意思.其实就是我们的内存不够了.可以临时放到磁盘上.
3.PAGELK节. 这个节是默认的.如果我们不指定代码放在那里.那么就会放在这个节中. 特点是不能进行内存交换.也就是说不可以和磁盘交互.
而我们可以指定我们的代码放到哪个节当中.
比如我们的入口函数.这个函数只会调用一次.那么我们可以放到INIT节中.这样初始化完之后就没有了.不占用内核内存.因为内核内存是共享的.用完就没了.
例如:
#pragma alloc_text(INIT,DriverEntry)
注意的问题:
如果我们将函数放入PAGE节中.那么代表我们这个函数运行中可以放到磁盘上.如果这样就会产生缺页中断. 所以如果放到PAGE节中的函数.那么不能调用DISPATCH级别的函数.
内核开发知识第二讲,编写Kerner 程序中注意的问题.的更多相关文章
- 32位汇编第二讲,编写窗口程序,加载资源,响应消息,以及调用C库函数
32位汇编第二讲,编写窗口程序,加载资源,响应消息,以及调用C库函数 (如果想看所有代码,请下载课堂资料,里面有所有代码,这里会讲解怎么生成一个窗口程序) 一丶32位汇编编写Windows窗口程序 首 ...
- 内核开发知识第一讲.内核中的数据类型.重要数据结构.常用内核API函数.
一丶内核中的数据类型 在内核中.程序的编写不能简单的用基本数据类型了. 因为操作系统不同.很有可能造成数据类型的长度不一.而产生重大问题.所以在内核中. 数据类型都一定重定义了. 数据类型 重定义数据 ...
- Delphi for iOS开发指南(8):在iOS应用程序中使用Tab组件来显示分页
Delphi for iOS开发指南(8):在iOS应用程序中使用Tab组件来显示分页 在FireMonkey iOS应用程序中的Tab Tab由FMX.TabControl.TTabControl定 ...
- Delphi for iOS开发指南(7):在iOS应用程序中使用WebBrowser组件
Delphi for iOS开发指南(7):在iOS应用程序中使用WebBrowser组件 在FireMonkey iOS应用程序中使用WebBrowser 在iOS平台上,FireMonkey使用T ...
- Delphi for iOS开发指南(6):在iOS应用程序中使用ComboBox组件来从列表中选择某一项
http://blog.csdn.net/delphiteacher/article/details/8924110 Delphi for iOS开发指南(6):在iOS应用程序中使用ComboBox ...
- Native Application 开发详解(直接在程序中调用 ntdll.dll 中的 Native API,有内存小、速度快、安全、API丰富等8大优点)
文章目录: 1. 引子: 2. Native Application Demo 展示: 3. Native Application 简介: 4. Native Ap ...
- Linux2.6.32内核笔记(5)在应用程序中移植使用内核链表【转】
转自:http://blog.csdn.net/Deep_l_zh/article/details/48392935 版权声明:本文为博主原创文章,未经博主允许不得转载. 摘要:将内核链表移植到应用程 ...
- 关于编写Windows程序中启动兼容性问题
之前用qt4编写Windows程序的时候遇到了一个软件在系统的兼容性问题:用户在win10系统下使用这个程序的时候,如果没有用低于win10版本的兼容模式运行的时候,存在运行某部分功能的时候无法使用的 ...
- 微信小程序开发系列五:微信小程序中如何响应用户输入事件
微信小程序开发系列教程 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 微信小程序开发系列二:微信小程序的视图设计 微信小程序开发系列三:微信小程序的调试方法 微信小程序开发系列四:微信小程序 ...
随机推荐
- linearlayout 中ImageView 居中等问题
linearlayout 下的子控件使用android:layout_gravity=”center” 控件居左,没有达到居中的效果, 父窗体只能指定一种控件摆放方向 横向还是竖向 下面我弄了三个 ...
- 二 分析easyswoole源码(启动服务)
前文连接,阅读的时候最好参照EasySwoole2.1.2的源码 $inst->run();//启动服务 这里实际调用的是Core的start方法ServerManager::getInstan ...
- Web常见安全漏洞-SQL注入
SQL注入攻击(SQL Injection),简称注入攻击,是Web开发中最常见的一种安全漏洞. 可以用它来从数据库获取敏感信息,或者利用数据库的特性执行添加用户,导出文件等一系列恶意操作, 甚至有可 ...
- js 原型链与继承
var A = function(){ this.name="xiaoming"; } A.prototype.age=9; var a = new A(); console.lo ...
- 锻造(forging)
--九校联考24OI__D1T1 题目背景 勇者虽然武力值很高,但在经历了多次战斗后,发现怪物越来越难打,于是开始思考是不是自己平时锻炼没到位,于是苦练一个月后发现--自己连一个史莱姆都打不过了. 勇 ...
- C#实现局部峰值查找,功能对应Matlab中的findpeaks.m(转)
相关算法的原理参考Ronny,地址:图像分析:投影曲线的波峰查找,这里感谢下原作者. 参照C++的代码实现,我用C#翻译了下,其实原理也很简单的,下面放相关实现代码: private double[] ...
- Linux 第七天
软件包管理 1.软件包分类 1)源码包(脚本安装包) 优点: l 开源,如果有足够的能力,可以修改源代码 l 可以自由选择所需的功能 l 软件是编译安装,所以更加适合自己的系统,更加稳定也效率更 ...
- slecte下拉框的多选操作及获取值的 变化
对select增加一个 multiple属性,再获取多选的值的时候,对数据进行遍历,如果单纯的获取select的value值,指挥获取一个值, 遍历方法 可以先获取到select的dom元素到,然后对 ...
- 用Rider写一个由Autofac管理资源的WebAPI应用程序
一:步骤和上一篇创建控制台项目一样,不过这次选择的是.net core区域下的Asp.net web application,Type里选择Web API(Web API类似java里的SpringB ...
- 在Word中插入Excel对象
using Word = NetOffice.WordApi; Word.Document doc = this._wordApplication.Documents.Add(@"C:\Us ...