一文讲透!Windows内核 & x86中断机制详解

2023-11-15

搞内核研究的经常对中断这个概念肯定不陌生,经常我们会接触很多与中断相关的术语,按照软件和硬件进行分类:

硬件CPU相关:

  • IRQ
  • IDT
  • cli&sti

软件操作系统相关:

  • APC
  • DPC
  • IRQL

一直以来对中断这一部分内容弄的一知半解,操作系统和CPU之间如何协同工作也是很模糊。最近花了点时间认真把这块知识进行了梳理,不当之处,还请高手指出,先行谢过了!

本文旨在解答下面这些问题:

  • IRQ和IRQL之间是什么关系?
  • Windows是如何在软件层面上虚拟出IRQL这套中断机制的
  • APC和DPC都是软件中断,既然是中断那么对应的IDT表项中的处理例程在哪里呢?

0x00 Intel 80386处理器的中断

首先,让我们忘记Windows,从最开始的80386处理器开始,看看Intel设计它的时候是如何处理中断这个东西的。

先来看看这个诞生于1985年的CPU长什么样子:
在这里插入图片描述
看看那些伸出来的引脚,下面是它的引脚标注图:
在这里插入图片描述
注意用红圈标注的两个引脚,这两个就是80386处理器为中断留出的两个引脚。其中INTR是可屏蔽中断输入口,NMI是不可屏蔽中断输入口。

那么中断是如何输入给处理器的呢?那么多外部设备,而这只有一个引脚(暂时只考虑可屏蔽中断),这里就需要为CPU配备一个管理中断的秘书——可编程中断控制器PIC。这个秘书需要干哪些活呢?外部设备的中断都从它来进入中央处理器,所以它负责从外设接收中断信号,并根据优先级向CPU发起中断请求。最开始的这个PIC角色是一个代号为8259A的芯片在进行扮演,这货长这样:
在这里插入图片描述
下面是它的引脚图:

在这里插入图片描述
其中IR0-IR7共8个引脚负责连接外部设备, 8259A PIC的每个IR口都连接着一条IRQ线,用于接收外设的中断信号。INT负责连接CPU的INTR引脚,用于向CPU发起中断请求。通常情况下,使用两片8259A芯片进行级联,一片连接CPU,称为主片,另一片连接到主PIC的IR2引脚,称为从片,这样总共就可以连接8+7=15个外设了。如下图所示:
在这里插入图片描述
在8259A中,默认情况下的优先级是主片IR0的中断请求优先级最高,主片IR7最低,从片IR0-7所有中断请求优先级都相当于IR2。所以IRQ线的优先级由高到低次序为IRQ0,IRQ1,IRQ8-15,IRQ3-7。这是默认情况,可以通过编程改变。

在8259a芯片内部有几个重要的寄存器:

中断请求寄存器: IRR,8bit,对应IR0-IR7,当对应引脚产生中断信号时,该bit位置1。

中断服务寄存器: ISR,8bit,对应IR0-IR7,当对应引脚的中断正在被CPU处理时,该bit位置1。

中断屏蔽寄存器: IMR,8bit,对应IR0-IR7,当对应位为1时,表示屏蔽该引脚产生的中断信号。

还有一个中断优先级判决器: PR,当中断引脚有信号时,结合这次产生中断的IRQ号和ISR中记录的当前正在处理的中断信息,根据优先级来决定是否把这个新的中断信号报告给CPU,以此来产生中断嵌套。

下面是这15条IRQ线分别连接的外设:
在这里插入图片描述
现在我们来看看这个秘书是如何和CPU之间进行协调工作的。

