Kernel stacks, saving registers, etc.
Posted: Mon Jul 21, 2003 4:26 am
I can't find any clear "kernel stacks for dummies" articles on the web. It looks simple enough, but I can't confess to understanding the purpose of this in boilerplate ASM code for a Linux userland application (I'll get to the kernel stacks in a moment):
[SECTION .text]
global main
main:
push ebp
mov ebp, esp
push ebx
push esi
push edi
... stuff ...
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret
....
This is apparently what the C library startup and control-returning code expects. You setup a stack frame in such a way and preserve the calling code's EBP, then make use of ESP through EBP. But why are EBX, ESI and EDI pushed onto the stack for a stack frame after EBP is saved? I thought everything was supposed to be between EBP and ESP, hence the name Base in Base Pointer. E.g.
EBP [mem] [mem] [mem] [mem] .... [mem] ESP
So is this a C library thing (why on earth? I'm not using the C library, however I will use Linux syscalls, which are written in C but with args passed mostly through registers... so wouldn't this mean normal C stack frame stuff isn't applicable?)
Getting to the kernel stack, what are the essential things to save when switching stacks between kernel, interrupt and user stacks? If applications used fp, wouldn't the fp registers need to be saved? Or are they already saved in a sense, since the fp registers are kind of stacky things?
I am thinking of using MicroC OS II as base code to build on, because it's small and beautiful. I can understand the code... I will be taking it and experimenting for educational purposes, e.g. adding paging, syscalls, that sort of do. Is this a good kernel to start from? Please check it out: http://www.ucos-ii.com. Please look at the Intel/AMD 32-bit protected mode flat model port.
I don't quite "get" kernel and interrupt stacks, I mean, I understand what they are for and so on, but the details of switching between them and what goes in a stack frame and the EBP...ESP business trips me up. Everything I have read so far seems vague. Is it vague because I can do whatever the hell I like with those stacks, as long as I store the essentials on them? (In other words, there are many ways to skin a cat or make a stack? No one way is strictly correct, excepting saving state in task switching?)
Now, Intel hardware has the TSS and provides hardware for task switching. I think I may as well use it. Will this make my job easier?
Now to interrupt stacks. What's the deal with these stacks, what MUST go there and what can optionally go there, and I need more examples of ISRs.... any links appreciated. (Again, is MicroC OS II a good starting point?)
Eesh, writing an OS from scratch is much harder than modifying the C sources of an existing OS... C is so.. so high level...
Many Thanks...
[SECTION .text]
global main
main:
push ebp
mov ebp, esp
push ebx
push esi
push edi
... stuff ...
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret
....
This is apparently what the C library startup and control-returning code expects. You setup a stack frame in such a way and preserve the calling code's EBP, then make use of ESP through EBP. But why are EBX, ESI and EDI pushed onto the stack for a stack frame after EBP is saved? I thought everything was supposed to be between EBP and ESP, hence the name Base in Base Pointer. E.g.
EBP [mem] [mem] [mem] [mem] .... [mem] ESP
So is this a C library thing (why on earth? I'm not using the C library, however I will use Linux syscalls, which are written in C but with args passed mostly through registers... so wouldn't this mean normal C stack frame stuff isn't applicable?)
Getting to the kernel stack, what are the essential things to save when switching stacks between kernel, interrupt and user stacks? If applications used fp, wouldn't the fp registers need to be saved? Or are they already saved in a sense, since the fp registers are kind of stacky things?
I am thinking of using MicroC OS II as base code to build on, because it's small and beautiful. I can understand the code... I will be taking it and experimenting for educational purposes, e.g. adding paging, syscalls, that sort of do. Is this a good kernel to start from? Please check it out: http://www.ucos-ii.com. Please look at the Intel/AMD 32-bit protected mode flat model port.
I don't quite "get" kernel and interrupt stacks, I mean, I understand what they are for and so on, but the details of switching between them and what goes in a stack frame and the EBP...ESP business trips me up. Everything I have read so far seems vague. Is it vague because I can do whatever the hell I like with those stacks, as long as I store the essentials on them? (In other words, there are many ways to skin a cat or make a stack? No one way is strictly correct, excepting saving state in task switching?)
Now, Intel hardware has the TSS and provides hardware for task switching. I think I may as well use it. Will this make my job easier?
Now to interrupt stacks. What's the deal with these stacks, what MUST go there and what can optionally go there, and I need more examples of ISRs.... any links appreciated. (Again, is MicroC OS II a good starting point?)
Eesh, writing an OS from scratch is much harder than modifying the C sources of an existing OS... C is so.. so high level...
Many Thanks...