Descriptors

From OSDev.wiki
Revision as of 03:56, 3 March 2007 by osdev>Jhawthorn
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Template:Convert


  _There is also [descriptor coverage in BabySteps tutorial|BabyStep6]. This is intended as a reference, with exhaustive coverage of various descriptor types, their structs and options, which can be used both for analysis of existing descriptors and for synthesis of your own._

Descriptors are one of the key structures of Protected Mode. They are used to hold information about various system objects and are used as entries in the three system tables - GDT, LDT and [IDT].

All descriptors are 8 bytes in size, but different types may have different format.

One thing they all have in common is the "type_attr" field (byte at offset 5) that contains descriptor type and some common attributes. Thus, if you have a descriptor of yet unknown type, you should look at the "type_attr" byte to find out the type. (Maybe you want to analyze and display the contents of some table)

<verbatim> // a "general" structure of a descriptor whose type we don't know, // only for the sake of discussion - you will want to use a more specific structure // according to the type you're dealing with, or define a union for all types struct Descr{

uint8 bytes[8];
// --- accessor methods
uint8 type_attr(){ return bytes[5]; };

}; </verbatim>

  1. [|type_attr]"type_attr" has the following bit fields:
  • bit 7: "P" (Present) flag
    • Indicates whether the descriptor is being used. Accessing an object through a descriptor which has P=0 will cause a General Protection Fault.
  • bits 5..6: DPL - Descriptor Privilege Level (2 bits, 0..3)
    • Used to control access to the object described by the descriptor
  • bit 4: "S" - whether this is a data/code segment (S=1) or a system segment (some other object) (S=0).
    • One can think of it as "(data/code) Segment" flag. This, combined with the "type" code, can be used to determine the descriptor type and structure.
  • bits 0..3: type (4 bits, 0..0xF)

Here are the formulas:

type |

(type_attr & 0xF)

S |

((type_attr>>4) & 1)

DPL |

((type_attr>>5) & 3)

P |

((type_attr>>7) & 1)

!!! Code/Data Segment Descriptors

These have S=1. Bit 3 of "type" indicates whether it's (0) Data or (1) Code.

<verbatim> struct SegDescr{

uint16 limit_1; // limit, bits 0..15
uint16 base_1; // base, bits 0..15
uint8 base_2; // base, bits 16..23
uint8 type_attr; // type_attr
uint8 lim_attr;
  //^ bits 0..3: limit, bits 16..19
  //^ bits 4..7: additional data/code attributes
uint8 base_3; // base, bits 24..31

}; </verbatim>

So we have (putting all chunks of each field together):

  • Base - 32 bits total
  • Limit - 20 bits total
    • when using G=0 (granularity: bytes), limit can be from 1b to 1Mb
    • when using G=1 (granularity: pages), limit can be from 4Kb to 4Gb

Type bits interpretation (general, for details specific to data or code see below):

bit 3 |

Data/Code |
 0 (data)
1 (code)

bit 2 |

E/C |
 Expand-down (data)
Conforming (code)

bit 1 |

W/R |
 Writeable (data)
Readable (code)

bit 0 |

A |
 Accessed (code, data)

Additional attributes from lim_attr (bits 4..7):

bit 7 |

G |
 Granularity |
  0 (limit is in bytes)
1 (limit is in pages of 4096 bytes)

bit 6 |

D/B |
 Default operand size/Big |
  0 for 16-bit segments
1 for 32-bit segments

bit 5 |

L |
 64-bit code segment |
  0 normally
1 if this is a 64-bit code segment in IA-32e mode

bit 4 |

AVL |
 Available |
  For use by system software
(your OS can use this as you choose)


<verbatim> // computing base and limit values - putting the bits together

uint32 SegDescr::base(){

return
  base_1 |
  (base_2<<16) |
  (base_3<<24);

};

uint32 SegDescr::limit(){

return
 limit_1 |
 ((lim_attr&0xf)<<16);

}; </verbatim>

!! Type bits for Data segments

bit 3 |

Data/Code |
 0 (data)

bit 2 |

Expand-down |
 0 (normal)
1 (expand-down FIXME how this works?)

bit 1 |

Writeable |
 0 (read-only)
1 (read-write)

bit 0 |

Accessed |
 0 (hasn't been accessed)
1 (has been accessed)

!! Type bits for Code segments

bit 3 |

Data/Code |
 1 (code)

bit 2 |

Conforming |
 0 (non-conforming)
1 (conforming FIXME how this works?)

bit 1 |

Readable |
 0 (execute-only)
1 (executable and readable)

bit 0 |

Accessed |
 0 (hasn't been accessed)
1 (has been accessed)

_to be continued_