现在假设我们敲击了一个键盘按键,键盘有中断事件产生,这一事件通过IRQ1这根线告知了主PIC,主PIC经过内部一些判断处理后通过INT发送电信号到CPU侧的INTR。CPU在执行完当前的指令后,检查到INTR有信号,说明有中断请求来了,再检查eflags中的IF不为零,表示当前允许中断,则发送信号给PIC的-INTA,告诉它把本次中断的向量号发送过来。主PIC收到-INTA管脚上的信号后,通过D0-D7引脚,输出此次中断的中断向量号到数据总线(这里简化了交互过程,实际上有两次INTA信号的发送)。CPU拿到这个号后,就可以从IDT中寻找中断服务例程(ISR)进行处理了,后面的事大家都知道了。

那PIC中的中断向量号是怎么来的呢?各个IRQ是如何对应到IDT中的各个项呢?这里就利用了中断控制器的可编程性来决定的了。

PIC全称为可编程中断控制器,那么它的可编程体现在哪些方面呢?参考资料2《i8259A中断控制器分析一》一文有比较详细的描述,大体包括编程指定主从片的IRQ线对应的中断在IDT表中的中断向量号、8259a中断控制器的中断方式、优先级方式、中断嵌套方式,中断屏蔽方式、中断结束方式等等,这些都可以由操作系统编程指定。具体的编程格式在参考资料3《i8259A中断控制器分析二》一文中有图文介绍。

回到上一个问题,IRQ线上的中断如何和IDT中的条目对应起来,操作系统在初始化的时候,会通过对8259a芯片编程(读写I/O端口),将指定PIC芯片的起始向量号,并要求低三位为0,起始向量号按照8对齐,这样规定的原因是,当中断发生时,低三位将自动填充对应的IRQ号,这样就可以和起始向量号相加直接送给数据总线从而被CPU拿到。具体到Windows中,系统初始化的时候对PIC的编程为:指定主片的起始中断向量号为0x30,指定从片的起始中断向量号为0x38。这样,通过中断控制器连接的15个外设将被平坦的映射到IDT中0x30-0x40这一范围中。Windows内核启动初始化过程中使用了hal!HalpInitializePICs对8259a芯片进行编程,ReactOS中代码如下:

在这里插入图片描述
其中0x20,0x21是主片的IO端口,0xa0,0xa1是从片的IO端口:
在这里插入图片描述
PRIMARY_VECTOR_BASE定义为:
在这里插入图片描述
具体8259a的编程方法就是读写IO端口,设置对应的控制命令,不用深入研究。我们来看Windows编程8259a的时候指定了哪些东西。

  • 1、指定了主片的工作方式为级联、中断方式为电信号边沿触发
  • 2、指定了主片IRQ的中断向量映射基址:0x30
  • 3、指定了主片的级联方式为使用了自己的IRQ2这个管脚
  • 4、指定了主片的工作模式为80x86模式,中断结束方式为普通结束模式
  • 5、指定了从片的工作方式为级联、中断方式为电信号边沿触发
  • 6、指定了从片IRQ的中断向量映射基址:0x38
  • 7、指定了从片的工作方式级联方式为主片的IRQ2这个管脚
  • 8、指定了从片的工作模式为80x86模式,中断结束方式为普通结束模式

至此我们可以知道,在使用8259A中断控制器的计算机上,通过IRQ线连接的那15个外设可屏蔽中断是被操作系统线性的映射到了IDT中的一个范围段。在Windows中是0x30-0x40(PS:在Linux中是0x20-0x2F),同时指定了中断控制器的中断方式为边沿触发,结束模式为普通结束模式(也就是需要CPU侧告知中断处理有没有结束并设置对应bit位,不能自动设置)。

0x02 8259a上的Windows IRQL

下面来看看IRQL。

从前面我们看到,硬件层面已经对中断的处理提供了很好的支持,需要操作系统做的也就两点:首先,初始化的时候对PIC进行编程设置其工作方式并对IRQ进行映射,让这些中断对应到IDT中的各个项,其次,实现这些IDT中的中断服务例程。似乎这样就够了,那Windows弄出来的一套IRQL又是什么东西呢?

