Building your own Operating System (Week 04)

Hello Everyone !!
This is the fourth article in this series. In this article, I’m going to talk about how to integrate segmentation. In the previous article, I explained how to integrate outputs and you can check it out by clicking here. For those coding and implementation staff, I’m following the guide “The little book about OS development” by Erik Helin and Adam Renberg.
So, what is segmentation? Segmentation in x86 means accessing the memory through segments. Segments are portions of the address space, possibly overlapping, specified by a base address and a limit.
To enable segmentation you need to set up a segment descriptor table that describes each segment. In x86, there are two types of descriptor tables: the Global Descriptor Table (GDT) and Local Descriptor Tables (LDT). An LDT is set up and managed by user-space processes, and all processes have their own LDT. LDTs can be used if a more complex segmentation model is desired. The GDT is shared by everyone which means it’s global. Here we use Global Descriptor Table.
Accessing Memory
The processor has six 16-bit segment registers. Which are cs, ss, ds, es, gs and fs. The register cs is the code segment register and specifies the segment to use when fetching instructions. The register ss is used whenever accessing the stack and ds is used for other data accesses. The OS is free to use the registers es, gs and fs.
So, here’s the assembly code for the file called “gdt.s” which is located in a newly created directory called “segmentation”. This will help to access the memory.
The Global Descriptor Table (GDT)
A GDT is an array of 8-byte segment descriptors. The first descriptor in the GDT is always a null descriptor and can never be used to access memory. At least two segment descriptors are needed for the GDT because the descriptor contains more information than just the base and limit fields. The two most relevant fields for us are the Type field and the Descriptor Privilege Level (DPL) field.
Loading the GDT
Loading the GDT into the processor is done with the “lgdt” assembly code instruction, which takes the address of a struct that specifies the start and size of the GDT. To do that you need to declare functions and structures within a file called “segments.h” which is in the “segmentation” directory.
Then you need to define those functions in a file called “segments.c” which is also in the “segmentation” directory.
Now you need to configure the “Makefile” properly like this to run your OS.
Now you can call the “segments_install_gdt” function in the “kmain.c” file. After doing those all things if your OS booted without any errors using the “make run” command, you integrated segmentation successfully. I think you all got a good idea about how to integrate segmentation. You can check my Github Repo using this link.
Thank you for reading and I will be back next week with part 5 of this article series.