flat assembler
Message board for the users of flat assembler.
Index
> OS Construction > The interrupts question |
Author |
|
tantrikwizard 16 Feb 2007, 00:08
Artlav wrote: In short: How interrupt handler can find out which interrupt called it? This is the same as real mode (sort of). Each interrupt has a seperate entry in the IDT starting at 0 to 255. The IDT entry contains the entry to the handler routine. Create a seperate handler routine for each interrupt and you will know which interrupt occured. It doesnt take so much memory, a few dozen bytes per entry at most. Also, all interrupts do not need to be serviced, processor exceptions are the only requirement (i think). You can always mask off hardware IRQs and not service them. Actually, youre not forced to service processor exceptions, but the system will not be very useful without at least process exceptions and IRQ handling. For a fully functional system, you will want a seperate handler to handle each specific interrupt anyway, so is best to create specific functions to handle each interrupt and set the entry points in the IDT. |
|||
16 Feb 2007, 00:08 |
|
Artlav 18 Feb 2007, 18:33
The question is not how to implement it, but how to implement it the most compact way. That is, is there a way to explicitly identify the just-occured software interrupt?
For IRQ's you can get the number of currently processed interrupt by sending 00001011b to 20h/0A0h port (interrupt controller) then reading same port. Is there any similar thing for software interrupts? 104 bytes per TSS, 8 bytes GDT, 8 bytes IDT, and 20 bytes of code for each interrupt, or 140 bytes. Times 256 that's 35Kb. Brute-force way. Or 32 exceptions + 16 IRQ's + service interrupt + dummy for the rest = 4640 bytes. |
|||
18 Feb 2007, 18:33 |
|
tantrikwizard 18 Feb 2007, 20:43
Artlav wrote: The question is not how to implement it, but how to implement it the most compact way. That is, is there a way to explicitly identify the just-occured software interrupt? I'm not sure if the processor informs and ISR that the ISR was invoked. One way is to get the return address from the stack and disassemble the instruction. You cannot escape the need for GDT and IDT entires for your ISR, TSS is optional depending on implementation, so the amount of memory will be the same in these structures regardless of the ISR implementation. The memory requirements for ISRs depend on the ISR implementation. There's a lot of minimal ISR examples running around. try http://osdever.net/bkerndev/index.php for a pretty good minimal implementation. Code: ; Service Routines (ISRs) right here! global _isr0 global _isr1 global _isr2 ... ; Fill in the rest here! global _isr30 global _isr31 ; 0: Divide By Zero Exception _isr0: cli push byte 0 ; A normal ISR stub that pops a dummy error code to keep a ; uniform stack frame push byte 0 jmp isr_common_stub ; 1: Debug Exception _isr1: cli push byte 0 push byte 1 jmp isr_common_stub ... ; Fill in from 2 to 7 here! ; 8: Double Fault Exception (With Error Code!) _isr8: cli push byte 8 ; Note that we DON'T push a value on the stack in this one! ; It pushes one already! Use this type of stub for exceptions ; that pop error codes! jmp isr_common_stub ... ; You should fill in from _isr9 to _isr31 here. Remember to ; use the correct stubs to handle error codes and push dummies! ; We call a C function in here. We need to let the assembler know ; that '_fault_handler' exists in another file extern _fault_handler ; This is our common ISR stub. It saves the processor state, sets ; up for kernel mode segments, calls the C-level fault handler, ; and finally restores the stack frame. isr_common_stub: pusha push ds push es push fs push gs mov ax, 0x10 ; Load the Kernel Data Segment descriptor! mov ds, ax mov es, ax mov fs, ax mov gs, ax mov eax, esp ; Push us the stack push eax mov eax, _fault_handler call eax ; A special call, preserves the 'eip' register pop eax pop gs pop fs pop es pop ds popa add esp, 8 ; Cleans up the pushed error code and pushed ISR number iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP! thats about 25 bytes per interrupt, not a memory hog. |
|||
18 Feb 2007, 20:43 |
|
Artlav 18 Feb 2007, 22:35
tantrikwizard wrote:
That's a good idea. That makes IRQ's and software interrupts covered. Now, what about exceptions? Exception can happen in any part of the code, not only int instruction. Half of them can be covered by checking for error code in the stack (by setting stack empty in the TSS before), still it can't name them. Checking the whole system context may be a solution, but exception interrupt overhead will be too big... |
|||
18 Feb 2007, 22:35 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.