Ok, I really need someone to explain interupts more fully for me... from what I understand, there are a few "inbuilt" hardware interupts on the cpu for exeptions and stuff these are numbered 0 - 30 or something, then the rest are for you to use, and these are like mini-funtions or something, and these are stored in memory and when the CPU gets gets an IRQ/ISR (interupt service request) it saves all the regiseters then goes to the mini-function to handle it, and to know which one to goto it looks up the interupt number in the IDT (interupt descriptor table) for the memory address to goto, so for the general protection fault interupt it would look up the interupt number in the IDT, then goto that mem address to start executing the code, of which you might do a windows and show a message box before crashing the system , then it returns with the iret instruction to go back to what ever the cpu was doing before the interupt... so if you wanted to have your own software interupt you would add a value into the IDT...am I right so far? but how do you know what the interupt number is for like hardware and stuff? like it sends an interupt to tell you the mouse and been moved or the keyboard pressed, but how do you know which interupt gets sent etc for you to write a handler function?
So am I right? any mistakes or corrections you want to make? or explain some of it further for me?
And as I understand, if the CPU can only be executing the one stream of code then how could you have a multi-tasking OS... so am I to understand there is an inbuilt timer interupt which in the handler function would call the shedaler to swap the task? where can I get info on this interupt?
Thanks.
Interupt help...
Re:Interupt help...
ok, looking in the Intel Docs, I see you have you use the APIC to send the timer interrupt, so does anyone have some code on this for me? like to set the countdown time...
Re:Interupt help...
Wow, that's a huge sentence in your first post (I count 9 lines)
Yep, that's correct, except that the CPU won't save most registers for you. If you look at the Intel docs (IIRC under interrupt stack frames) you'll see that, for an interrupt from ring 3 to ring 0, the CPU will save EIP, CS, ESP, SS and EFLAGS, as well as pushing an error code sometimes. You need to save, and restore, everything else, including the general-purpose registers (use PUSHA/POPA), the other segment registers and, optionally, the FPU registers. Note that the CPU doesn't pop the error code on IRET, so you need to do ADD ESP, 4 before you IRET.
The CPU doesn't tell you what interrupt called the code, so you need to write a separate assembly handler stub for each one. Most people automate this in their assembly file using macros, with each one JMP'ing to a common handler, which calls the main interrupt handler. For example, my first 8 interrupt handlers look like this:
_isr_and_switch pushes all the other registers, calls a C handler, switches stacks if necessary, and pops the registers from the new stack (thereby implementing multi-tasking). Note that each interrupt stub pushes the interrupt number onto the stack, as well as a fake error code (exception handlers don't push the error code since the CPU has already pushed it).
Your guess about using the timer interrupt to do multitasking is right. However, in practice you'll only multitask on the timer interrupt if some task is taking too long over some calculations. Most of the time a task will be waiting for user input, so you can switch to some other task when it starts waiting, and switch back when input is available (e.g. when the user presses a key). However, it could happen that all tasks are waiting for input (this will happen most of the time), so you'll need an idle thread to 'suck up' the remaining CPU time. The idle thread's job is to run when no other threads need to.
Usually it's up to the PIT (the 8254 programmable interval timer, not the APIC) to give you an IRQ 0 periodically. The BIOS sets it to run at 18.2Hz, giving you about 50ms between interrupts, but you'll probably want to speed it up a bit. Speed it up too much and you'll find that your scheduler is taking up more CPU time that your threads; slow it down too much and multitasking will be too jerky. 100Hz is a common setting.
Yep, that's correct, except that the CPU won't save most registers for you. If you look at the Intel docs (IIRC under interrupt stack frames) you'll see that, for an interrupt from ring 3 to ring 0, the CPU will save EIP, CS, ESP, SS and EFLAGS, as well as pushing an error code sometimes. You need to save, and restore, everything else, including the general-purpose registers (use PUSHA/POPA), the other segment registers and, optionally, the FPU registers. Note that the CPU doesn't pop the error code on IRET, so you need to do ADD ESP, 4 before you IRET.
The CPU doesn't tell you what interrupt called the code, so you need to write a separate assembly handler stub for each one. Most people automate this in their assembly file using macros, with each one JMP'ing to a common handler, which calls the main interrupt handler. For example, my first 8 interrupt handlers look like this:
Code: Select all
%macro interrupt 1
[global _interrupt_%1]
_interrupt_%1:
push dword 0
push dword 0x%1
jmp _isr_and_switch
align 8
%endmacro
interrupt 0
interrupt 1
interrupt 2
interrupt 3
interrupt 4
interrupt 5
interrupt 6
interrupt 7
Your guess about using the timer interrupt to do multitasking is right. However, in practice you'll only multitask on the timer interrupt if some task is taking too long over some calculations. Most of the time a task will be waiting for user input, so you can switch to some other task when it starts waiting, and switch back when input is available (e.g. when the user presses a key). However, it could happen that all tasks are waiting for input (this will happen most of the time), so you'll need an idle thread to 'suck up' the remaining CPU time. The idle thread's job is to run when no other threads need to.
Usually it's up to the PIT (the 8254 programmable interval timer, not the APIC) to give you an IRQ 0 periodically. The BIOS sets it to run at 18.2Hz, giving you about 50ms between interrupts, but you'll probably want to speed it up a bit. Speed it up too much and you'll find that your scheduler is taking up more CPU time that your threads; slow it down too much and multitasking will be too jerky. 100Hz is a common setting.
Re:Interupt help...
Thanks, so are IRQ's and ISR's the same? or are IRQ's only sent to the APIC/PIC witch you have to remap to the values to above 31 so you can handle them?
Also while im here, I think I need a little bit of register help as well...
eax - general perpose, C function returned values are placed in here... as well as mul using the value in this...
ebx - general perpose... etc
ecx - general perpose... etc
edx - general perpose... etc
ds - data segment, this is a pointer to the mem address of the segment we are executing in...
cs - code segment, im not sure if I get the difference between this and the data segement...
es - extra segement, WTF is this?
ss - stack segment, this is a pointer to the segment where the stack is located, can it be different than the segment we are executing in? and can I change its value etc to like swap stacks or something?
bp - base pointer, points to what? the bottom of the stack for the maximum amount we can use or something?
esi - source index, used for like movs etc
edi - destination index, as above
esp - like the stack segment except its the offset into the stack where we are currently upto, so to switch stacks you would need to change the value of this upto the top...
eip - next instruction pointer, what instructions the processor is executing next...
flags - flags etc...
cr0 - I have read something about this control register... can you give me more info?
Sorry for all my questions... but I need the help... thanks.
Also while im here, I think I need a little bit of register help as well...
eax - general perpose, C function returned values are placed in here... as well as mul using the value in this...
ebx - general perpose... etc
ecx - general perpose... etc
edx - general perpose... etc
ds - data segment, this is a pointer to the mem address of the segment we are executing in...
cs - code segment, im not sure if I get the difference between this and the data segement...
es - extra segement, WTF is this?
ss - stack segment, this is a pointer to the segment where the stack is located, can it be different than the segment we are executing in? and can I change its value etc to like swap stacks or something?
bp - base pointer, points to what? the bottom of the stack for the maximum amount we can use or something?
esi - source index, used for like movs etc
edi - destination index, as above
esp - like the stack segment except its the offset into the stack where we are currently upto, so to switch stacks you would need to change the value of this upto the top...
eip - next instruction pointer, what instructions the processor is executing next...
flags - flags etc...
cr0 - I have read something about this control register... can you give me more info?
Sorry for all my questions... but I need the help... thanks.
Re:Interupt help...
32bit registers: first 16 bit + ax,bx,cx or dxeax - general perpose, C function returned values are placed in here... as well as mul using the value in this...
ebx - general perpose... etc
ecx - general perpose... etc
edx - general perpose... etc
ds - data segment, this is a pointer to the mem address of the segment we are executing in...
cs - code segment, im not sure if I get the difference between this and the data segement...
es - extra segement, WTF is this?
ss - stack segment, this is a pointer to the segment where the stack is located, can it be different than the segment we are executing in? and can I change its value etc to like swap stacks or something?
bp - base pointer, points to what? the bottom of the stack for the maximum amount we can use or something?
esi - source index, used for like movs etc
edi - destination index, as above
esp - like the stack segment except its the offset into the stack where we are currently upto, so to switch stacks you would need to change the value of this upto the top...
eip - next instruction pointer, what instructions the processor is executing next...
flags - flags etc...
cr0 - I have read something about this control register... can you give me more info?
Sorry for all my questions... but I need the help... thanks.
(32bit registers: eax,ebx,ecx,edx)
16bit registers ( 1/2 of the 32 bit registers - last part)
ax,bx,cx,dx
8bit registers:
ax = ah + al
bx = bh + bl
cx = ch + cl
dx = dh + dl
cs/ds: for use of variables
(in section .text or data)
es: extra segment, for if all those other segments are in use....
can store cs,ds stuff I think...
cr0 is a control register for protected mode (max 4 gig of mem),
if set to 1, pmode is enabled.
Re:Interupt help...
IRQs are generated by the hardware: there can be 16 different IRQ lines, and they are actual physical tracks on the motherboard. They get routed to the I/O APIC or the PIC, which translates pulses on the IRQ lines to CPU interrupt numbers, and sends the interrupt number to the CPU. The CPU then executes an interrupt as normal and jumps to the appropriate handler. You need to tell the PIC that you have handled the IRQ by sending it an End-Of-Interrupt (EOI) signal.Thanks, so are IRQ's and ISR's the same? or are IRQ's only sent to the APIC/PIC witch you have to remap to the values to above 31 so you can handle them?
It's possible for more IRQs to come in at the PIC before you send the EOI: if that happens, the lower-priority interrupts get stacked up whereas higher-priority interrupts get let through. For example, you could be handling IRQ 14 when a timer IRQ (IRQ 0) and an IRQ 15 are received. The IRQ 0 will get let through whereas the IRQ 15 won't. However, all IRQs are ignored by the CPU as long as interrupts on the CPU are disabled; the CPU disables interrupts when it enters an interrupt handler and restores them to how they were before (enabled or disabled) on IRET. IIRC, if the CPU receives an IRQ while CPU interrupts are disabled, it will queue it and issue it after interrupts are enabled (e.g. when you do an IRET or STI).
Re:Interupt help...
Ok, a little more help ^_^
If I call int 10h (BIOS video interrupt) to go into mode 13h, hows this? I thought the first ~32 interrupts were reserved...
If I call int 10h (BIOS video interrupt) to go into mode 13h, hows this? I thought the first ~32 interrupts were reserved...
Re:Interupt help...
Intel reserved the first 32 interrupts originally, but when IBM designed the first BIOS they ignored Intel's advice and used interrupts 10h and upwards anyway. This isn't too much of a problem, since most of the reserved interrupts refer to protected mode, where the BIOS isn't used.