看看《Windows Internals》一书对IRQL的定义:
在这里插入图片描述
写驱动的时候经常会接触到IRQL这个概念,它实现了Windows里的中断优先级制度,高优先级的中断总是可以优先被处理,而低优先级的中断则不得不等待高优先级中断被处理完后才得到处理。软件虚拟出来的这一套机制怎么能管到硬件的优先级呢?这是如何实现的呢?

先来解决两个问题:

1、IRQ和IRQL的关系是什么?、使用KeRaiseIrql提升当前IRQL后,为什么就能保证不被低优先级的中断打扰?

对于第一个问题,在使用8259a中断控制器的计算机中,IRQL=27-IRQ,其就是一个线性关系。

关于第二个问题,《Windows Internals》一书是这样解答的:
在这里插入图片描述
下面我们具体来看Windows的实现:

IRQL是一个完全虚拟出来的概念,Windows为了实现这一个虚拟的机制,完全虚拟了一个中断控制器,它在KPCR中:

+0x024 Irql         : UChar  //IRQL
+0x028 IRR          : Uint4B  //虚拟中断请求寄存器
+0x02c IrrActive    : Uint4B  //虚拟中断在服务寄存器
+0x030 IDR          : Uint4B  //虚拟中断屏蔽寄存器

在前面第一部分提到过,通过两片8259a芯片连接的15个中断源被映射到处理器IDT中的一段范围,具体Windows而言,是在0x30-0x40这个范围。这15个IDT中的中断描述符所描述的中断处理例程(ISR)不同于int 3所对应的KiTrap03和int 0e所对应的KiTrap0E,他们的ISR指向的代码位于各自的中断对象KINTERRUPT的DispatchCode。下面是这个结构的定义:

typedef struct _KINTERRUPT {
    CSHORT Type;
    CSHORT Size;
    LIST_ENTRY InterruptListEntry;
    PKSERVICE_ROUTINE ServiceRoutine;
    PVOID ServiceContext;
    KSPIN_LOCK SpinLock;
    ULONG TickCount;
    PKSPIN_LOCK ActualLock;
    PVOID DispatchAddress;
    ULONG Vector;
    KIRQL Irql;
    KIRQL SynchronizeIrql;
    BOOLEAN FloatingSave;
    BOOLEAN Connected;
    CHAR Number;
    UCHAR ShareVector;
    KINTERRUPT_MODE Mode;
    ULONG ServiceCount;
    ULONG DispatchCount;
    ULONG DispatchCode[106];
} KINTERRUPT, *PKINTERRUPT;

复制代码 DispatchCode里面的代码是根据一个模板来的,这些ISR处理开始和KiTrap03这些一样,首先会建立陷阱帧,然后会获取自己所在KINTERRUPT对象地址,得到这两个参数之后,便开始使用KiInterruptDispatch或KiChainedDispatch(如果对该中断注册了多个KINTERRUPT结构构成了链表使用此函数)进行中断派遣。而在这两个具体的派遣中都会先调用HalBeginSystemInterrupt,然后才会执行对应中断的实际处理工作,最后会执行HalEndSystemInterrupt完成此次中断处理。下面我们重点来看看这两个函数。

BOOLEAN
HalBeginSystemInterrupt(
    IN KIRQL Irql
    IN CCHAR Vector,
    OUT PKIRQL OldIrql);

输入参数Irql表示本次发生的中断对应的的IRQL,Vector表示中断向量号,如前所述,这两个参数都是DispatchCode从自己所在KINTERRUPT对象中取出来的。

