I. Linux implementation
Intel provides three types of Interrupt descriptors: Task gate, interrupt gate, and trap gate. Linux is slightly different. According to Intel's definition, there are several types of windows.
1. Broken door
An Intel interrupt gate inaccessible to user-mode processes, DPL = 0.
2 system doors
An Intel trap that can be accessed by user-mode processes. DPL = 3 activates three exceptions in Linux: 128, (0x80 ).
3. system interrupt door
An Intel interrupt gate that a user-state process can access. DPL is 3. If an exception occurs, it is a system interrupt gate, int 0x03.
4 traps
The user-state process cannot access the Intel trap gate, DPL = 0.
5 tasks
Intel task gate that cannot be accessed by user-mode processes, DPL = 0.
Binary interrupt handler array interrupt [I]
The following assembly code in entry_32.s declares and initializes the interrupt array. Several details are worth analyzing.
/* Description and initialization of the interrupt array, which stores the address of the interrupt handler function */
/* The interrupt array belongs to the Data Segment just like the C language array, so it is declared in the data segment. However, array Initialization is the content of the Code segment. Note that */
. Data
Entry (Interrupt)
. Text
Entry (irq_entries_start)
Ring0_int_frame
Vector = 0
. Rept nr_irqs
Align
. If Vector
Cfi_adjust_cfa_offset-4
. Endif
1: pushl $ ~ (Vector)
Cfi_adjust_cfa_offset 4
JMP common_interrupt
. Previous/* Previous the following well-known content is connected to a segment, that is, the data segment */
. Long 1b
. Text
Vector = vector + 1
. Endr
End (irq_entries_start)
. Previous
End (Interrupt)/* the content of the data segment */
. Previous
It can be summarized:
The above Assembly first declares an interrupt array in the data segment, as shown in the following code:
. Data
Entry (Interrupt)
. Long 1b
End (Interrupt)
The initial value of each element in the array is the address of number 1. Therefore, when accessing elements in the array, the system will jump to level 1 and execute corresponding commands.
There is another detail: Call the set_intr_gate (vector, interrupt [I]) function in i8259_32.c;
The Global interrupt array defined in the data segment in entry_32.s is referenced here. However, the intterrupt array defined in the Data Segment can only be used for connection. This symbol is already defined, the C compiler cannot determine its type and size. Therefore, in hw_irq_32.h, redeclare extern void (* interrupt [nr_irqs]) (void ), in this way, the C compiler determines the type and size of the array.