x86 Segmentation/Paging + OS Plans
Re:x86 Segmentation/Paging + OS Plans
Did you forget SS or does the CPU do that automagically as well?
Now I think I can start programming this thing, one problem what do I call the folder with the source in, I havn't got a new name yet!!!
And it doesn't matter if this int handler is run by IRQ0 or one of the quick RTC interrupts does it?
Pete
Now I think I can start programming this thing, one problem what do I call the folder with the source in, I havn't got a new name yet!!!
And it doesn't matter if this int handler is run by IRQ0 or one of the quick RTC interrupts does it?
Pete
Re:x86 Segmentation/Paging + OS Plans
Yep, the CPU does SS3 and ESP3 as well. Remember that the CPU switches to the ring 0 stack before pushing all this.Therx wrote:Did you forget SS or does the CPU do that automagically as well?
No, but you probably won't need the RTC for this. Quantum expiry -- that is, switching tasks because one task has been running continously for too long -- doesn't need to happen often.And it doesn't matter if this int handler is run by IRQ0 or one of the quick RTC interrupts does it?
Re:x86 Segmentation/Paging + OS Plans
Slightly confused on format of segment selectors
In Intel doc it says:-
[table][tr][td]7 6 5 4 3[/td][td]2[/td][td]1 0[/td][/tr]
[tr][td]Index[/td][td]0=GDT/1=LDT[/td][td]RPL[/td][/tr][/table]
Yet it the OSD examples it sets DS as GDT_CODE
where GDT_CODE is defined as GDT_CODE equ $-gdt_start. Which doesn't seem right to me.
If I need to use a GDT entry other than this assembly file do the indexes start at 0 or 1
In Intel doc it says:-
[table][tr][td]7 6 5 4 3[/td][td]2[/td][td]1 0[/td][/tr]
[tr][td]Index[/td][td]0=GDT/1=LDT[/td][td]RPL[/td][/tr][/table]
Yet it the OSD examples it sets DS as GDT_CODE
where GDT_CODE is defined as GDT_CODE equ $-gdt_start. Which doesn't seem right to me.
If I need to use a GDT entry other than this assembly file do the indexes start at 0 or 1
Re:x86 Segmentation/Paging + OS Plans
Sorry I understand. You can take the offset as the segent selector because the entries are 8 bytes and that is the equivilant of shifting the index left 3 places and setting the ring to 0 and table to GDT
Re: Software Multitasking
I haven't tested all this yet but from reading the Intel manual I can see a problem. Apparently when the interrupt handler is loaded it only pushs/pops ESP and SS on entering if it is changing ring. What if one task is ring 0 and the other ring 3.
Ring 0 -> Interrupt (doesn't push/pop ESP or SS) -> Ring 3 -> Interrupt (tries to pop SS and ESP off ring 0 task stack but they're not there) -> ERROR
This would also cause a problem when adding a task
Pete
Ring 0 -> Interrupt (doesn't push/pop ESP or SS) -> Ring 3 -> Interrupt (tries to pop SS and ESP off ring 0 task stack but they're not there) -> ERROR
This would also cause a problem when adding a task
Pete
Re:x86 Segmentation/Paging + OS Plans
I don't understand your question.
Here's what the four different protected mode x86 stack frames look like: (from the text-format 386 manual, 386intel.txt)
[tt]Figure 9-5. Stack Layout after Exception of Interrupt
WITHOUT PRIVILEGE TRANSITION
D O 31 0 31 0
I F ?---------------? ?---------------?
R ????????????????? OLD ????????????????? OLD
E E ?-------+-------? SS:ESP ?-------+-------? SS:ESP
C X ????????????????? ? ????????????????? ?
T P ?---------------??----+ ?---------------??----+
I A ? OLD EFLAGS ? ? OLD EFLAGS ?
O N ?---------------? ?---------------?
N S ?????????OLD CS ? NEW ?????????OLD CS ?
I ?---------------? SS:ESP ?---------------?
? O ? OLD EIP ? ? ? OLD EIP ? NEW
? N ?---------------??----+ ?---------------? SS:ESP
? ? ? ? ERROR CODE ? ?
? ? ? ?---------------??----+
? ? ? ?
? ?
WITHOUT ERROR CODE WITH ERROR CODE
WITH PRIVILEGE TRANSITION
D O 31 0 31 0
I F +---------------+?----+ +---------------+?----+
R ?????????OLD SS ? ? ?????????OLD SS ? ?
E E ?---------------? SS:ESP ?---------------? SS:ESP
C X ? OLD ESP ? FROM TSS ? OLD ESP ? FROM TSS
T P ?---------------? ?---------------?
I A ? OLD EFLAGS ? ? OLD EFLAGS ?
O N ?---------------? ?---------------?
N S ?????????OLD CS ? NEW ?????????OLD CS ?
I ?---------------? SS:EIP ?---------------?
? O ? OLD EIP ? ? ? OLD EIP ? NEW
? N ?---------------??----+ ?---------------? SS:ESP
? ? ? ? ERROR CODE ? ?
? ? ? ?---------------??----+
? ? ? ?
? ?
WITHOUT ERROR CODE WITH ERROR CODE[/tt]
(apologies for the formatting; it looks much better in Unicode)
The CPU will use one of the top two formats when an interrupt occurs in ring 0, and one of the bottom two when an interrupt occurs in ring 3. (Things get slightly different for V86 mode.)
As you can see:
[x] CS:EIP and EFLAGS always get pushed
[x] SS3:ESP3 get pushed for a privilege level transition
[x] An error code gets pushed for some exceptions (see the manual for details)
I don't think it's possible to have an interrupt go to a less-privileged ring.
Here's what the four different protected mode x86 stack frames look like: (from the text-format 386 manual, 386intel.txt)
[tt]Figure 9-5. Stack Layout after Exception of Interrupt
WITHOUT PRIVILEGE TRANSITION
D O 31 0 31 0
I F ?---------------? ?---------------?
R ????????????????? OLD ????????????????? OLD
E E ?-------+-------? SS:ESP ?-------+-------? SS:ESP
C X ????????????????? ? ????????????????? ?
T P ?---------------??----+ ?---------------??----+
I A ? OLD EFLAGS ? ? OLD EFLAGS ?
O N ?---------------? ?---------------?
N S ?????????OLD CS ? NEW ?????????OLD CS ?
I ?---------------? SS:ESP ?---------------?
? O ? OLD EIP ? ? ? OLD EIP ? NEW
? N ?---------------??----+ ?---------------? SS:ESP
? ? ? ? ERROR CODE ? ?
? ? ? ?---------------??----+
? ? ? ?
? ?
WITHOUT ERROR CODE WITH ERROR CODE
WITH PRIVILEGE TRANSITION
D O 31 0 31 0
I F +---------------+?----+ +---------------+?----+
R ?????????OLD SS ? ? ?????????OLD SS ? ?
E E ?---------------? SS:ESP ?---------------? SS:ESP
C X ? OLD ESP ? FROM TSS ? OLD ESP ? FROM TSS
T P ?---------------? ?---------------?
I A ? OLD EFLAGS ? ? OLD EFLAGS ?
O N ?---------------? ?---------------?
N S ?????????OLD CS ? NEW ?????????OLD CS ?
I ?---------------? SS:EIP ?---------------?
? O ? OLD EIP ? ? ? OLD EIP ? NEW
? N ?---------------??----+ ?---------------? SS:ESP
? ? ? ? ERROR CODE ? ?
? ? ? ?---------------??----+
? ? ? ?
? ?
WITHOUT ERROR CODE WITH ERROR CODE[/tt]
(apologies for the formatting; it looks much better in Unicode)
The CPU will use one of the top two formats when an interrupt occurs in ring 0, and one of the bottom two when an interrupt occurs in ring 3. (Things get slightly different for V86 mode.)
As you can see:
[x] CS:EIP and EFLAGS always get pushed
[x] SS3:ESP3 get pushed for a privilege level transition
[x] An error code gets pushed for some exceptions (see the manual for details)
I don't think it's possible to have an interrupt go to a less-privileged ring.
Re:x86 Segmentation/Paging + OS Plans
What I'm saying is that when a ring 0 task is saved it won't have SS or ESP saved. Then a ring 3 task is saved (ie the ring changes) and they are not saved (SS and ESP) and when is returns from that interrupt changing back to ring 0 task it will try to restore SS and ESP even though they don't exist.
Does that make sense?
Pete
Does that make sense?
Pete
Re:x86 Segmentation/Paging + OS Plans
I don't know. I also don't how to describe this. Here's another go
Ring 0 Task
|
Don't push SS, ESP
|
Task Switch to ring 3 task
|
Don't pop SS, ESP
|
Ring 3 Task
|
Push SS, ESP
|
Task Switch to ring 0 task
|
Pop SS, ESP
|
ERROR SS and ESP aren't on the ring 0 stack
Pete
Ring 0 Task
|
Don't push SS, ESP
|
Task Switch to ring 3 task
|
Don't pop SS, ESP
|
Ring 3 Task
|
Push SS, ESP
|
Task Switch to ring 0 task
|
Pop SS, ESP
|
ERROR SS and ESP aren't on the ring 0 stack
Pete
Re:x86 Segmentation/Paging + OS Plans
Ahhh... maybe you've misunderstood. The CPU looks at what's on the stack as it's popping to make sure it pops the right registers.
Ring 0 Task
|
Don't push SS, ESP
|
Task Switch to ring 3 task
|
(IRET) Pop SS, ESP, because the CS on the stack is ring 3
|
Ring 3 Task
|
(INT) Push SS, ESP
|
Task Switch to ring 0 task
|
(IRET) Don't pop SS, ESP, because the CS on the stack is ring 0
Ring 0 Task
|
Don't push SS, ESP
|
Task Switch to ring 3 task
|
(IRET) Pop SS, ESP, because the CS on the stack is ring 3
|
Ring 3 Task
|
(INT) Push SS, ESP
|
Task Switch to ring 0 task
|
(IRET) Don't pop SS, ESP, because the CS on the stack is ring 0
Re:x86 Segmentation/Paging + OS Plans
Ah ok, that explains. So when I add a task. I should do something like
move ALLOCATED STACK TOP -> esp
if (new task is ring 3){
push SS
push ESP
}
push EFLAGS
push ring 3 code selector
push task address (EIP)
and then all the other things covered by previous posts.
move ALLOCATED STACK TOP -> esp
if (new task is ring 3){
push SS
push ESP
}
push EFLAGS
push ring 3 code selector
push task address (EIP)
and then all the other things covered by previous posts.
-
- Member
- Posts: 1600
- Joined: Wed Oct 18, 2006 11:59 am
- Location: Vienna/Austria
- Contact:
Re:x86 Segmentation/Paging + OS Plans
lets give it a try...
Pete, if you have setup your interrupt stubs (ie save_state, restore_state) in a proper way, they do their job *regardless* of the privilege level of the task you switch from/to. the mechanism is laid out to work this way.
Nested interrupts: You have a variable somewhere. If any interrupt is triggered whilst execution of an other isr, you check this variable. Only for ONE time, you have to save off task states/switch to a dedicated kernel stack. Every further interrupt after the first one is to be executed on this kernel stack. you have to mask each irq line which is served by the isr and unmask it when the isr has finished execution. You can nest irq's up to the maximum of available irq lines. when every irq line is masked, no further irq will be recognized/triggered.
your sorrow about privilege level changes: tim has explained it in an excellent manner. Here I describe in words, what happens on a int/iret:
ring3/ring0/ring3 change:
upon int, cpu switches to the stack indicated in esp0/ss0 field in the system tss, pushes ss,esp,eflags,eip,cs on the stack without further instruction. after that, you have to push segment registers and other registers in isr prologue (save_state)
before iret, in the epilogue (restore_state), you pop the registers off the actual ring0 stack (you have to switch to it in restore_state), then issue iret. this command pops off: cs,eip,eflags,ss,esp. so you see, automatically, the user stack is the stack in use.
when interrupting a ring0 task (same privilege level ) no ss and esp are pushed - look at Tims explanation.
You see, you don't need to worry too much about it. the cpu knows what to do at ?least with *this* nitty gritty.
ps: have received your mail. thank you. I should point out this possibilities you have remarked too. You are right. I just took the code examples from my os project.
Pete, if you have setup your interrupt stubs (ie save_state, restore_state) in a proper way, they do their job *regardless* of the privilege level of the task you switch from/to. the mechanism is laid out to work this way.
Nested interrupts: You have a variable somewhere. If any interrupt is triggered whilst execution of an other isr, you check this variable. Only for ONE time, you have to save off task states/switch to a dedicated kernel stack. Every further interrupt after the first one is to be executed on this kernel stack. you have to mask each irq line which is served by the isr and unmask it when the isr has finished execution. You can nest irq's up to the maximum of available irq lines. when every irq line is masked, no further irq will be recognized/triggered.
your sorrow about privilege level changes: tim has explained it in an excellent manner. Here I describe in words, what happens on a int/iret:
ring3/ring0/ring3 change:
upon int, cpu switches to the stack indicated in esp0/ss0 field in the system tss, pushes ss,esp,eflags,eip,cs on the stack without further instruction. after that, you have to push segment registers and other registers in isr prologue (save_state)
before iret, in the epilogue (restore_state), you pop the registers off the actual ring0 stack (you have to switch to it in restore_state), then issue iret. this command pops off: cs,eip,eflags,ss,esp. so you see, automatically, the user stack is the stack in use.
when interrupting a ring0 task (same privilege level ) no ss and esp are pushed - look at Tims explanation.
You see, you don't need to worry too much about it. the cpu knows what to do at ?least with *this* nitty gritty.
ps: have received your mail. thank you. I should point out this possibilities you have remarked too. You are right. I just took the code examples from my os project.
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
BlueillusionOS iso image
Re:x86 Segmentation/Paging + OS Plans
Yeh thanks I'm clear on it now.
I never sent no mail, did I?ps: have received your mail. thank you. I should point out this possibilities you have remarked too. You are right. I just took the code examples from my os project.