Page 1 of 1

Stack Segment Descriptors in Protected Mode

Posted: Tue Mar 18, 2008 8:27 am
by zaleschiemilgabriel
http://www.csee.umbc.edu/~plusquel/310/ ... arch2.html
I've been trying to decipher what it says on that page about stack segment descriptors, so I can use it in my GDT:

Code: Select all

    *  Type=2 or 3: A stack segment is defined analogously to Types 0 and 1.

 

          o However, the interpretation of the limit field is different.
                + In this case, all offsets must be greater than the limit.
                + The upper limit is set to base address + FFFF (with D=0) or base address + FFFFFFFF (with D=1).

 

          o This means the stack segment ends 1 byte below the base address.

 

          o Expanding of the stack segment simply involves decreasing the limit.
I've tried all kinds of values for the BASE and LIMIT addresses, but I just can't get the stack to work without causing a triple-fault.
Here's my current GDT entry for the stack segment:

Code: Select all

SYS_STACK_SEL   = $-gdt
gdt4:   dq      00CF96000000FFFFh       ; limit 0xFFFFF; base 0; present, ring 0, stack, expand-down, writable; page-granular, 32-bit
I want to create the segment so that it takes up the entire 4 GB address space and then set ESP to wherever I want. Also, I would like some help with initializing SS and ESP.
If using the entire address space is not possible (only conceptually, because physically I'll never be able to use that much memory), how do I initialize (what values do I need for) the descriptor entry so that the stack it describes expands from physical address 0x80000 to 0x90000 (so that I get 16384 DWORD-sized stack entries).
I know I could just define a normal data segment and use it as a stack, but that has some protection issues if you set ESP to 0. I don't understand what expand-down segments are and how they are supposed to be used, and that link doesn't help much.

Thanks,

Gabriel

Re: Stack Segment Descriptors in Protected Mode

Posted: Tue Mar 18, 2008 10:41 am
by JAAman
zaleschiemilgabriel wrote: I know I could just define a normal data segment and use it as a stack,
that is the normal way to do it
but that has some protection issues if you set ESP to 0.
not sure why you would set it to 0 anyway...
I don't understand what expand-down segments are and how they are supposed to be used, and that link doesn't help much.
basically, the difference between expand-up and expand-down, is whether the base is the top or bottom of the segment

for example:

if you have a base of 0x10000 and a limit of 0x10000, with expand-up, your range covers 0x10000-0x20000

if you have those same values for an expand-down segment, your range will be 0x0-0x10000 -- so, by changing the limit of an expand-up segment, you are changing the highest addressable location, where changing the limit of an expand-down segment, you are changing the lowest addressable location

as the stack 'grows' it grows downward starting at the highest address, and each time something is placed on the stack, the stack pointer is decreased, to point the next entry to a lower address, by using an expand-down segment, you can increase the lower limit of the segment by altering the limit, without modifying the base, allowing you to increase the amount of space available to the stack (this is only important if you intend to change the stack segment at runtime -- if you are using a flat model, where your stack segment covers the entire address range, you dont need to worry about this)

-- reference: 3A:3.4.5.1 (primarily paragraph 3 in revision 019US)
I want to create the segment so that it takes up the entire 4 GB address space and then set ESP to wherever I want
that is the normal way to do it -- just create a single data segment for each ring you use, and it should work just fine



hope this helps you

Re: Stack Segment Descriptors in Protected Mode

Posted: Wed Mar 19, 2008 3:47 am
by zaleschiemilgabriel
JAAman wrote:if you are using a flat model, where your stack segment covers the entire address range, you dont need to worry about this
On the contrary, this is exactly what I'm worrying about. If, for example, I set SS to point to such a segment and I set ESP to 4*256, every push will overwrite the real mode interrupt table. Also, something weird happens if I set ESP to the value 4 and then just do 2 PUSHes on the stack: The ESP now points to 0xFFFFFFFC, without causing any exception. I would expect an exception to arise if the stack is filled up...

Re: Stack Segment Descriptors in Protected Mode

Posted: Wed Mar 19, 2008 3:55 am
by JamesM
zaleschiemilgabriel wrote:
JAAman wrote:if you are using a flat model, where your stack segment covers the entire address range, you dont need to worry about this
On the contrary, this is exactly what I'm worrying about. If, for example, I set SS to point to such a segment and I set ESP to 4*256, every push will overwrite the real mode interrupt table. Also, something weird happens if I set ESP to the value 4 and then just do 2 PUSHes on the stack: The ESP now points to 0xFFFFFFFC, without causing any exception. I would expect an exception to arise if the stack is filled up...
Unfortunately not, if your base is 0 and your limit 0xFFFFFFFF, there can never be a value (32-bit) which is not in this range. Thus, you would never get a segv exception.

What you are 'worried about' can easily be implemented using paging, using nonpresent pages / supervisor only pages. In most cases, paging can be used instead of segmentation - the one biggest exception being subpage granularity protection.

Posted: Wed Mar 19, 2008 5:50 am
by zaleschiemilgabriel
So I should get paging enabled early on in the kernel. I thought I could get the kernel to run on physical memory and enable paging later, only for user tasks... I understand now. I expected the PUSH/CALL instructions to check for a NULL ESP before decreasing it. I guess I was wrong.

Thanks for all the useful answers!

One more thing that has been making me wonder lately are relocatable modules. Say that I have a module that can load other modules' code/data segments into it's own address space (then the modules can access each other's data). If any of the loaded modules have overlapping segments, they need to be relocated. Is there any standard way of doing this?

Cheers,
Gabriel

Re: Stack Segment Descriptors in Protected Mode

Posted: Wed Mar 19, 2008 8:47 am
by JAAman
On the contrary, this is exactly what I'm worrying about. If, for example, I set SS to point to such a segment and I set ESP to 4*256, every push will overwrite the real mode interrupt table. Also, something weird happens if I set ESP to the value 4 and then just do 2 PUSHes on the stack: The ESP now points to 0xFFFFFFFC, without causing any exception. I would expect an exception to arise if the stack is filled up...
this has nothing to do with expand-up vs. expand-down segments (which is the question i was responding to when i said it doesnt matter if your using a flat segment)


but as was mentioned, paging with help to prevent this problem
So I should get paging enabled early on in the kernel. I thought I could get the kernel to run on physical memory and enable paging later, only for user tasks...
you either use paging or you dont -- while it is possible to enable and disable paging constantly, it would be much more complicated, and have much worse performance, with no real benefit (the best benefit of paging, is you dont need to worry about where in physical memory your code/data is located)

Posted: Wed Mar 19, 2008 9:01 am
by zaleschiemilgabriel
Is it ok if i set the initial ESP to 0xA0000? That's just below the text-mode video memory.

Posted: Wed Mar 19, 2008 9:19 am
by JAAman
zaleschiemilgabriel wrote:Is it ok if i set the initial ESP to 0xA0000? That's just below the text-mode video memory.
while that might be acceptable on some computers, there is an extended BIOS data area located at that address you may need to be careful of... idk, someone else maybe can tell you whats in it and whether it needs to be preserved, but its there

for my system, i place my initial RMode stack below the bootsector (i set SP to 0x7C00), and i never use any memory above 0x8_0000 which should keep me safe without having to worry about how much is reserved for the EBDA

Posted: Thu Mar 20, 2008 5:02 am
by zaleschiemilgabriel
Thanks!

Posted: Thu Mar 20, 2008 5:20 am
by jal
zaleschiemilgabriel wrote:One more thing that has been making me wonder lately are relocatable modules.
Don't hijack the thread. Start a new thread if you want it answered.


JAL