Expand down stack segment setting on x86

Discussions on more advanced topics such as monolithic vs micro-kernels, transactional memory models, and paging vs segmentation should go here. Use this forum to expand and improve the wiki!
Post Reply
RajivKumarSrivastav
Member
Member
Posts: 26
Joined: Wed Sep 28, 2011 6:46 am
Location: Bangalore - India

Expand down stack segment setting on x86

Post by RajivKumarSrivastav »

Hi All,

I got stuck in setting the base & limit for stack protection :( .
Can some one explain the idea of Expand down stack segment please? I dont get enough information from Intel's System Programming Guide 1.
I want to use expand down stack from address 0xffff,0000 to 0xfffe,0000 ( 64KB) in kernel mode. G (Granularity flag) bit is set to 1 for 4KB increments.
D/B is 1, making operation size as 32 bit pointer.
What should be the value of Segment Descriptor for Stack segment with above required information? Is it related with Real & Protected mode?

Code: Select all

void Init_MicroKernel(){                // entry function for kernel 
gdt_install();  // 1st line in this function
 
}
void setkgdt(uint32 index, uint16 low, uint8 mid, uint8 high, uint16 limit, uint8 access, uint8 gran) {
   kgdt[index].seglimit = limit;
   kgdt[index].lowbase = low;
   kgdt[index].midbase = mid;
   kgdt[index].access = access;
   kgdt[index].granularity = gran;
   kgdt[index].highbase = high;
}

void gdt_install() {
   desc gdtp;   
   setkgdt(0, 0, 0, 0, 0, 0, 0);
   setkgdt(1, 0, 0, 0, 0xFFFF, 0x9B, 0xCF);  // code at 0x8
   setkgdt(2, 0, 0, 0, 0xFFFF, 0x93, 0xCF);   // data
   setkgdt(3, 0x0, 0xFF, 0xFF, 0xFFFD, 0x97, 0xCF); // stack
   setkgdt(4, 0, 0, 0, 0, 0, 0); 
  
   gdtp.limit = (sizeof (gdt_entry) * MAX_GDT_ENTRIES) - 1;
   gdtp.base = (uint32)kgdt;
   InstallGdt((uint32)&gdtp);
}
InstallGdt:
        mov 4(%esp), %eax
        lgdt (%eax)
        mov $DATA_SEL, %ax  /* DATA_SEL  equals =0x10 */
        mov %ax, %ds
        mov %ax, %ss
        mov %ax, %es
        mov %ax, %fs
        mov %ax, %gs
        .byte  0xEA
        .long  done
        .word  CODE_SEL  /* CODE_SEL  equals =0x8 */
done:
        ret

Please reply soon.....

Thanks
Last edited by RajivKumarSrivastav on Wed Sep 28, 2011 8:05 am, edited 1 time in total.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Expand down stack segment setting on x86

Post by Combuster »

If you have to post code, use

Code: Select all

 tags as per the forum rules, but right now I don't even see the relevance of code related to your question. :shock: 

Second problem: I went looking for the definition of [url=http://www.google.com/search?client=ubuntu&channel=fs&q=expand+down+segment&ie=utf-8&oe=utf-8]expand down segment[/url]s and noticed you didn't STFW either since the first link gave quite an elaborate explanation including examples.


Please follow the forum rules, they exist for a reason (your protection from bullies and moderators included).
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
RajivKumarSrivastav
Member
Member
Posts: 26
Joined: Wed Sep 28, 2011 6:46 am
Location: Bangalore - India

Re: Expand down stack segment setting on x86

Post by RajivKumarSrivastav »

Thanks for the suggestion.
Expand down segment search from google did not give me the information i need. Those are theory mostly without example for stack :( . The first link explanation did not work for me :cry: .

Boot.s has the reset vector code, temp IDT, temp GDT and then jump to kernel entry after necessary initialization .
I have posted the complete code for setting the GDT inside Kernel.
I want to know the exact working combination for line :
setkgdt(3, 0x0, 0xFF, 0xFF, 0xFFFD, 0x97, 0xCF); // stack


Thanks,
User avatar
Chandra
Member
Member
Posts: 487
Joined: Sat Jul 17, 2010 12:45 am

Re: Expand down stack segment setting on x86

Post by Chandra »

Intel's Manual wrote:For all types of segments except expand-down data segments, the value of the limit is one less than the size (expressed in bytes) of the segment. The
processor causes a general-protection exception in any of these cases:

þ Attempt to access a memory byte at an address > limit.
þ Attempt to access a memory word at an address òlimit.
þ Attempt to access a memory doubleword at an address ò(limit-2).

For expand-down data segments, the limit has the same function but is
interpreted differently. In these cases the range of valid addresses is from
limit + 1 to either 64K or 2^(32) - 1 (4 Gbytes) depending on the B-bit. An
expand-down segment has maximum size when the limit is zero.


The expand-down feature makes it possible to expand the size of a stack by
copying it to a larger segment without needing also to update intrastack
pointers.

The limit field of descriptors for descriptor tables is used by the
processor to prevent programs from selecting a table entry outside the
descriptor table. The limit of a descriptor table identifies the last valid
byte of the last descriptor in the table. Since each descriptor is eight
bytes long, the limit value is N * 8 - 1 for a table that can contain up to
N descriptors.

Limit checking catches programming errors such as runaway subscripts and
invalid pointer calculations. Such errors are detected when they occur, so
that identification of the cause is easier. Without limit checking, such
errors could corrupt other modules; the existence of such errors would not
be discovered until later, when the corrupted module behaves incorrectly,
and when identification of the cause is difficult.


Table 6-2. Useful Combinations of E, G, and B Bits (which is unfortunately misaligned while posting. Please read the official Manual for the insight)


Case: 1 2 3 4

Expansion Direction U U D D
G-bit 0 1 0 1
B-bit X X 0 1

Lower bound is:
0 X X
LIMIT+1 X
shl(LIMIT,12,1)+1 X

Upper bound is:
LIMIT X
shl(LIMIT,12,1) X
64K-1 X
4G-1 X

Max seg size is:
64K X
64K-1 X
4G-4K X
4G X

Min seg size is:
0 X X
4K X X


shl (X, 12, 1) = shift X left by 12 bits inserting one-bits on the right
That's all the information you need.
Programming is not about using a language to solve a problem, it's about using logic to find a solution !
User avatar
Chandra
Member
Member
Posts: 487
Joined: Sat Jul 17, 2010 12:45 am

Re: Expand down stack segment setting on x86

Post by Chandra »

rajiv123 wrote:I want to use expand down stack from address 0xffff,0000 to 0xfffe,0000 ( 64KB) in kernel mode. G (Granularity flag) bit is set to 1 for 4KB increments.

Code: Select all

void setkgdt(uint32 index, uint16 low, uint8 mid, uint8 high, uint16 limit, uint8 access, uint8 gran)

Code: Select all

setkgdt(3, 0x0, 0xFF, 0xFF, 0xFFFD, 0x97, 0xCF); // stack
That looks terribly wrong. The limit you're passing as a parameter for the stack segment is 0xFFFd. Add higher 4 bits from the granularity field (0xF) to the limit and this gives the segment limit of 0xFFFFd*1024*4Kb = 0xFFFFD000, which is obviously not what you wanted. Moreover, you're treating the fields as if it were expand-up segment. Intel's Manual says that the expand-down segment has maximum size when limit is 0. The whole segment mechanism works slightly in reverse order. Please read the Manual carefully.
Programming is not about using a language to solve a problem, it's about using logic to find a solution !
RajivKumarSrivastav
Member
Member
Posts: 26
Joined: Wed Sep 28, 2011 6:46 am
Location: Bangalore - India

Re: Expand down stack segment setting on x86

Post by RajivKumarSrivastav »

Thanks Chandra for the reply. I have already gone thruogh theory. Most links on internet will explain the Code and Data Segments descriptor settings for reset code.Theory for Expand up stack segment is same as Data Segment. But i am not getting explanation for expand down stack segment.

I understand the concept from your below reply :
For expand-down data segments, the limit has the same function but is
interpreted differently. In these cases the range of valid addresses is from
limit + 1 to either 64K or 2^(32) - 1 (4 Gbytes) depending on the B-bit. An
expand-down segment has maximum size when the limit is zero.
But i want to use small memory region out of 4GB i.e from 0xffff,0000 to 0xfffe,0000. So i want to know what shall i write in stack segment descriptor ?
Even if the below code setting did not work.

Code: Select all

setkgdt(3, 0x0, 0xFF, 0xFF, 0xFFFE, 0x97, 0xCF); // stack
Even this URL did not work- http://www.sudleyplace.com/dpmione/expanddown.html

Can you pls post some example code from reset vector till loading GDT through lgdt instruction ?
In my development environment, i have board where i can burn/program the boot and kernel binary. Its not like having flopy image, reading sectors , copying kernel for execution etc.

Thanks,
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Expand down stack segment setting on x86

Post by Combuster »

Can you pls post some example code from reset vector till loading GDT through lgdt instruction ?
Write your OS for you?. That's your homework.

Please learn to read and solve your own problems. You haven't even bothered to fix all the issues mentioned by Chandra.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Post Reply