HalBeginSystemInterrupt内部使用IRQL参数在一个表格中进行了分发,这个表中除了个别函数不同外(其实也只是多了一层判断),其他表项都是一致的,在ReactOS中名为HalpDismissIrqGeneric,该函数直接转而调用其下划线版本_HalpDismissIrqGeneric。这里就是IRQL优先级实现的核心所在了。该函数不长,下面是ReactOS中的代码(在Windows2000代码中是汇编形式不如ReactOS使用的C语言形式直观,所以采用了ReactOS的代码进行说明):
在这里插入图片描述
首先,判断本次发生的中断对应的IRQL与当前处理器(KPCR)中的IRQL进行比较,如果大于了当前处理器的IRQL,则表示来了一个优先级更高的中断,这时设置KPCR中的IRQL为这个新的更高的数值,后面返回了TRUE,表示需要处理这次中断请求。如果不大于当前处理器的IRQL的话,首先把本次中断记录记录到KPCR中的虚拟中断控制器的IRR值,然后就直接通过KiI8259MaskTable表中选取当前处理器IRQL对应的屏蔽码写入PIC,用以屏蔽那些IRQL比自己低的中断源,后面返回FALSE,表示不处理这次中断请求。为什么不在设置处理器新IRQL的时候就进行设置屏蔽码呢?《Windows Internals》是这样解释的:
在这里插入图片描述
HalpDismissIrqGeneric的返回值将直接作为HalBeginSystemInterrupt的返回值。以中断派遣函数KiInterruptDispatch为例看看它是如何使用这个返回值的:
在这里插入图片描述
可以看出,如果HalBeginSystemInterrupt返回了FALSE,则直接导致本次中断处理提前结束。只有当HalBeginSystemInterrupt返回了TRUE时,才继续执行真正的中断处理例程。最后, 情况下都会调用KiExitInterrupt结束中断处理过程,看一下这个函数。结合KiInterruptDispatch的代码,可以看出,只有当HalBeginSystemInterrupt返回的是TRUE时,下面的if条件才会成立,从而进入HalEndSystemInterrupt。
在这里插入图片描述
最后看一下HalEndSystemInterrupt,前面提到如果发生的中断对应的IRQL低于处理器的IRQL,则不会执行其ISR,但会在KPCR中的虚拟中断控制器的IRR中记录起来,等到处理器执行完了高IRQL的任务时,到了HalEndSystemInterrupt的时候,就会降低处理器的IRQL并重新设置PIC的中断屏蔽码,另外很重要的就是去检查IRR中的记录,如果记录中有比降低后的IRQL高的记录,则派遣该中断。

→【技术文档】←

总结

最后总结一下使用8259a中断控制器的计算机中Windows的IRQL。

首先,系统启动时对8259a芯片编程,设置其工作方式,并将15个中断源(IRQ)映射到IDT中的0x30-0x40这一段。

第二,Windows自己定义了一个称为中断请求级的IRQL概念用来描述中断的优先级别,IRQL是一个DWORD,共计32个级别,Windows使用一个简单的线性关系来映射IRQ和IRQL:IRQL=27-IRQ。

第三,被映射中断请求的0x30-0x40这一段的中断描述符的每个ISR都指向了一个KINTERRUPT结构中的DispatchCode,这段DispatchCode使用中断派遣函数KiInterruptDispatch或KiChainedDispatch进行中断派遣。

第四,派遣过程为:先使用HalBeginSystemInterrupt对本次中断的IRQL进行判断来决定是否需要处理本次中断,若不需要,则设置中断控制器的屏蔽码,防止再被打扰,同时将本次中断登记在KPCR中的虚拟中断控制器IRR中。若需要则提升IRQL,进而执行该中断的实际处理例程,执行完毕后使用HalEndSystemInterrupt降低IRQL,然后检查IRR有没有记录没被处理的中断以便在这个时候进行处理。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

