I'm not sure what you mean by 'create GDT segment descriptors' if you haven't set up the representation of the GDT entries yet. Are you referring to the code that loads the GDT Register, and if so, how are you doing that if the table itself isn't set up?
If you can, please post the relevant code you are referring to, and perhaps post a link to your offsite repo so we can see the larger picture of your project (you
do have your code under version control, right? If not, drop everything right now and get that taken care of, stat).
While a
struct is common way of representing the GDT entries in C (or
even in assembly, if your assembler has a data structure facility), it isn't strictly necessary; you could use an array of
uint8_ts or a single
uint64_t to represent each entry, if you find those more convenient. I personally find the
struct approach easier to work with, but it isn't the only way.
No matter how you do it, you would then want to have an array of those entries, and then populate the fields of the individual entries themselves with the appropriate settings for the Null Entry, a System Code entry, System Data, at least one TSS, and at least a few User Code and User Data entries - as well as space for additional entries to be updated later.
Only once you have the table populated should you load the GDTR.
Again, the example from my own code can be seen
here. though it probably isn't much help from a C perspective. In C, you would almost certainly want to have one or more functions which manipulate the GDT entries, rather than statically initializing them as I did here; this example really only suits a temporary GDT for going from Legacy BIOS to protected mode, which doesn't apply in your case given that you are using GRUB.
I won't pretend to be an expert on the GDT, so if I anyone more experienced in this topic spots any mistakes in what I just said, please correct me.