Compare commits

...

6 Commits

Author SHA1 Message Date
0xAX 96af2d0f92
Merge pull request #753 from Mutated1994/patch-2
4 years ago
Z 6eda376586
Update linux-initialization-2.md
4 years ago
0xAX fbaf3d8b31
Merge pull request #752 from chaffz/master
4 years ago
wuyuxin af6b5d82b5
Update linux-initialization-2.md
4 years ago
wuyuxin eb6d1204a9
Update contributors.md
4 years ago
wuyuxin 93dd23b65d
Update linux-initialization-2.md
4 years ago

@ -115,7 +115,11 @@ Where:
* `Offset` - is offset to entry point of an interrupt handler;
* `DPL` - Descriptor Privilege Level;
* `P` - Segment Present flag;
* `Segment selector` - a code segment selector in GDT or LDT
* `Segment selector` - a code segment selector in GDT or LDT (actually in linux, it must point to a valid descriptor in your GDT.)
```C
#define __KERNEL_CS (GDT_ENTRY_KERNEL_CS*8) // 0000 0000 0001 0000
#define GDT_ENTRY_KERNEL_CS 2
```
* `IST` - provides ability to switch to a new stack for interrupts handling.
And the last `Type` field describes type of the `IDT` entry. There are three different kinds of gates for interrupts:
@ -164,7 +168,7 @@ where `NUM_EXCEPTION_VECTORS` expands to `32`. As we can see, We're filling only
and inserts an interrupt gate to the `IDT` table which is represented by the `&idt_descr` array.
The `early_idt_handler_array` array is declaredd in the [arch/x86/include/asm/segment.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/segment.h) header file and contains addresses of the first `32` exception handlers:
The `early_idt_handler_array` array is declared in the [arch/x86/include/asm/segment.h](https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/segment.h) header file and contains addresses of the first `32` exception handlers:
```C
#define EARLY_IDT_HANDLER_SIZE 9
@ -332,15 +336,39 @@ Next we save general registers on the stack:
UNWIND_HINT_REGS
```
Okay, now the stack contains following data:
```
High |-------------------------|
| %rflags |
| %cs |
| %rip |
| error code |
| %rdi |
| %rsi |
| %rdx |
| %rax |
| %r8 |
| %r9 |
| %r10 |
| %r11 |
| %rbx |
| %rbp |
| %r12 |
| %r13 |
| %r14 |
| %r15 |<-- %rsp
Low |-------------------------|
```
We need to do it to prevent wrong values of registers when we return from the interrupt handler. After this we check the vector number, and if it is `#PF` or [Page Fault](https://en.wikipedia.org/wiki/Page_fault), we put value from the `cr2` to the `rdi` register and call `early_make_pgtable` (we'll see it soon):
```assembly
cmpq $14,%rsi
cmpq $14,%rsi /* Page fault? */
jnz 10f
GET_CR2_INTO(%rdi)
call early_make_pgtable
andl %eax,%eax
jz 20f
andl %eax,%eax /* It is more efficient, the opcode is shorter than movl 1, %eax, only 2 bytes. */
jz 20f /* All good */
```
otherwise we call `early_fixup_exception` function by passing kernel stack pointer:

@ -131,3 +131,4 @@ Thank you to all contributors:
* [Sebastian Fricke](https://github.com/initBasti)
* [Zhouyi Zhou](https://github.com/zhouzhouyi-hub)
* [Mingzhe Yang](https://github.com/Mutated1994)
* [Yuxin Wu](https://github.com/chaffz)

Loading…
Cancel
Save