Prev: what timer?
Next: the general server is not sufficient
From: James Harris on 25 Jun 2010 20:36 I've always found the many different types of 32-bit x86 descriptors and their fields hard to remember and distinguish. For my own use I've put together some notes to help me recall their fields and identify the forms. In case anyone else finds the document useful it is at http://codewiki.wikispaces.com/x86+descriptors and there is a linked page on the type codes used. It may have some inaccuracies as I've just finished it (check the manuals to be sure) but I think it's a useful breakdown to help demystify these awkward structures. It's not light reading as there's a lot in a short space and it may be best read in stages. Some interesting things have come out that I didn't know. For example, there are only two fundamental descriptor forms, one for blocks of memory and one for points in memory. The blocks of memory descriptor form includes all the memory segment types plus some System types - those for LDT and TSS blocks. And the points of memory are all gates. Simple! As ever, corrections welcome. Also, I've included only 32-bit data. Should I add 64-bit data to it or will that overload it with too much information? James
From: Stargazer on 26 Jun 2010 04:48 On Jun 26, 3:36 am, James Harris <james.harri...(a)googlemail.com> wrote: > I've always found the many different types of 32-bit x86 descriptors > and their fields hard to remember and distinguish. For my own use I've > put together some notes to help me recall their fields and identify > the forms. In case anyone else finds the document useful it is at > > http://codewiki.wikispaces.com/x86+descriptors > > and there is a linked page on the type codes used. > > It may have some inaccuracies as I've just finished it (check the > manuals to be sure) but I think it's a useful breakdown to help > demystify these awkward structures. It's not light reading as there's > a lot in a short space and it may be best read in stages. In my opinion, x86 descriptors are more awkward than, say SPRs or segment descriptors on PowerPC or cp0 registers with 0 to 3 "selects" per register on MIPS. All more or less mature architectures have their bunch of awkwardness due to past and future compatibility issues and... many attempts to simplify/generalize things (don't laugh). > Some interesting things have come out that I didn't know. For example, > there are only two fundamental descriptor forms, one for blocks of > memory and one for points in memory. The blocks of memory descriptor > form includes all the memory segment types plus some System types - > those for LDT and TSS blocks. And the points of memory are all gates. > Simple! I think that Intel manuals also refer to two types of descriptors, but call them "segment" and "gate" descriptors (or it was in earlier documents, I didn't check that recently). I would also suggest that your terminology choice is bad even for your own memorizing. First, the architecture definition also refers to two types of descriptors, but calls them with different name; you must have some good reason to suggest a different pair of names which would require you then remember both pairs and correspondence between them in order to look up things in specs. Second, if you wanted to ease remembering you ought to choose more "talkative" (not even descriptive names) - names that would remind you the things as they are. "Blocks" have too many options to mix up (besides segments, MTRR-defined ranges may be refered as "blocks"; pages or page tables may be thought of as "blocks", etc.) Everything in your "blocks" group is a segment except for LDT, so "segments" or "segments and tables" may be a better replacement name. "Points" are better hinting, but apparently not in a way that you assumed, or at least your definition of "points" is misleading: it's not "points in memory", but "system entry points"! As such "points" may be more descriptive than "gates". > As ever, corrections welcome. One thing that comes to mind is regarding limits. Unless Intel added a special treatment for 0-limited segments recently, the limit for 4K- granular segments is 2**12-1 .. 2**32-1, not 0 .. 2**32-1. > Also, I've included only 32-bit data. > Should I add 64-bit data to it or will that overload it with too much > information? No (64-bit data belongs to a different architecture), but I think you should add 16-bit specifications. Daniel
From: wolfgang kern on 26 Jun 2010 05:59 James Harris posted: > I've always found the many different types of 32-bit x86 descriptors > and their fields hard to remember and distinguish. For my own use I've > put together some notes to help me recall their fields and identify > the forms. In case anyone else finds the document useful it is at > http://codewiki.wikispaces.com/x86+descriptors > and there is a linked page on the type codes used. Me too found it a bit confusing, so I made myself a quick reference for 32 bit types (16 bit types seem to vary by one bit only). I'll add my html-source at the end here. > It may have some inaccuracies as I've just finished it (check the > manuals to be sure) but I think it's a useful breakdown to help > demystify these awkward structures. It's not light reading as there's > a lot in a short space and it may be best read in stages. Because I use only 93/9B/8E types, there could be errors in the other fields I'm not even aware of. Please check and confirm before using. > Some interesting things have come out that I didn't know. For example, > there are only two fundamental descriptor forms, one for blocks of > memory and one for points in memory. The blocks of memory descriptor > form includes all the memory segment types plus some System types - > those for LDT and TSS blocks. And the points of memory are all gates. > Simple! Yes, but it took me once 'some' time to see it this way :) > As ever, corrections welcome. Also, I've included only 32-bit data. > Should I add 64-bit data to it or will that overload it with too much > information? IMHO I think 64-bit descriptors would be better an apart story, the difference to 32 bit will add some confusion anyway. __ wolfgang I'm not an expert on html, but it shall be readable at least. _____source of x86-descriptor.html______________________ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Strict//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <!-- copied from the "Holy Book of KESYS" Jan.1999, Author: Wolfgang Kern, Vienna Austria (LEOC, KESYS-development) > <title>x86descriptors</title> <style type="text/css"> <!-- tr {nowrap; } td {nowrap; align:center; } --> </style> </head> <body bgcolor="#FFFFFF" text="#000000" align="left"> <basefont face="Lucida Console"> <basefont size="2"> <u><b>x86 Protected Mode Descriptors</caption><b/></u> <table border="1" frame="box" rules="all" bgcolor="#FFFFFF" height="200" cellspacing="0" cellpadding="0" bordercolor="#808080"> <colgroup> <col width="8"> <col width="24" align="middle" span=8> <col width="200" align="left" valign="top"> </colgroup> <tr> <td>7</td> <td colspan="8">BASE 31..24</td> <td rowspan="9"> <pre><b><u> DATA [93][GDT,LDT]</b></u> G 4Kb granular limit B 32-bit stack P present E expand down (stack) W writable A accessed</pre> </td> </tr> <tr> <td>6</td> <td><b>G</td> <td><b>B</td> <td><b>0</td> <td>x</td> <td nowrap colspan="4">LIM 19..16</td> </tr> <tr> <td>5</td> <td>P</td> <td colspan="2">DPL</td> <td colspan="2" style="border-width:medium;border-color:#000000; border-style:double;"> <b>1 0</td> <td><b>E</td> <td><b>W</td> <td><b>A</td> </tr> <tr> <td>4</td> <td rowspan="3" colspan="8">BASE 0..23</td> </tr> <tr> <td>3</td></tr> <tr> <td>2</td></tr> <tr> <td>1</td> <td rowspan="2" colspan="8">LIMIT 0..15</td> </tr> <tr><td>0</td></tr> <tr style="font-size:7pt;"> <td></td> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr> </table> <br> <table border="1" frame="box" rules="all" bgcolor="#FFFFFF" height="200" cellspacing="0" cellpadding="0" bordercolor="#808080"> <colgroup> <col width="8"> <col width="24" align="middle" span=8> <col width="200" align="left" valign="top"> </colgtroup> <tr> <td>7</td> <td colspan="8">BASE 31..24</td> <td rowspan="9"> <pre><b><u> CODE [9b][GDT,LDT]</u></b> G 4Kb granular B 32-bit P present C confirming R readable A accessed</pre> </td></tr> <tr> <td>6</td> <td><b>G</td> <td><b>B</td> <td><b>0</td> <td>x</td> <td nowrap colspan="4">LIM 19..16</td> </tr> <tr> <td>5</td> <td>P</td> <td colspan="2">DPL</td> <td colspan="2" style="border-width:medium;border-color:#000000; border-style:double; padding:0px;"><b>1 1</td> <td><b>C</td> <td><b>R</td> <td><b>A</td> </tr> <tr> <td>4</td> <td rowspan="3" colspan="8">BASE 0..23</td> </tr> <tr> <td>3</td></tr> <tr> <td>2</td></tr> <tr> <td>1</td> <td rowspan="2" colspan="8">LIMIT 0..15</td> </tr> <tr><td>0</td></tr> <tr style="font-size:7pt;"> <td></td> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr> </table> <br> <table border="1" frame="box" rules="all" bgcolor="#ffffff" height="200" cellspacing="0" cellpadding="0" bordercolor="#808080"> <colgroup> <col width="8"> <col width="24" align="middle" span=8> <col width="200" align="left" valign="top"> </colgtroup> <tr> <td>7</td> <td colspan="8">BASE 31..24</td> <td rowspan="9"><pre><u><b> TASK-switch [81/89]</u> [GDT]</b> G 4Kb granular limit P present BT 32-bit BS task is busy</pre> </td></tr> <tr> <td>6</td> <td><b>G</td> <td><b>0</td> <td><b>0</td> <td>x</td> <td nowrap colspan="4">LIM 19..16</td> </tr> <tr> <td>5</td> <td>P</td> <td colspan="2">DPL</td> <td style="border-color:#000000;border-width:medium;border-style:double"><b>0</td> <td><b>BT</td> <td colspan= "3" style="border-color:#000000;border-width:medium;border-style:double"> <b>0 BS 1</td> </tr> <tr> <td>4</td> <td rowspan="3" colspan="8">BASE 0..23</td> </tr> <tr> <td>3</td></tr> <tr> <td>2</td></tr> <tr> <td>1</td> <td rowspan="2" colspan="8">LIMIT 0..15</td> </tr> <tr><td>0</td></tr> <tr style="font-size:7pt;"> <td></td> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr> </table> <br> <table border="1" frame="box" rules="all" bgcolor="#ffffff" height="200" cellspacing="0" cellpadding="0" bordercolor="#808080"> <colgroup> <col width="8"> <col width="24" align="middle" span=8> <col width="200" align="left" valign="top"> </colgtroup> <tr> <td>7</td> <td rowspan="2" colspan="8">Linear Address 31..16</td> <td rowspan="9"><pre><u><b> LDT [82][GDT]</b></u></td></tr> <tr> <td>6</td> </tr> <tr> <td>5</td> <td>P</td> <td colspan="2">--</td> <td style="border-color:#000000;border-width:medium;border-style:double"> <b>0</td> <td><b>0</td> <td colspan= "3" style="border-color:#000000;border-width:medium;border-style:double"> <b>0 1 0</td> </tr> <tr> <td>4</td> <td colspan="8">reserved</td> </tr> <tr> <td>3</td> <td colspan="8">SEGMENT-</td> </tr> <tr> <td>2</td> <td colspan="5">SELECTOR</td> <td>x</td> <td colspan="2">RPL</td> </tr> <tr> <td>1</td> <td rowspan="2" colspan="8">Linear Address 15..0</td> </tr> <tr><td>0</td></tr> <tr style="font-size:7pt;"> <td></td> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr> </table> <br> <br> <table border="1" frame="box" rules="all" bgcolor="#ffffff" height="200" cellspacing="0" cellpadding="0" bordercolor="#808080"> <colgroup> <col width="8"> <col width="24" align="middle" span=8> <col width="200" align="left" valign="top"> </colgtroup> <tr> <td>7</td> <td rowspan="2" colspan="8">Offset 31..16</td> <td rowspan="9"><pre><u><b> Call-GATE [84/8c] [GDT,LDT]</b></u> T 32-bit L LDT (else GDT) Dwords copied from callers stack. </td></tr> <tr> <td>6</td> </tr> <tr> <td>5</td> <td>P</td> <td colspan="2">DPL</td> <td style="border-color:#000000;border-width:medium;border-style:double"> <b>0</td> <td><b>T</td> <td colspan= "3" style="border-color:#000000;border-width:medium;border-style:double"> <b>1 0 0</td> </tr> <tr> <td>4</td> <td colspan="4">0 0 0 0</td> <td colspan="4">Dwords </td> </tr> <tr> <td>3</td> <td colspan="8">SEGMENT-</td> </tr> <tr> <td>2</td> <td colspan="5">SELECTOR</td> <td>L</td> <td colspan="2">RPL</td> </tr> <tr> <td>1</td> <td rowspan="2" colspan="8">Offset 15..0</td> </tr> <tr><td>0</td></tr> <tr style="font-size:7pt;"> <td></td> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr> </table> <br> <table border="1" frame="box" rules="all" bgcolor="#ffffff" height="200" cellspacing="0" cellpadding="0" bordercolor="#808080"> <colgroup> <col width="8"> <col width="24" align="middle" span=8> <col width="200" align="left" valign="top"> </colgtroup> <tr> <td>7</td> <td rowspan="2" colspan="8">reserved</td> <td rowspan="9"><pre><u><b> TASK-GATE [85/8d] [GDT,IDT,LDT]</b></u> T: 32-bit </td></tr> <tr> <td>6</td> </tr> <tr> <td>5</td> <td>P</td> <td colspan="2">DPL</td> <td style="border-color:#000000;border-width:medium;border-style:double"> <b>0</td> <td><b>T</td> <td colspan= "3" style="border-color:#000000;border-width:medium;border-style:double"> <b>1 0 1</td> </tr> <tr> <td>4</td> <td colspan="8">reserved</td> </tr> <tr> <td>3</td> <td colspan="8">SEGMENT-</td> </tr> <tr> <td>2</td> <td colspan="5">SELECTOR</td> <td>x</td> <td colspan="2">RPL</td> </tr> <tr> <td>1</td> <td rowspan="2" colspan="8">reserved</td> </tr> <tr><td>0</td></tr> <tr style="font-size:7pt;"> <td></td> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr> </table> <br> <table border="1" frame="box" rules="all" bgcolor="#ffffff" height="200" cellspacing="0" cellpadding="0" bordercolor="#808080"> <colgroup> <col width="8"> <col width="24" align="middle" span=8> <col width="200" align="left" valign="top"> </colgtroup> <tr> <td>7</td> <td rowspan="2" colspan="8">Offset 31..16</td> <td rowspan="9"><pre><u><b> INT-GATE [86/8e][IDT]</b></u> T 32-bit disables IRQ, TRAP and NT cleared until IRET </td></tr> <tr> <td>6</td> </tr> <tr> <td>5</td> <td>P</td> <td colspan="2">DPL</td> <td style="border-color:#000000;border-width:medium;border-style:double"> <b>0</td> <td><b>T</td> <td colspan= "3" style="border-color:#000000;border-width:medium;border-style:double"> <b>1 1 0</td> </tr> <tr> <td>4</td> <td colspan="8">reserved</td> </tr> <tr> <td>3</td> <td colspan="8">SEGMENT-</td> </tr> <tr> <td>2</td> <td colspan="5">SELECTOR</td> <td>x</td> <td colspan="2">RPL</td> </tr> <tr> <td>1</td> <td rowspan="2" colspan="8">Offset 15..0</td> </tr> <tr><td>0</td></tr> <tr style="font-size:7pt;"> <td></td> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr> </table> <br> <table border="1" frame="box" rules="all" bgcolor="#ffffff" height="200" cellspacing="0" cellpadding="0" bordercolor="#808080"> <colgroup> <col width="8"> <col width="24" align="middle" span=8> <col width="200" align="left" valign="top"> </colgtroup> <tr> <td>7</td> <td rowspan="2" colspan="8">Offset 31..16</td> <td rowspan="9"><pre><u><b> INT-TRAP [87/8f][IDT]</b></u> T 32-bit IRQ-status unchanged, TRAP and NT cleared until IRET </td></tr> <tr> <td>6</td> </tr> <tr> <td>5</td> <td>P</td> <td colspan="2">DPL</td> <td style="border-color:#000000;border-width:medium;border-style:double"> <b>0</td> <td><b>T</td> <td colspan= "3" style="border-color:#000000;border-width:medium;border-style:double"> <b>1 1 1</td> </tr> <tr> <td>4</td> <td colspan="8">reserved</td> </tr> <tr> <td>3</td> <td colspan="8">SEGMENT-</td> </tr> <tr> <td>2</td> <td colspan="5">SELECTOR</td> <td>x</td> <td colspan="2">RPL</td> </tr> <tr> <td>1</td> <td rowspan="2" colspan="8">Offset 15..0</td> </tr> <tr><td>0</td></tr> <tr style="font-size:7pt;"> <td></td> <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td> </tr> </table> <br> </font> </body> </html>
From: James Harris on 26 Jun 2010 09:08 On 26 June, 09:48, Stargazer <stargazer3...(a)gmail.com> wrote: .... > > Some interesting things have come out that I didn't know. For example, > > there are only two fundamental descriptor forms, one for blocks of > > memory and one for points in memory. The blocks of memory descriptor > > form includes all the memory segment types plus some System types - > > those for LDT and TSS blocks. And the points of memory are all gates. > > Simple! > > I think that Intel manuals also refer to two types of descriptors, but > call them "segment" and "gate" descriptors (or it was in earlier > documents, I didn't check that recently). I would also suggest that > your terminology choice is bad even for your own memorizing. That there are basically only two forms of descriptor is is one of those pieces of information that once you know it it seems obvious. Where I've seen them in the Intel manuals, however, they refer to many types. > First, the architecture definition also refers to two types of > descriptors, but calls them with different name; you must have some > good reason to suggest a different pair of names which would require > you then remember both pairs and correspondence between them in order > to look up things in specs. > > Second, if you wanted to ease remembering you ought to choose more > "talkative" (not even descriptive names) - names that would remind you > the things as they are. "Blocks" have too many options to mix up > (besides segments, MTRR-defined ranges may be refered as "blocks"; > pages or page tables may be thought of as "blocks", etc.) Everything > in your "blocks" group is a segment except for LDT, so "segments" or > "segments and tables" may be a better replacement name. "Points" are > better hinting, but apparently not in a way that you assumed, or at > least your definition of "points" is misleading: it's not "points in > memory", but "system entry points"! As such "points" may be more > descriptive than "gates". Isn't an LDT a segment? Maybe it isn't. I haven't checked. I take your point about names. I don't want to call the first type "segment descriptors" as the term segment has a lot of baggage and means specific things to many people. I want the reader to see the first descriptor type as identifying a block/range/region/space of memory and contrast that with the second type which identifies a single location, not a range. I think that aids remembering because it highlights *why* they are different. Any term has baggage but I agree that "block" is not good. I've changed it to "range." Maybe that's a bit better? > > As ever, corrections welcome. > > One thing that comes to mind is regarding limits. Unless Intel added a > special treatment for 0-limited segments recently, the limit for 4K- > granular segments is 2**12-1 .. 2**32-1, not 0 .. 2**32-1. Thanks. I've corrected it. > > Also, I've included only 32-bit data. > > Should I add 64-bit data to it or will that overload it with too much > > information? > > No (64-bit data belongs to a different architecture), but I think you > should add 16-bit specifications. That's a surprise! Aren't the 16-bit forms needed only on the 80286? Again, I haven't checked. They are listed in the type codes. I think that's enough. To add breakdowns of them as well would cause confusion. James
From: Mike Gonta on 26 Jun 2010 12:13
On Jun 26, 9:08 am, James Harris <james.harri...(a)googlemail.com> wrote: > On 26 June, 09:48, Stargazer <stargazer3...(a)gmail.com> wrote: > > No (64-bit data belongs to a different architecture), but I think you > > should add 16-bit specifications. > > That's a surprise! Aren't the 16-bit forms needed only on the 80286? A valid 16 bit segment descriptor must be moved to the segment registers prior to entering real mode from protected mode. Mike Gonta look and see - many look but few see http://mikegonta.com/pdBIOS32 |