I've been struggling with understanding segmentation for some time now. Here's what I know.
There are different types of segments, such as the code segment, data segment, stack segment, and extra segments. In old architectures (286 and below), segments were limited to 64kB and used a segment:offset addressing scheme. In later architectures, the addressing scheme was changed to a selector:offset scheme where the selector would access an entry in a GDT or LDT which would contain the address of the segment and other information.
Here's what I'm confused about. What's the point of having different types of segments? If they can overlap, than there's no point in having separate data and code segments, just one general type of segment both can go in.
Secondly, if the segments specified in the LDT are for specific processes, what are the segments specified in the GDT for?
How are the segment addresses set in the LDT? I've written assembly code before but I've never had to tell the LDT where to find my segments before. Does the kernel handle all of that?