Stack Segment Descriptors in Protected Mode

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
zaleschiemilgabriel
Member
Member
Posts: 232
Joined: Mon Feb 04, 2008 3:58 am

Stack Segment Descriptors in Protected Mode

Post 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
User avatar
JAAman
Member
Member
Posts: 879
Joined: Wed Oct 27, 2004 11:00 pm
Location: WA

Re: Stack Segment Descriptors in Protected Mode

Post 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
User avatar
zaleschiemilgabriel
Member
Member
Posts: 232
Joined: Mon Feb 04, 2008 3:58 am

Re: Stack Segment Descriptors in Protected Mode

Post 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...
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Re: Stack Segment Descriptors in Protected Mode

Post 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.
User avatar
zaleschiemilgabriel
Member
Member
Posts: 232
Joined: Mon Feb 04, 2008 3:58 am

Post 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
User avatar
JAAman
Member
Member
Posts: 879
Joined: Wed Oct 27, 2004 11:00 pm
Location: WA

Re: Stack Segment Descriptors in Protected Mode

Post 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)
User avatar
zaleschiemilgabriel
Member
Member
Posts: 232
Joined: Mon Feb 04, 2008 3:58 am

Post by zaleschiemilgabriel »

Is it ok if i set the initial ESP to 0xA0000? That's just below the text-mode video memory.
User avatar
JAAman
Member
Member
Posts: 879
Joined: Wed Oct 27, 2004 11:00 pm
Location: WA

Post 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
User avatar
zaleschiemilgabriel
Member
Member
Posts: 232
Joined: Mon Feb 04, 2008 3:58 am

Post by zaleschiemilgabriel »

Thanks!
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Post 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
Post Reply