Description of segments used in GDT #8
dimakuv
started this conversation in
Background knowledge
Replies: 1 comment
-
|
I looked at these values again because I was analyzing the asm code here: https://wiki.osdev.org/Symmetric_Multiprocessing#AP_Initialization_Code These are the GDT descriptors suggested in that code:
So the only difference from our descriptors is that it is NOT accessed, which I think totally irrelevant.
So the only differences from our descriptors are that it is NOT accessed and it is 16-bit. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
DISCLAIMER: THIS DESCRIPTION IS OLD, SOME FILENAMES ETC. MAY HAVE CHANGED!
I always forget about the magic numbers in the segment descriptors in GDT, so let me create a helper issue.
The GDT table contains a list of segment descriptors, each 8 bytes in size. The first descriptor is always a zero. Next typically come descriptors for the kernel code, kernel data, user code, user data, and then TSS. Here's a typical one, taken from
vm-common/kernel_static_structs.S:Here is the image from Intel SDM on descriptors:

Here is the image of code/data encoding (when S = 1):

Now let's decipher some typical segment descriptors.
VM,
bios/bios.S0xffff, 0xcf9b00= low 32 bits:1111 1111 1111 1111+ high 32 bits:1100 1111 1001 1011 0000 00001111 1111 1111 1111. The upper part is in bits 19..16 of high 32 bits:1111. So the total segment limit is a 20-bit value: 0xFFFFF.1-- code or data descriptor.00-- ring-0, used for kernel.1-- segment is present in memory (set). This bit is always set.0-- who cares.0-- we are NOT in 64-bit mode (see D/B).1-- 32-bit segment.1-- the segment limit is interpreted in 4KB units (NOT in bytes).1011-- code, X/R, accessed. The accessed bit is actually not interesting, could be zero.Summary: this is a 32-bit code kernel segment descriptor, can be executed and read, covers address range 0..4GB.
0xffff, 0xcf9300= low 32 bits:1111 1111 1111 1111+ high 32 bits:1100 1111 1001 0011 0000 00001-- code or data descriptor.00-- ring-0, used for kernel.1-- present.0-- who cares.0-- we are NOT in 64-bit mode.1-- 32-bit segment.1-- limit in 4KB units.0011-- data, R/W, accessed.Summary: this is a 32-bit data kernel segment descriptor, can be read/written, covers address range 0..4GB.
VM,
bootloader.S0xffff, 0xaf9b00= low 32 bits:1111 1111 1111 1111+ high 32 bits:1010 1111 1001 1011 0000 00001-- code or data descriptor.00-- ring-0, used for kernel.1-- present.0-- who cares.1-- we are in 64-bit mode. (By the way, if L bit is set then D bit must be cleared.)0-- NOT 16/32-bit segment.1-- limit in 4KB units.1011-- code, X/R, accessed.Summary: this is a 64-bit code kernel segment descriptor, can be executed and read, covers address range 0..4GB.
NOTE: I think in 64-bit mode, segment base and limit are useless, but I didn't find a proof in Intel SDM.
0xffff, 0xcf9300-- same as in data segment in BIOS (not that the data segment doesn't need to be 64-bit, since CPU only cares about the bitness of code).0x0068, 0xcf8900= low 32 bits:0110 1000+ high 32 bits:1100 1111 1000 1001 0000 0000This is a TSS system segment, it has a special formatting:
0-- system descriptor.1001-- 64-bit TSS.VM Common,
kernel_static_structs.S0xffff, 0xaf9b00= low 32 bits:1111 1111 1111 1111+ high 32 bits:1010 1111 1001 1011 0000 0000-- same as in bootloader.0xffff, 0xaf9300= low 32 bits:1111 1111 1111 1111+ high 32 bits:1010 1111 1001 0011 0000 00001-- code or data descriptor.00-- ring-0, used for kernel.1-- present.0-- who cares.1-- we are in 64-bit mode. (By the way, if L bit is set then D bit must be cleared.)0-- NOT 16/32-bit segment.1-- limit in 4KB units.0011-- data, R/W, accessed.Summary: this is a 64-bit data kernel segment descriptor, can be read/written, covers address range 0..4GB.
0xffff, 0xcffb00-- low 32 bits:1111 1111 1111 1111+ high 32 bits:1100 1111 1111 1011 0000 00001-- code or data descriptor.11-- ring-3, used for apps.1-- present.0-- who cares.0-- we are NOTE in 64-bit mode.1-- 32-bit segment.1-- limit in 4KB units.1011-- code, X/R, accessed.Summary: this is a 32-bit code userspace segment descriptor, can be executed and read, covers address range 0..4GB.
0xffff, 0xcff300-- low 32 bits:1111 1111 1111 1111+ high 32 bits:1100 1111 1111 0011 0000 00001-- code or data descriptor.11-- ring-3, used for apps.1-- present.0-- who cares.0-- we are NOTE in 64-bit mode.1-- 32-bit segment.1-- limit in 4KB units.0011-- data, R/W, accessed.Summary: this is a 32-bit data userspace segment descriptor, can be read/written, covers address range 0..4GB.
0xffff, 0xaffb00-- low 32 bits:1111 1111 1111 1111+ high 32 bits:1010 1111 1111 1011 0000 00001-- code or data descriptor.11-- ring-3, used for apps.1-- present.0-- who cares.1-- we are in 64-bit mode.0-- NOT 16/32-bit segment.1-- limit in 4KB units.1011-- code, X/R, accessed.Summary: this is a 64-bit code userspace segment descriptor, can be executed and read, covers address range 0..4GB.
Beta Was this translation helpful? Give feedback.
All reactions