顺便复习操作系统了
WinOS 相关原理
中断级
如果有时间的话可以试着玩一玩这个游戏:https://github.com/plbrault/youre-the-os
在线:https://plbrault.github.io/youre-the-os/
或许在游玩的过程中你会自己总结出一套操作系统进程调度的一套方法,便于其他方法的理解
-
调度方式:抢占式
-
最小执行单元:纤程->线程->进程
-
中断级( Irql ) 0->2级别越来越高,高级别可以打断低级别
-
0:Pass level
-
1:Apc level
-
2: Dpc level
ISR延迟调用,硬件中断后,不那么紧急的任务放在DPC队列中
DPC访问换页内存,页面换到磁盘中pagefile.sys,引起换页缺页中断,如果换页中断无法打断DPC,然后就会访问无效地址,造成BSOD,所以DPC中最好不要使用换页内存,也即要使用
nonpagedpool
,而不要使用paged pool
-
hardware(io…)
-
强制打断:ipicall
-
自旋锁
有一间厕所,A进去后就锁上了厕所的门。B和C的其他就只有在门外排队等待
应用场景:
- 操作危险数据:全局变量等(可以参考SQL)
- 可重入代码
编程相关
中断级
获取自身中断级别:KeGetCurrentIrql()
升级到DPC:KeRaiseIrqlToDpcLevel
降级:KeLowerIrql
1 | DbgPrint("Current Irql %d\nNow Try Raise to DPC\n", KeGetCurrentIrql()); |
将线程保持在DPC会导致蓝屏
应用:希望函数在该线程执行中:1.不被中断,2:相关目标不被执行或者修改等
MSDN中有每个内核函数的中断级
创建DPC
线程
1 | VOID DpcRoutineFunc() { |
DPC中调用ZwOpenFile
之类的会BSOD
自旋锁
一般的自旋锁都是全局变量
1 | KeInitializeSpinLock(&kSpinLock); |
加锁这个函数会会提升到DPC中,但是DPC不能访问可分页内存,例如Ring3下的PCB中的LDR
视频给出了一个技巧