一文讲透!Windows内核 & x86中断机制详解 的相关文章

  • 在 64 位 Windows 上运行 32 位可执行文件时出现问题

    如果允许的话 我会添加 500 个我自己的代表作为赏金 我在用着wkhtml转pdf http wkhtmltopdf org 将 HTML 网页转换为 PDF 这在我的 32 位开发服务器上完美运行 不幸的是 我无法运送我的机器 p 但是
  • 如何批量获取子字符串在字符串中的位置

    获取子串的位置 Set str1 This is Test string Set sstr Test 这里我需要获取 Test 8 的位置 谢谢 echo OFF SETLOCAL Set str1 This is Test string
  • 批处理脚本 - IF EXIST 复制到 %localappdata% 错误

    我似乎被批处理脚本困住了 需要一些帮助 基本上我需要检查文件是否存在于文件夹中 localappdata 如果确实如此 则覆盖该文件 如果没有放置在不同的位置 那么目前它的内容如下 IF EXIST localappdata foldern
  • 已达到网络 BIOS 命令限制

    我的 ASP Net 应用程序从另一台 Windows 服务器上的共享文件夹获取文件 当请求增加时 我收到以下错误 The network BIOS command limit has been reached 我已按照以下步骤操作微软 K
  • Windows 等效的系统配置目录

    我正在 Ruby 中开发一个 CLI 应用程序 我希望允许通过标准配置文件级联在 Unix 中进行配置 etc appnamerc appnamerc 然而 该应用程序也应该在 Windows 环境中运行 我不确定将像这样的文件放在哪里 e
  • Notepad++ - 使函数“可点击”?

    我只是想这可能有用 但我找不到办法 在 Notepad 中 有没有一种方法可以使函数名称 可单击 即使它们成为链接 这样如果您单击它们 它会自动将您带到其定义 最好是跨整个代码库 目前还没有插件提供可直接单击的函数名称 但您可以尝试使用 S
  • 在 Windows cmd 中,如何在不引用完整路径的情况下运行当前目录中的可执行文件(而不是 %PATH% 中同名的可执行文件)? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在尝试运行可执行文件foobar来自目录 但 Windows 也恰好有一个名为的可执行文件 或命令 foobar 在 UNIX 中 我
  • _CrtCheckMemory使用示例

    我试图了解如何使用 CrtCheckMemory追踪我正在开发的 Windows 应用程序中的堆损坏 我似乎无法让它返回false 这是我的测试代码 int test new int 1 for int i 0 i lt 100 i tes
  • 使用特定的 JRE 运行 JAR 文件

    在 Windows 上有没有办法使用位于特定文件夹中的 JRE 运行 JAR 文件 类似于 Eclipse 在您提供给它的某个路径中查找其 JRE 的方式 一些 Windows 可执行代码 C 或 C 或批处理文件都可以完成这项工作 谢谢
  • 使用 Rust 构建的 DLL 在运行时是否需要 libgcc.dll?

    如果我构建一个 DLLRust 语言 http rust lang org 是否需要libgcc dll在运行时出现 一方面 我在互联网上的某个地方看到过一个帖子 声称是的 rustc exe has libgcc s dw2 1 dll在
  • 适用于 Python 的 GitLab CI 共享 Windows 运行器

    我在 GitLab 中有一个 python 项目仓库 我看到 GitLab 共享了可用的测试版 Windows 运行程序 请参阅this https about gitlab com blog 2020 01 21 windows shar
  • .NET 中安全身份的本地化

    我想在 NET 中实现一个用于服务 客户端通信的命名管道 并遇到了这段代码 http code msdn microsoft com windowsdesktop CSNamedPipeCommunication 33b2485c view
  • Java 7 默认语言环境

    我刚刚安装了 jre7 我很惊讶地发现我的默认区域设置现在是 en US 对于jre6 它是de CH 与jre7有什么不同 默认区域设置不再是操作系统之一吗 顺便说一句 我使用的是Windows7 谢谢你的回答 编辑 我已经看到了语言环境
  • 如何在 Windows 中创建上下文菜单子菜单?

    我一直在编写实用程序并通过 Shell 键 上的 Regedit 将它们映射到上下文菜单 但我不知道如何像一些更流行的实用程序那样创建子菜单 例如 如果我有三个脚本将文件移动和重命名到三个不同的文件夹 那么现在我有三个不同的上下文菜单条目
  • Windows 10:任务栏中的图标大小错误

    从 Windows 10 开始 任务栏中的图标大小似乎为 24x24px 如果 Windows 选择图标文件中的 24px 版本进行显示 那么这不会有问题 但它选择了 32px 版本并将其缩小 这会导致丑陋的伪像 尤其是当你的图标中有直线时
  • 无法在 Windows 10 上运行 Python 3.7“权限被拒绝”

    当尝试使用 Git Bash 在 Windows 10 上运行 Python 3 7 时 出现以下错误 python version bash c Users Name AppData Local Microsoft WindowsApps
  • 如何在 Windows 上使用命令行获取 svn 修订信息

    我正在尝试使用此命令行获取头部的修订信息 svn info https myserver branches Code Improvements rHEAD find Revision 然而 这返回修订版 1234 由于我使用 svn inf
  • Web 应用程序的带宽和流量模拟器?

    您能否建议如何创建一个测试环境来模拟 Web 应用程序中的各种类型的带宽和流量 或者也许是一个针对本地主机执行此操作的开源程序 我认为在编写网络应用程序时这是一个非常重要的主题 但这不是一个常见的主题 我能想象创建这种环境的唯一方法是在本地
  • 如何通过文件关联执行已启动应用程序的事件?

    在尝试了一个新的 Windows 窗体项目后 我发现当您将文件类型与 Windows 中的可执行文件关联时 您可以使用以下命令找到启动应用程序的文件的文件路径args 0 from static void Main string args
  • 如何告诉 IntelliJ 使用 Java 1.6 JDK 启动 gradle?

    一个简单的问题 即使经过几个小时的尝试和搜索 我也无法弄清楚 我安装了 Java 6 和 7 如何告诉 IntelliJ 使用 JDK 版本 1 6 启动 Gradle 构建 无论我做什么 IntelliJ 都会以以下方式开始我的 grad

