内核开发知识第二讲,编写Kerner 程序中注意的问题.
一、函数多线程的安全问题
函数多线程安全指的是,当一个函数在被调用但尚未返回时,如果被其他线程再次调用,其执行结果仍然是可靠的。
在用户层编写多线程程序时,我们通常会关注同步问题,以确保线程安全。同样地,在内核中也需要注意以下几点:
-
可能在多线程环境中运行的函数必须保证线程安全。如果运行在单线程环境中,则不需要考虑线程安全性,因为没有其他线程操作。
-
如果函数A调用函数B,函数B调用函数C,且A和B都运行在同一单线程中,那么C也应保证运行在单线程中。
-
如果函数A调用函数B,函数B调用函数C,且B和C可能在多线程环境中运行,那么A也可能在多线程环境中运行。因为A会调用B和C,所以B和C在多线程环境中运行。
-
如果函数A调用函数B,函数B调用函数C,且B运行在多线程环境中,那么需要采取多线程序列化为单线程的强制措施,使得函数B在单线程中运行。
内核中的“多线程序列化为单线程的强制措施”包括互斥体和自旋锁。
-
只使用函数内部资源,不使用全局变量、静态变量或其他全局性资源的函数是多线程安全的。
-
如果使用全局变量、静态变量等,那么需要使用同步函数来进行同步。
二、中断级别
这篇博客主要讨论了理论和需要注意的问题。在内核中,Kernel API有中断级别之分。
在用户层,代码都是同级别运行,因此不需要关心中断级别,但在Kernel内核中,必须关注中断级别,否则可能会导致持续的问题。
目前,中断级别有两个:
- Passive级别。
- Dispatch级别。
关于这两种级别,内核博客的前两课有简单介绍其本质。我们只需注意这两种级别的区别即可。
简单的函数运行在Dispatch级别中。因此,在调用任何Kernel API之前,都需要查询一下中断级别。
Dispatch级别比Passive级别高。
如何判断中断级别?
- 调用路径:A -> B -> C,那么C的调用路径就是A和B,因为是一条线。
- 调用源:A -> B -> C,那么一次递推到A,那么C的调用源就是A。
判断规则:
- 如果调用路径上没有特殊情况(导致中断级别提高或降低的情况),那么函数执行时的中断级别与其调用源级别相同。
- 如果调用路径上有获取自旋锁,则中断级别随之提高;如果有释放自旋锁,则中断级别降低。
内核中的中断级别:
| 调用源 | 级别 |
|---|---|
| DriverEntry | Passive级别 |
| DriverUnload | Passive级别 |
| 各种分发函数 | Passive级别 |
| 完成函数 | Dispatch级别 |
| 各种NDIS回调函数 | Dispatch级别 |
查询Kernel API时,会发现有说明该API在什么级别使用。
例如:
可以看到中断级别是...
疑问?
如果当前代码运行在DISPATCH级别,但必须调用PASSIVE级别的API,该怎么办?可以利用内核API降低当前中断级别吗?
答:
不可以。Windows代码都是在规范的级别上运行的,任意降低或提高都会影响代码的执行。因此,在需要调用这种API时,可以创建一个专门的线程来执行PASSIVE级别的代码。
解决方法很多,可以在网络上搜索相关资料。博主也是自学,所以暂时还没有接触到更多方法。
三、内核中宏代码代表的意思
在内核中查看API时,可以看到许多宏,这些宏都是空宏,用于说明。
例如:
- IN:表示这个参数是传递进去的。
- OUT:表示这个参数是传出参数。
例如:
__in_bcount(StatusBuffsize) IN PVOID statusBuffer;
这里的参数表示statusBuffer的大小依赖于StatusBuffsize这个参数来指定。
四、指定函数位置的预编译指令
这个小主题本来可以放在第三个问题中,但单独说明更重要。
#pragma alloc_text()
这个宏表示我们的函数的可执行代码编译出来之后在.sys文件中的位置。
.sys文件本质上是PE文件,PE文件有段和节,不同的节加载到内存中会有不同的处理情况。我们需要关注的有三种:
- INIT节:这个节的特点是初始化完毕后就会释放,不再占用内存空间。
- PAGE节:这个节的特点是可以进行分页交换的内存空间,即内存不够时可以临时放到磁盘上。
- PAGELK节:这是默认的节,如果不指定代码放在哪里,就会放在这个节中。特点是不能进行内存交换,即不可以和磁盘交互。
我们可以指定我们的代码放到哪个节中。
例如,入口函数只会调用一次,可以放到INIT节中,这样初始化完后就不占用内核内存,因为内核内存是共享的,用完就没了。
例如:
#pragma alloc_text(INIT,DriverEntry)
注意的问题:
如果将函数放入PAGE节中,代表该函数运行中可以放到磁盘上,这样会产生缺页中断。因此,放到PAGE节中的函数不能调用DISPATCH级别的函数。
以上就是内核开发知识第二讲,编写Kerner 程序中注意的问题.的详细内容,更多请关注就爱读【www.sztg.com.cn】。
如非特殊说明,本站内容均来自于网友自主分享,如有任何问题均请联系我们进行处理!
猜您喜欢
《冒险家艾略特的千年奇谭》编写历史成就做法攻略分享
2026-06-27《冒险家艾略特的千年奇谭》中的特殊成就的数量是非常多的,编写历史成就就是其中一个,成就的要求就是集齐所有手记,部分手记只会在你剧情推进到一定程度才会出现,提前去不会有,根据自己玩的流程大概有这么6本。 编写历史成就怎么做 编写历史 集齐所有手记 正常流程中28本,真结局通关后的自由行动时间有3本,分别在大臣家2楼,基友研究室,公主房间 不受剧情进度影响的只有26本。 2本是推进真结局到一定进度时,...
如何利用Kimi查找最新的Linux内核更新说明_利用Kimi实时搜索技术文档
2026-06-04Kimi可通过实时联网搜索精准获取kernel.org发布的最新Linux内核官方更新说明。需开启【实时搜索】并使用指定指令(如“site:kernel.org‘TheLinuxKernelchangelog’latest”),优先访问git.kernel.org链接,再通过Ctrl+F定位“Fixes:”“drivers/”等关键字段提取硬件修复信息。 你需要快速获取最新linux内核版本的官方...
怎样用Kimi编写Python脚本实现钉钉自动打卡_结合Kimi代码生成
2026-06-04钉钉打卡接口可用,但需先抓包获取有效Cookie和员工ID;若启用面部/蓝牙等强校验则脚本失效。 ☞☞☞AI智能聊天,问答助手,AI智能搜索,多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜ 你需要在每天上班前用Python脚本自动向钉钉提交打卡数据,但不熟悉逆向工程、HTTP协议或模拟登录流程,想借助Kimi的代码生成能力快速产出可运行脚本。 确认钉钉打卡接口是否可用 打开钉钉网页版(https...
如何在 Windows 11 中开启“程序员多窗口协同分屏模板” 提高编写代码提效
2026-06-04必须先启用SnapLayoutsv3引擎及全部六项贴靠子功能与超级分屏开关,否则程序员四象限模板无法触发;需在设置→系统→多任务处理中勾选贴靠窗口、布局、助手、组、贴靠时显示布局/助手,并启用超宽显示器扩展布局和超级分屏模板(仅24H2+)。 要在Windows11中真正启用“程序员多窗口协同分屏模板”,让VSCode、终端、浏览器与调试器四类窗口按语义逻辑自动排布到左上(IDE)、右上(浏览器)...
如何编写程序持续读取用户输入的整数并输出最大值
2026-06-02本教程讲解如何用python实现一个循环输入程序,持续接收用户输入的整数(每行一个),直到输入"stop"为止,并准确输出其中的最大值,同时妥善处理边界情况与类型安全问题。 本教程讲解如何用python实现一个循环输入程序,持续接收用户输入的整数(每行一个),直到输入"stop"为止,并准确输出其中的最大值,同时妥善处理边界情况与类型安全问题。 在解决“读取数字直至输入'Stop'并输出最大值”这...
Python编写Flask接口如何实现分页_SQLAlchemy使用limit与offset分页
2026-06-02SQLAlchemy中用limit()和offset()做深分页性能极差,因数据库需扫描并丢弃大量前置行;应改用基于id或created_at的游标分页。 SQLAlchemy用limit()和offset()分页会慢得离谱 不是语法错,是设计错。当offset值很大(比如第1000页,每页20条→offset=20000),数据库仍要扫描前20000行再扔掉,CPU和IO都白耗。PostgreS...
编写你的第一个 VBA 宏
2026-05-29经过前面几篇内容的学习,你已经对ExcelVBA有了初步了解,并掌握了VBA编辑器的基本操作。如果尚未阅读相关基础内容,建议优先完成以下学习: ExcelVBA是什么? VBA中的核心术语与基本要素 如何在Excel中启用「开发工具」选项卡 合理配置宏的安全级别 正确保存含有VBA代码的工作簿(必须选择支持宏的格式) 利用VBA编辑器开展基础开发工作 本节将手把手带你完成第一个完整的VBA宏——即...
如何在Windows 11中开启内核隔离与底层防护 预防零日漏洞恶意软件攻击
2026-05-29需重启才能生效;可通过Windows安全中心一键启用内存完整性,或用组策略编辑器(专业版等)强制启用VBS,亦可用注册表修改(家庭版适用),三者均依赖CPU虚拟化、UEFI安全启动和TPM2.0。 您需要在Windows11中启用内核隔离与底层防护功能,以阻止利用零日漏洞的恶意软件在内核层加载未签名驱动、篡改系统进程或执行提权操作;该防护依赖基于虚拟化的安全性(VBS)和受虚拟机监控程序保护的代码...
统信UOS系统出现多个引导项 彻底清理多余内核启动项的方法
2026-05-29先执行uname-r确认当前运行内核(如5.15.0-amd64)并保留;再通过控制中心图形化卸载旧内核,或用终端命令sudoaptpurge$(dpkg-l|awk'/^iilinux-image-[0-9]/&&!/$(uname-r)/{print$2}')--yes批量清理非当前内核,最后运行sudoupdate-grub同步引导项。 确认当前运行内核版本 先确保不误删正在...
修复Windows 11提示此驱动程序无法在此设备上加载 修复内核签名不匹配方法
2026-05-29Windows11驱动无法加载本质是内核签名验证失败,需针对性绕过:1.临时禁用驱动强制签名(Shift+重启→WinRE→F7);2.永久禁用内核完整性检查(bcdedit/setnointegritycheckson);3.关闭内存完整性(HVCI);4.启用测试模式;5.关闭SecureBoot。 Windows11提示“此驱动程序无法在此设备上加载”,本质是内核签名验证失败——系统检测到驱...
