x86 real mode/protected mode interrupts

本文深入探讨x86/x64架构下的中断体系,包括硬件、软件及内部中断,阐述实模式下中断向量表(IVT)与保护模式下中断描述符表(IDT)的工作原理,解析不同类型的中断及其处理机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 深入理解 x86/x64 的中断体系(IVT VS IDT)

1.Interrupt
  Interrupt is a mechanism that allow hardware or software to suspend normal execution on microprocessor in order to switch to interrupt service routine for hardware / software. Interrupt can also described as asynchronous electrical signal that sent to a microprocessor in order to stop current execution and switch to the execution signaled (depends on priority). Whether an interrupt is prioritized or not depends on the interrupt flag register which controlled by priority / programmable interrupt controller (PIC).

  There are 5 type of interrupts:

  • hardware interrupt, this is external interrupt caused by hardware; for example when pressing keyboard.
  • Non-maskable interrupt (NMI), the interrupt that can not be ignored by microprocessor.
  • Software interrupt, this is maskable interrupt that comes from a software; this interrupt comes when an assembly routine execute int instruction
  • Internal interrupt, this interrupt is a result of processor state violation, for example : divide by zero error
  • Reset, this interrupt will reset cpu state

2.Real mode interrupts(Interrupt Vector Table (IVT))

  Interrupt vector table on 8086 is a vector that consists of 256 total interrupts placed at first 1 kb of memory from 0000h to 03ffh, where each vector consists of segment and offset as a lookup or jump table to memory address of bios interrupt service routine (f000h to ffffh) or dos interrupt service routine address, the call to interrupt service routine is similar to far procedure call.

  The size for each interrupt vector is 4 bytes (2 word in 16 bit), where 2 bytes (1 word) for segment and 2 bytes for offset of interrupt service routine address.So it takes 1024 bytes (1 kb) memory for interrupt vector table. On 8086 with dos operating system, interrupt vector table at 00h-1fh (int num 0-31) consists of lookup / jump table address to hardware or bios interrupt handler routine, meanwhile 20h-ffh (int num 32-255) consist of jump table address to dos interrupt handler routine.

  For example int 13h that located on ivt at 0000:004c contains address of Bios ROM Interrupt Service Routine, what it records is segment F000h, and offset 1140h, each bytes of that address will be placed little endian. The lower the interrupt number on interrupt vector table means the more priority needed for an interrupt.

3.protected mode interrupts(IDT)

  In protected mode, interrupts are handled in a similar way as real mode. The Interrupt Descriptor Table (IDT) does what the IVT does in real mode. IDT consists of an array of 8-byte segment descriptors called gates. The Interrupt Descriptor Table Register (IDTR) holds the base address and the limit of IDT. The IDT must exist in physical memory and should never swap out to virtual memory. This is because if an interrupt were to occur while the IDT were swapped out, the processor would generate an exception, requiring the IDT to get the handler for handling this exception, and so on until the system crashed. The gates in the IDT can consist of three types: interrupt gates, trap gates, and task gates. We won’t dwell on the details of the trap and task gates. For further information, refer to Intel processor documentation.

  Interrupt gates interest us. The important fields of interrupt gates include the code segment selector and the offset of the code for execution for this interrupt, as well as the privilege level of the interrupt descriptor. The interrupt processing closely resembles that in real mode. When the interrupt occurs, the processor indexes the interrupt number in IDT, pushes EFLAGS, CS, and EIP onto the stack, and calls the handler specified in the IDT. When the handler finishes executing, it should execute the IRET instruction to return control. Depending upon the type of interrupt, an error code may be pushed on the stack. The handler must clear this error code from the stack. The DPL field in the interrupt gate controls the software interrupts. The current privilege level must be at least as privileged as DPL to call these software interrupts. If not, then a General Protection Fault is triggered. This protection feature permits the operating system to reserve certain software interrupts for its own use. Hardware interrupts and exceptions process without regard to the current privilege level.

参考资料:
https://www.itread01.com/content/1544550128.html
http://www.reverse-engineering.info/SystemHooking/hooksoft.htm

### 编写操作系统 Bootloader 的基础 为了从零开始编写操作系统的引导加载程序(Bootloader),了解其基本概念和工作原理是必不可少的。Bootloader 是计算机启动过程中最早运行的一段代码,负责初始化硬件并加载操作系统内核。 #### 理解 Bootloader 工作流程 在理解了 Bootloader 基本概念之后,项目进一步深入解析了 Bootloader 引导操作系统的步骤和流程[^1]。具体来说: - **硬件初始化**:这是整个启动过程的第一步,在此阶段,CPU 和其他重要外围设备会被设置到已知状态。 - **模式切换**:现代 CPU 默认以实模式启动,而大多数操作系统则运行于保护模式或更高级别的执行环境。因此,Bootloader 需要完成从低级模式向更高权限级别的转换[^2]。 - **加载内核映像**:一旦完成了必要的准备工作,下一步就是定位存储介质上的目标操作系统镜像,并将其读入内存指定位置准备执行。 #### 开发工具链的选择 针对不同平台特性选择合适的编译器、链接器以及调试工具非常重要。对于 x86 架构而言,NASM 或 GAS 可作为汇编语言编译选项;GCC 则适合用于 C/C++ 混合编程场景下构建较复杂的 Bootloader 功能模块[^3]。 ```assembly ; boot.asm - A simple bootloader example using NASM syntax bits 16 ; Set code generation to 16-bit mode org 0x7c00 ; Origin point (offset where BIOS loads the MBR) start: jmp short loader ; Jump over data section nop loader: cli ; Clear interrupts cld ; Clear direction flag xor ax, ax ; Zero out AX register mov ds, ax ; Initialize DS segment register mov es, ax ; Initialize ES segment register mov ss, ax ; Initialize SS stack segment mov sp, 0x7c00 ; Setup a small stack pointer just below our bootloader call load_kernel ; Load kernel into memory call switch_to_protected_mode ; Switch from real-mode to protected-mode jmp $ ; Infinite loop until we jump elsewhere times 510-($-$$) db 0 ; Pad remainder of sector with zeros... dw 0xaa55 ; ...and end with magic number indicating valid boot record. ``` 上述代码展示了如何创建一个简单的基于 x86 实模式架构的 Bootloader 片段,该片段实现了最基本的自举功能。 #### 学习资源推荐 尽管有许多资料可以指导开发者入门 Bootloader 开发领域,但对于初学者来说,《Thor-OS: 从零开始的C++操作系统指南》提供了宝贵的见解,特别是关于启动过程核心部分的理解。另外,“第〇章 从零开始开发 UEFI 引导的 64 位操作系统内核”也是一份独特且有价值的参考资料,虽然这份文档本身并不专注于教授 Bootloader 编程技巧,但它强调了一些重要的原则和技术细节。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值