DRY up IDT
This commit is contained in:
2
about.md
2
about.md
@@ -12,6 +12,8 @@ Minimal examples are useful because it is easier to observe the requirements for
|
||||
|
||||
Another advantage is that it is easier to DRY up minimal examples (here done simply through `#include` and macros), which is much harder on progressive OS template tutorials, which tend to repeat big chunks of code between the examples.
|
||||
|
||||
Using C or not is a hard choice. It does make it much easier to express higher level ideas, and gives portability. But in the end, it increases the complexity that one has to understand, so we've stayed away from it.
|
||||
|
||||
## Pre-requisites
|
||||
|
||||
OS dev is one of the most insanely hard programming tasks a person can undertake, and will push your knowledge of several domains to the limit.
|
||||
|
||||
49
common.h
49
common.h
@@ -457,3 +457,52 @@ loop:
|
||||
add $12, %esp
|
||||
POP_EDAX
|
||||
.endm
|
||||
|
||||
.macro IDT_START
|
||||
idt_start:
|
||||
.endm
|
||||
|
||||
.macro IDT_END
|
||||
idt_end:
|
||||
/* Exact same structure as gdt_descriptor. */
|
||||
idt_descriptor:
|
||||
.word idt_end - idt_start
|
||||
.long idt_start
|
||||
.endm
|
||||
|
||||
.macro IDT_ENTRY
|
||||
/* Low handler address.
|
||||
It is impossible to write:
|
||||
.word (handler & 0x0000FFFF)
|
||||
as we would like:
|
||||
http://stackoverflow.com/questions/18495765/invalid-operands-for-binary-and
|
||||
So this must be done at runtime.
|
||||
*/
|
||||
.word 0
|
||||
/* Segment selector: byte offset into the GDT. */
|
||||
.word CODE_SEG
|
||||
/* Reserved 0. */
|
||||
.byte 0
|
||||
/*
|
||||
Flags. Format:
|
||||
- 1 bit: present. If 0 and this happens, triple fault.
|
||||
- 2 bits: ring level we will be called from.
|
||||
- 5 bits: fixed to 0xE.
|
||||
*/
|
||||
.byte 0x8E
|
||||
/* High word of base. */
|
||||
.word 0
|
||||
.endm
|
||||
|
||||
/*
|
||||
- index: r/m/imm32 Index of the entry to setup.
|
||||
- handler: r/m/imm32 Address of the handler function.
|
||||
*/
|
||||
.macro IDT_SETUP_ENTRY index, handler
|
||||
mov \index, %eax
|
||||
mov \handler, %ebx
|
||||
mov %bx, idt_start(%eax, 8)
|
||||
shr $16, %ebx
|
||||
mov $6, %ecx
|
||||
mov %bx, idt_start(%ecx, %eax, 8)
|
||||
.endm
|
||||
|
||||
31
idt.S
31
idt.S
@@ -7,8 +7,6 @@ Expected output: "a"
|
||||
|
||||
The first 32 handlers are reserved by the processor and have predefined meanings.
|
||||
|
||||
0 is division by zero.
|
||||
|
||||
TODO on Linux kernel.
|
||||
|
||||
## lidt
|
||||
@@ -26,34 +24,13 @@ BEGIN
|
||||
STAGE2
|
||||
CLEAR
|
||||
PROTECTED_MODE
|
||||
IDT_SETUP_ENTRY $0, $handler
|
||||
lidt idt_descriptor
|
||||
int $0
|
||||
jmp .
|
||||
idt_start:
|
||||
/* Low handler address. */
|
||||
/* TODO get this proper version working. */
|
||||
/*.word (handler & 0x0000FFFF)*/
|
||||
.word handler
|
||||
/* Segment selector: byte offset into the GDT. */
|
||||
.word CODE_SEG
|
||||
/* Reserved 0. */
|
||||
.byte 0
|
||||
/*
|
||||
Flags. Format:
|
||||
- 1 bit: present. If 0 and this happens, triple fault.
|
||||
- 2 bits: ring level we will be called from.
|
||||
- 5 bits: fixed to 0xE.
|
||||
*/
|
||||
.byte 0x8E
|
||||
/* High word of base. */
|
||||
/* TODO get this proper version working. */
|
||||
/*.word (handler >> 16) & 0xFFFF*/
|
||||
.word 0
|
||||
idt_end:
|
||||
/* Exact same structure as gdt_descriptor. */
|
||||
idt_descriptor:
|
||||
.word idt_end - idt_start
|
||||
.long idt_start
|
||||
IDT_START
|
||||
IDT_ENTRY
|
||||
IDT_END
|
||||
handler:
|
||||
/* TODO needed? Molloy uses it. */
|
||||
/*cli*/
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
|
||||
Division by zero causes a Divide Error which Intel notes as `#DE`.
|
||||
|
||||
Expected output: "a"
|
||||
|
||||
It is then handled by IDT 0.
|
||||
|
||||
Remember that DE is not *only* for division by zero: it also happens on overflow!
|
||||
Thus the name: Division Error, and not Division by zero.
|
||||
|
||||
@@ -15,6 +19,7 @@ BEGIN
|
||||
STAGE2
|
||||
CLEAR
|
||||
PROTECTED_MODE
|
||||
IDT_SETUP_ENTRY $0, $handler
|
||||
lidt idt_descriptor
|
||||
mov $0, %edx
|
||||
mov $1, %eax
|
||||
@@ -22,17 +27,9 @@ BEGIN
|
||||
/* The iret jumps back here! */
|
||||
div %ecx
|
||||
jmp .
|
||||
/* TODO DRY up with idt.S */
|
||||
idt_start:
|
||||
.word handler
|
||||
.word CODE_SEG
|
||||
.byte 0
|
||||
.byte 0x8E
|
||||
.word 0
|
||||
idt_end:
|
||||
idt_descriptor:
|
||||
.word idt_end - idt_start
|
||||
.long idt_start
|
||||
IDT_START
|
||||
IDT_ENTRY
|
||||
IDT_END
|
||||
handler:
|
||||
VGA_PRINT_STRING $message
|
||||
/* If we don't do this, we get an infinite loop! */
|
||||
|
||||
Reference in New Issue
Block a user