I’m reading the disassemble code of mit os’s kernel code. I think the kernel code should follow the same rule.
I saw the instruction in the kernel that load the Global Descriptor Table is as follows: lgdtl 0x10f018
I know the lgdt takes the length of the GDT (16bit) and the address of the GDT (32bit) as the operand. However, I cannot tell what the GDT’s address is from the command.
I exam the 8 word memory content starting at 0x10f0 and 0xf018. All of the 8 words starting at both of these two address are zero.
My question is:
What is the GDT address from the lgdtl 0x10f018
? How did you tell it? The machine is intel 32bit.
Is there any register holding the address of the GDT? I’m using bochs to run the OS, so if I know the register, maybe I can just print out the content of the register.
Thank you very much for your help!
[MODIFICATION] I looked acround and found lgdtl ADDR means load the content at ADDR to the GDTR. So the content at ADDR is the limit and address of GDT. I print out the memory content at 0x10f018:
<bochs:24> x /8wx 0x10f018 [bochs]: 0x0010f018 <bogus+ 0>: 0xf0000017 0x00000010 0x32311b00 0x36353433 0x0010f028 <bogus+ 16>: 0x30393837 0x09083d2d 0x72657771 0x69757974
Below is the set up of the GDT
################################################################### # setup the GDT ################################################################### .p2align 2 # force 4 byte alignment mygdt: SEG_NULL # null seg SEG(STA_X|STA_R, -KERNBASE, 0xffffffff) # code seg SEG(STA_W, -KERNBASE, 0xffffffff) # data seg mygdtdesc: .word 0x17 # sizeof(mygdt) - 1 .long RELOC(mygdt) # address mygdt
My question is: how can I interpret the
0x0010f018 <bogus+ 0>: 0xf0000017 0x00000010 0x32311b00
to get the address of GDT?
BTW, the content at 0x00f01000 is as follows. I thought it could be the GDT, but not. 🙁 Any one can help?
<bochs:31> x /16wx 0x00f01000 [bochs]: 0x00f01000 <bogus+ 0>: 0x00000000 0x00000000 0x00000000 0x00000000 0x00f01010 <bogus+ 16>: 0x00000000 0x00000000 0x00000000 0x00000000 0x00f01020 <bogus+ 32>: 0x00000000 0x00000000 0x00000000 0x00000000 0x00f01030 <bogus+ 48>: 0x00000000 0x00000000 0x00000000 0x00000000
Solved:
<bochs:29> x /6bx 0x10f018 [bochs]: 0x0010f018 <bogus+ 0>: 0x17 0x00 0x00 0xf0 0x10 0x00
Based on little edian, the register has 0010f000 0017 So the address of GDT is 0010f000, its length is 0017; This is confirmed by looking at the content at 0010f000:
<bochs:32> x /8wx 0x0010f000 [bochs]: 0x0010f000 <bogus+ 0>: 0x00000000 0x00000000 0x0000ffff 0x10cf9a00 0x0010f010 <bogus+ 16>: 0x0000ffff 0x10cf9300 0xf0000017 0x00000010
In addition, the initial esp is pointed to 0x0010f000 which is the start address of GDT. When the first function is called, the stack is increased from the higher address to lower address.
The memory map is as follows (left is lower address):
—program stack—|GDT
Advertisement
Answer
GDT is basically a structure which contains various GDT entries. lgdtl
is the instruction to load Global Descriptor Table into gdt register. So, to answer from your question: 0x10f018 is the GDT base address. If you look at the code you’ll find GDT is defined as structure and 0x10f018 is the address of that structure (as per your disassembly) , inside the GDT struct there can be up to 8192 entries.
So, yes GDT register holds the base address of GDT struct. lgdt
is used to setup the gdt and it has format like: lgdt maddr
. And, your plan of printing out the content of register won’t work before you setup the GDT, cause the only way to setup GDT is to use lgdt
.
Hope this will help! Also take a look at following references for clearing up the concept of GDT and LGDT