随机推荐

  • WebGoatV8.1(challenges)详细过关教程

    一 Admin lost password 设置代理继续抓包 刷新题目本页面 抓取url路径为 WebGoat challenge logo的包 重放在回应包里面搜索admin找到账号和密码 登录拿到flag 二 Without passw
  • 华为od统一考试B卷【师徒关系】

    题目描述 给定数组 2 1 3 2 每组表示师徒关系 第一个元素是第二个元素的老师 数字代表排名 现在找出比自己强的徒弟 输入 2 1 3 2 输出 0 1 2 第一行数据 2 1 表示排名第 2 的员工是排名第 1 员工的导师 后面的数据
  • Flask 数据库-单表操作

    Flask SQLAlchemy Flask SQLAlchemy是在Flask中操作关系型数据库的拓展 是以面向模型对象的形式操作数据库 通过迁移完成建表 安装 pip install flask sqlalchemy 基本配置 第一种
  • c语言2进制转3进制

    保存答案的 要求二进制满足最多64位 网上的答案都不对 听同学讲用了 unsigned long long 和 运算左移 方法一 include
  • Nodejs等待一段时间

    定义 function timeout ms return new Promise resolve reject gt setTimeout resolve ms done 使用 等待2秒 timeout 2000 then gt 这里写等
  • Auto.js监测抖音验证弹窗和关闭权限弹窗如(点击文字弹窗、滑动拼图解锁弹窗、上滑查看更多视频弹窗等)

    文章目录 前言 一 实现原理 二 使用步骤 1 代码示例 2 echo log方法 总结 前言 在使用Auto js实现抖音模拟点击过程中 会出现权限申请弹窗 验证弹窗 上滑查看更多视频弹窗等 阻塞脚本运行 下面给大家介绍下摸索的成果 一
  • C/C++编程:类

    什么是类 类是一种用户定义 数据 类型 类似与C语言的结构体 无论是什么编程语言 进行面向对象程序设计都是从类的设计开始的 类则是C 面向对象编程的实现方式 类的声明与定义 语法 类关键词 class struct union 之一 类可拥
  • 1.3 大数据导论与Linux基础-VMware Workstation虚拟机使用

    文章目录 VMware Workstation虚拟机使用 一 VMware虚拟机概念与安装 VMware介绍 VMware功能 组件 网络架构图 在PC上安装VMware Workstation虚拟机软件 二 Centos操作系统的虚拟机导
  • LeetCodes刷题总结1——寻找两个正序数组的中位数

    题目 给定两个大小分别为 m 和 n 的正序 从小到大 数组 nums1 和 nums2 请你找出并返回这两个正序数组的 中位数 算法的时间复杂度应该为 O log m n 示例1 输入 nums1 1 3 nums2 2 输出 2 000
  • ‘parent.relativePath‘ points at com.xxx instead of org.springframework.boot:spring-boot-starter的快速解决

    快速解决 在
  • PTA 7-76 寻找完美数*

    PTA 7 76 寻找完美数 所有真因子之和小于其本身的数称为亏数 如 4 的真因子 1 2 之和为 3 小于 4 是亏数 所有真因子之和大于其本身的数称为盈数 如 12 的真因子 1 2 3 4 6 之和为 16 大于 12 是盈数 不盈
  • throttle-debounce 节流和防抖

    目录 1 区别 2 使用 3 实现 3 1 debounce 3 2 throttle 4 意外收获 throttle节流 debounce防抖 1 区别 假设时间频率 1s throttle 是每隔 1s 必然执行 高铁不能人 到点就发车
  • 八进制在计算机系统中的应用场景,二进制、八进制、十进制、十六进制都能干什么? 十六进制计算器使用场景...

    二进制 二进制如今主要用在电子技术的数字电路中 比如我们经常使用的计算机能够识别的语言就是二进制语言 数字电路中的高 低电平 导通 截止 开 关 有 无 真 假等等都是二进制表示 二进制的逻辑电路使用0和1表示 八进制 十进制 十六进制 八
  • springboot 源码_springboot源码解析

    1 springboot是什么 脚手架 纵观框架的发展过程 最终由springboot出来做了SSM的整合 方便程序员偷懒 因为SSM整合过程中有很多的配置 很多的依赖 很容易出错 也不方便快速开发 2 spring创建对象的过程 图解 开
  • Air Raid

    http poj org problem id 1422 Description 例如 Consider a town where all the streets are one way and each street leads from
  • 比double精度更高的数据类型_MySQL 数据类型之浮点

    基本数据类型 为什么明确数据类型 不同数据类型大小不同 明确了数据类型之后 可以帮助使用者进行类型检查 明确存储空间大小 明确操作是否合理 从手册上来看 基本的数据类型包括 日期与时间 05 27 2020 字符串 abcd 空间数据 JS
  • hadoop-for-windows

    http dongxicheng org mapreduce hadoop for windows
  • 使用ftp服务上传文件时553报错的解决(绝对有用)

    使用ftp服务上传文件时553报错的解决 在使用ftp上传本地文件时 会遇到553的报错 以下是我总结的解决方法 1 使用本地用户登陆时 在使用本地用户登陆ftp服务上传文件时 如果遇到553的报错 一般来说可能有两种原因 原因1 本地文件
  • Linux用户态和内核态

    1 用户态和内核态的概念区别 究竟什么是用户态 什么是内核态 这两个基本概念以前一直理解得不是很清楚 根本原因个人觉得是在于因为大部分时候我们在写程序时关注的重点和着眼的角度放在了实现的功能和代码的逻辑性上 先看一个例子 1 例子 void
  • 一文讲透!Windows内核 & x86中断机制详解

    搞内核研究的经常对中断这个概念肯定不陌生 经常我们会接触很多与中断相关的术语 按照软件和硬件进行分类 硬件CPU相关 IRQ IDT cli sti 软件操作系统相关 APC DPC IRQL 一直以来对中断这一部分内容弄的一知半解 操作系