1

I want to implement 32-bit 4Gb Flat Memory mapping for an application, for this purpose I have to get and update Data Segment Descriptor and Code Segment Descriptors. By using assembly command "sgdt" i can get Global Descriptor Table but I am not sure if its CS or DS or any other descriptor. It would be really appreciated if some one can help me deal with this confusion.

I am relying on GRUB to set GDT that's why i don't know the exact location where it put all the segment descriptors. By viewing the GDT table entries I can see 5 same Code Segment Entries and 6 Same Data Segment entries, with base address of each entry set to '0' and limit of each set to '0xfffff'. Can you please tell me reason for these duplicate entries? And from these viewing, can you kindly confirm that Flat Memory mode is already being set by GRUB?

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
  • 1
    It gives you the 16-bit limit + the 32-bit linear address of the whole table, not one of the entries. https://www.felixcloutier.com/x86/sgdt. – Peter Cordes Jan 24 '19 at 19:30
  • @PeterCordes How can I iterate through the table to get specific descriptors? – Ameer Hamza Jan 24 '19 at 19:32
  • 1
    You could `mov eax, cs` and index the table of GDT-entry structs. https://wiki.osdev.org/Global_Descriptor_Table. You're supposed to know what you put in the GDT, if you're writing your own OS. If you're on Linux, there's a `modify_ldt` system call to ask the OS to create new GDT entries for you. What are you doing where you don't already have a 32-bit flat memory model? – Peter Cordes Jan 24 '19 at 19:35
  • @PeterCordes Thanks a lot for clearing this confusion. Actually I am relying on GRUB to set GDT that's why i don't know the exact location where it put all the segment descriptors. By viewing the GDT table entries I can see 5 same Code Segment Entries and 6 Same Data Segment entries, with base address of each entry set to '0' and limit of each set to '0xfffff'. Can you please tell me reason for these duplicate entries? And from these viewing, can you kindly confirm that Flat Memory mode is already being set by GRUB? – Ameer Hamza Jan 24 '19 at 20:01
  • 1
    See https://www.felixcloutier.com/x86/lsl for a description of how to decode segment limits: there's a bit that says whether it's a byte limit or a page limit. `0xfffff` times 4k is 4GiB, and it does seem likely that GRUB would set up a flat memory model. That's what everyone wants. – Peter Cordes Jan 24 '19 at 20:08
  • Yeah I got it. But I am still confused about duplicate entries within GDT. By viewing GDT table entries, I can make sure there are 6 same Data Segment entries and 5 same Code Segment entries. Lastly it would be really nice of you if you can tell me about the reason for duplicate entries, I am unable to get it. – Ameer Hamza Jan 24 '19 at 20:25
  • 1
    I have no idea why GRUB sets them up that way. Maybe it uses a different descriptor for each segment register. Look at the GRUB source code if you're curious. Or google `grub source code gdt` and find blog posts like https://0xax.github.io/grub/ for a guided tour. – Peter Cordes Jan 24 '19 at 20:29
  • http://git.savannah.gnu.org/cgit/grub.git/tree/grub-core/kern/i386/realmode.S?id=e3fd394a10a709e4935c3a64b237dada17f01b8e has GRUB's GDT. When GRUB itself switches to protected mode, it only has a code seg, a data seg, and a "16 bit real mode CS" and "16 bit real mode DS". – Peter Cordes Jan 24 '19 at 20:36
  • 3
    I'n going to chime in. **DO NOT rely on the GDT in GRUB**. Consider it temporary and should be replaced by your own. The [Multiboot specification](https://www.gnu.org/software/grub/manual/multiboot/multiboot.html) doesn't say how the GDT will look and what entries it uses. It lists the values in the segments as "undefined". Even worse is that you can't even assume the GDTR is valid (per the same docs).This means the moment you wish to change the segment registers directly or indirectly) there is no guarantee it will work. – Michael Petch Jan 24 '19 at 22:06
  • 2
    The moment you start creating an IDT with entries (which requires knowing what CS actually is) you will be in trouble. Since CS is reloaded to perform an interrupt request you risk having it fail the first time an interrupt is fired because the GDTR *may be invalid*. Don't rely on it working a particular way. Always do it right - create your own GDT and load it yourself with `lgdt` – Michael Petch Jan 24 '19 at 22:11
  • As for the reason GRUB has 16-bit and 32-bit descriptors (for code and data) is because GRUB will switch into protected mode from real mode requiring 32-bit descriptors. But GRUB will also flip from protected mode back to real mode so it also needs 16-bit descriptors for Code and Data. This may happen when GRUB needs to query the BIOS for video modes and resolutions. If you are not going to change from protected mode to real mode in your own OS you will not need 16-bit descriptors. – Michael Petch Jan 24 '19 at 22:18
  • I am tempted to mark this as a duplicate of this question: https://stackoverflow.com/questions/43163599/keyboard-interrupt-in-x86-protected-mode-causes-processor-error/43171871#43171871 .There is some assembly code that defines a GDT and a function that can be called to load it. – Michael Petch Jan 24 '19 at 22:27

1 Answers1

1

Answering my own question after getting great response in comments section. GDT Table contains the entries for Segment descriptors in protected mode, The Code Segment and Data Segment are identified by reading value of Code Segment Register / Data Segment Register where it contains the index for particular segment (also called Segment Selector) in GDT table.