mirror of
https://github.com/cfenollosa/os-tutorial.git
synced 2024-10-27 20:34:19 +00:00
Lesson 23, step 6
This commit is contained in:
parent
d9ee2545da
commit
aa7a78349b
@ -39,6 +39,9 @@ C99 introduces standard fixed-width data types like `uint32_t`
|
|||||||
We need to include `<stdint.h>` which works even in `-ffreestanding` (but requires stdlibs)
|
We need to include `<stdint.h>` which works even in `-ffreestanding` (but requires stdlibs)
|
||||||
and use those data types instead of our own, then delete them on `type.h`
|
and use those data types instead of our own, then delete them on `type.h`
|
||||||
|
|
||||||
|
We also delete the underscores around `__asm__` and `__volatile__` since they aren't needed.
|
||||||
|
|
||||||
|
|
||||||
4. Improperly aligned `kmalloc`
|
4. Improperly aligned `kmalloc`
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
@ -53,12 +56,24 @@ For now, it will always return a new page-aligned memory block.
|
|||||||
5. Missing functions
|
5. Missing functions
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
|
We will implement the missing `mem*` functions in following lessons
|
||||||
|
|
||||||
|
|
||||||
6. Interrupt handlers
|
6. Interrupt handlers
|
||||||
---------------------
|
---------------------
|
||||||
- also cli, sti in interrupt handlers
|
`cli` is redundant, since we already established on the IDT entries if interrupts
|
||||||
|
are enabled within a handler using the `idt_gate_t` flags.
|
||||||
|
|
||||||
|
`sti` is also redundant, as `iret` loads the eflags value from the stack, which contains a
|
||||||
|
bit telling whether interrupts are on or off.
|
||||||
|
In other words the interrupt handler automatically restores interrupts whether or not
|
||||||
|
interrupts were enabled before this interrupt
|
||||||
|
|
||||||
|
|
||||||
7. Structs and attributes
|
On `cpu/isr.h`, `struct registers_t` has a couple issues.
|
||||||
-------------------------
|
First, the alleged `esp` is renamed to `useless`.
|
||||||
|
The value is useless because it has to do with the current stack context, not what was interrupted.
|
||||||
|
Then, we rename `useresp` to `esp`
|
||||||
|
|
||||||
|
Finally, we add `cld` just before `call isr_handler` on `cpu/interrupt.asm`
|
||||||
|
|
||||||
|
@ -13,5 +13,5 @@ void set_idt() {
|
|||||||
idt_reg.base = (uint32_t) &idt;
|
idt_reg.base = (uint32_t) &idt;
|
||||||
idt_reg.limit = IDT_ENTRIES * sizeof(idt_gate_t) - 1;
|
idt_reg.limit = IDT_ENTRIES * sizeof(idt_gate_t) - 1;
|
||||||
/* Don't make the mistake of loading &idt -- always load &idt_reg */
|
/* Don't make the mistake of loading &idt -- always load &idt_reg */
|
||||||
__asm__ __volatile__("lidtl (%0)" : : "r" (&idt_reg));
|
asm volatile("lidtl (%0)" : : "r" (&idt_reg));
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ isr_common_stub:
|
|||||||
mov gs, ax
|
mov gs, ax
|
||||||
|
|
||||||
; 2. Call C handler
|
; 2. Call C handler
|
||||||
|
cld ; C code following the sysV ABI requires DF to be clear on function entry
|
||||||
call isr_handler
|
call isr_handler
|
||||||
|
|
||||||
; 3. Restore state
|
; 3. Restore state
|
||||||
@ -25,7 +26,6 @@ isr_common_stub:
|
|||||||
mov gs, ax
|
mov gs, ax
|
||||||
popa
|
popa
|
||||||
add esp, 8 ; Cleans up the pushed error code and pushed ISR number
|
add esp, 8 ; Cleans up the pushed error code and pushed ISR number
|
||||||
sti
|
|
||||||
iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
|
iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
|
||||||
|
|
||||||
; Common IRQ code. Identical to ISR code except for the 'call'
|
; Common IRQ code. Identical to ISR code except for the 'call'
|
||||||
@ -47,7 +47,6 @@ irq_common_stub:
|
|||||||
mov gs, bx
|
mov gs, bx
|
||||||
popa
|
popa
|
||||||
add esp, 8
|
add esp, 8
|
||||||
sti
|
|
||||||
iret
|
iret
|
||||||
|
|
||||||
; We don't get information about which interrupt was caller
|
; We don't get information about which interrupt was caller
|
||||||
@ -328,97 +327,81 @@ isr31:
|
|||||||
|
|
||||||
; IRQ handlers
|
; IRQ handlers
|
||||||
irq0:
|
irq0:
|
||||||
cli
|
|
||||||
push byte 0
|
push byte 0
|
||||||
push byte 32
|
push byte 32
|
||||||
jmp irq_common_stub
|
jmp irq_common_stub
|
||||||
|
|
||||||
irq1:
|
irq1:
|
||||||
cli
|
|
||||||
push byte 1
|
push byte 1
|
||||||
push byte 33
|
push byte 33
|
||||||
jmp irq_common_stub
|
jmp irq_common_stub
|
||||||
|
|
||||||
irq2:
|
irq2:
|
||||||
cli
|
|
||||||
push byte 2
|
push byte 2
|
||||||
push byte 34
|
push byte 34
|
||||||
jmp irq_common_stub
|
jmp irq_common_stub
|
||||||
|
|
||||||
irq3:
|
irq3:
|
||||||
cli
|
|
||||||
push byte 3
|
push byte 3
|
||||||
push byte 35
|
push byte 35
|
||||||
jmp irq_common_stub
|
jmp irq_common_stub
|
||||||
|
|
||||||
irq4:
|
irq4:
|
||||||
cli
|
|
||||||
push byte 4
|
push byte 4
|
||||||
push byte 36
|
push byte 36
|
||||||
jmp irq_common_stub
|
jmp irq_common_stub
|
||||||
|
|
||||||
irq5:
|
irq5:
|
||||||
cli
|
|
||||||
push byte 5
|
push byte 5
|
||||||
push byte 37
|
push byte 37
|
||||||
jmp irq_common_stub
|
jmp irq_common_stub
|
||||||
|
|
||||||
irq6:
|
irq6:
|
||||||
cli
|
|
||||||
push byte 6
|
push byte 6
|
||||||
push byte 38
|
push byte 38
|
||||||
jmp irq_common_stub
|
jmp irq_common_stub
|
||||||
|
|
||||||
irq7:
|
irq7:
|
||||||
cli
|
|
||||||
push byte 7
|
push byte 7
|
||||||
push byte 39
|
push byte 39
|
||||||
jmp irq_common_stub
|
jmp irq_common_stub
|
||||||
|
|
||||||
irq8:
|
irq8:
|
||||||
cli
|
|
||||||
push byte 8
|
push byte 8
|
||||||
push byte 40
|
push byte 40
|
||||||
jmp irq_common_stub
|
jmp irq_common_stub
|
||||||
|
|
||||||
irq9:
|
irq9:
|
||||||
cli
|
|
||||||
push byte 9
|
push byte 9
|
||||||
push byte 41
|
push byte 41
|
||||||
jmp irq_common_stub
|
jmp irq_common_stub
|
||||||
|
|
||||||
irq10:
|
irq10:
|
||||||
cli
|
|
||||||
push byte 10
|
push byte 10
|
||||||
push byte 42
|
push byte 42
|
||||||
jmp irq_common_stub
|
jmp irq_common_stub
|
||||||
|
|
||||||
irq11:
|
irq11:
|
||||||
cli
|
|
||||||
push byte 11
|
push byte 11
|
||||||
push byte 43
|
push byte 43
|
||||||
jmp irq_common_stub
|
jmp irq_common_stub
|
||||||
|
|
||||||
irq12:
|
irq12:
|
||||||
cli
|
|
||||||
push byte 12
|
push byte 12
|
||||||
push byte 44
|
push byte 44
|
||||||
jmp irq_common_stub
|
jmp irq_common_stub
|
||||||
|
|
||||||
irq13:
|
irq13:
|
||||||
cli
|
|
||||||
push byte 13
|
push byte 13
|
||||||
push byte 45
|
push byte 45
|
||||||
jmp irq_common_stub
|
jmp irq_common_stub
|
||||||
|
|
||||||
irq14:
|
irq14:
|
||||||
cli
|
|
||||||
push byte 14
|
push byte 14
|
||||||
push byte 46
|
push byte 46
|
||||||
jmp irq_common_stub
|
jmp irq_common_stub
|
||||||
|
|
||||||
irq15:
|
irq15:
|
||||||
cli
|
|
||||||
push byte 15
|
push byte 15
|
||||||
push byte 47
|
push byte 47
|
||||||
jmp irq_common_stub
|
jmp irq_common_stub
|
||||||
|
@ -74,9 +74,9 @@ extern void irq15();
|
|||||||
/* Struct which aggregates many registers */
|
/* Struct which aggregates many registers */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t ds; /* Data segment selector */
|
uint32_t ds; /* Data segment selector */
|
||||||
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; /* Pushed by pusha. */
|
uint32_t edi, esi, ebp, useless, ebx, edx, ecx, eax; /* Pushed by pusha. */
|
||||||
uint32_t int_no, err_code; /* Interrupt number and error code (if applicable) */
|
uint32_t int_no, err_code; /* Interrupt number and error code (if applicable) */
|
||||||
uint32_t eip, cs, eflags, useresp, ss; /* Pushed by the processor automatically */
|
uint32_t eip, cs, eflags, esp, ss; /* Pushed by the processor automatically */
|
||||||
} registers_t;
|
} registers_t;
|
||||||
|
|
||||||
void isr_install();
|
void isr_install();
|
||||||
|
@ -13,7 +13,7 @@ uint8_t port_byte_in (uint16_t port) {
|
|||||||
*
|
*
|
||||||
* Inputs and outputs are separated by colons
|
* Inputs and outputs are separated by colons
|
||||||
*/
|
*/
|
||||||
__asm__("in %%dx, %%al" : "=a" (result) : "d" (port));
|
asm("in %%dx, %%al" : "=a" (result) : "d" (port));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,15 +23,15 @@ void port_byte_out (uint16_t port, uint8_t data) {
|
|||||||
* However we see a comma since there are two variables in the input area
|
* However we see a comma since there are two variables in the input area
|
||||||
* and none in the 'return' area
|
* and none in the 'return' area
|
||||||
*/
|
*/
|
||||||
__asm__ __volatile__("out %%al, %%dx" : : "a" (data), "d" (port));
|
asm volatile("out %%al, %%dx" : : "a" (data), "d" (port));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t port_word_in (uint16_t port) {
|
uint16_t port_word_in (uint16_t port) {
|
||||||
uint16_t result;
|
uint16_t result;
|
||||||
__asm__("in %%dx, %%ax" : "=a" (result) : "d" (port));
|
asm("in %%dx, %%ax" : "=a" (result) : "d" (port));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void port_word_out (uint16_t port, uint16_t data) {
|
void port_word_out (uint16_t port, uint16_t data) {
|
||||||
__asm__ __volatile__("out %%ax, %%dx" : : "a" (data), "d" (port));
|
asm volatile("out %%ax, %%dx" : : "a" (data), "d" (port));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user