Updated GDT code

This commit is contained in:
Alex 2022-11-05 07:36:57 +02:00
parent 8e579133cc
commit 14ccd20d9b
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
2 changed files with 100 additions and 51 deletions

View File

@ -12,29 +12,35 @@ namespace GlobalDescriptorTable
{.Length = 0x0, {.Length = 0x0,
.BaseLow = 0x0, .BaseLow = 0x0,
.BaseMiddle = 0x0, .BaseMiddle = 0x0,
.Access = 0b00000000, .Access = {.Raw = 0x0},
.Flags = 0b00000000, .Flags = {.Raw = 0x0},
.BaseHigh = 0x0}, .BaseHigh = 0x0},
// kernel code // kernel code
{.Length = 0x0, {.Length = 0x0,
.BaseLow = 0x0, .BaseLow = 0x0,
.BaseMiddle = 0x0, .BaseMiddle = 0x0,
.Access = RING0 | .Access = {.A = 0,
CODE_READABLE | .RW = 1,
CODE_SEGMENT | .DC = 0,
PRESENT, .E = 1,
.Flags = _64BITS, .S = 1,
.DPL = 0,
.P = 1},
.Flags = {.L = 1},
.BaseHigh = 0x0}, .BaseHigh = 0x0},
// kernel data // kernel data
{.Length = 0x0, {.Length = 0x0,
.BaseLow = 0x0, .BaseLow = 0x0,
.BaseMiddle = 0x0, .BaseMiddle = 0x0,
.Access = RING0 | .Access = {.A = 0,
DATA_WRITEABLE | .RW = 1,
DATA_SEGMENT | .DC = 0,
PRESENT, .E = 0,
.S = 1,
.DPL = 0,
.P = 1},
.Flags = 0b00000000, .Flags = 0b00000000,
.BaseHigh = 0x0}, .BaseHigh = 0x0},
@ -42,21 +48,27 @@ namespace GlobalDescriptorTable
{.Length = 0x0, {.Length = 0x0,
.BaseLow = 0x0, .BaseLow = 0x0,
.BaseMiddle = 0x0, .BaseMiddle = 0x0,
.Access = CODE_READABLE | .Access = {.A = 0,
CODE_SEGMENT | .RW = 1,
RING3 | .DC = 0,
PRESENT, .E = 1,
.Flags = _64BITS, .S = 1,
.DPL = 3,
.P = 1},
.Flags = {.L = 1},
.BaseHigh = 0x0}, .BaseHigh = 0x0},
// user data // user data
{.Length = 0x0, {.Length = 0x0,
.BaseLow = 0x0, .BaseLow = 0x0,
.BaseMiddle = 0x0, .BaseMiddle = 0x0,
.Access = DATA_WRITEABLE | .Access = {.A = 0,
DATA_SEGMENT | .RW = 1,
RING3 | .DC = 0,
PRESENT, .E = 0,
.S = 1,
.DPL = 3,
.P = 1},
.Flags = 0b00000000, .Flags = 0b00000000,
.BaseHigh = 0x0}, .BaseHigh = 0x0},
@ -83,6 +95,10 @@ namespace GlobalDescriptorTable
__attribute__((no_stack_protector)) void Init(int Core) __attribute__((no_stack_protector)) void Init(int Core)
{ {
debug("Kernel: Code Access: %ld; Data Access: %ld", GDTEntries.Code.Access.Raw, GDTEntries.Data.Access.Raw);
debug("Kernel: Code Flags: %ld; Data Flags: %ld", GDTEntries.Code.Flags.Raw, GDTEntries.Data.Flags.Raw);
debug("User: Code Access: %ld; Data Access: %ld", GDTEntries.UserCode.Access.Raw, GDTEntries.UserData.Access.Raw);
debug("User: Code Flags: %ld; Data Flags: %ld", GDTEntries.UserCode.Flags.Raw, GDTEntries.UserData.Flags.Raw);
CPU::x64::lgdt(&gdt); CPU::x64::lgdt(&gdt);
asmv("movq %%rsp, %%rax\n" asmv("movq %%rsp, %%rax\n"

View File

@ -5,39 +5,72 @@
namespace GlobalDescriptorTable namespace GlobalDescriptorTable
{ {
/* https://github.com/nanobyte-dev/nanobyte_os/blob/master/src/kernel/arch/i686/gdt.c */ /** @brief The GDT Access Table
/* https://wiki.osdev.org/Global_Descriptor_Table */ * @details For more information, see https://wiki.osdev.org/Global_Descriptor_Table
typedef enum */
union GlobalDescriptorTableAccess
{ {
CODE_READABLE = 0b00000010, struct
DATA_WRITEABLE = 0b00000010, {
/** @brief Access bit.
* @note The CPU sets this bit to 1 when the segment is accessed.
*/
uint8_t A : 1;
CODE_CONFORMING = 0b00000100, /** @brief Readable bit for code segments, writable bit for data segments.
DATA_DIRECTION_NORMAL = 0b00000000, * @details For code segments, this bit must be 1 for the segment to be readable.
DATA_DIRECTION_DOWN = 0b00000100, * @details For data segments, this bit must be 1 for the segment to be writable.
*/
uint8_t RW : 1;
DATA_SEGMENT = 0b00010000, /** @brief Direction bit for data segments, conforming bit for code segments.
CODE_SEGMENT = 0b00011000, * @details For data segments, this bit must be 1 for the segment to grow up (higher addresses).
* @details For code segments, this bit must be 1 for code in the segment to be able to be executed from an equal or lower privilege level.
*/
uint8_t DC : 1;
DESCRIPTOR_TSS = 0b00000000, /** @brief Executable bit.
* @details This bit must be 1 for code-segment descriptors.
* @details This bit must be 0 for data-segment and system descriptors.
*/
uint8_t E : 1;
RING0 = 0b00000000, /** @brief Descriptor type.
RING1 = 0b00100000, * @details This bit must be 0 for system descriptors.
RING2 = 0b01000000, * @details This bit must be 1 for code or data segment descriptor.
RING3 = 0b01100000, */
uint8_t S : 1;
PRESENT = 0b10000000 /** @brief Descriptor privilege level.
} AccessFlags; * @details This field determines the privilege level of the segment.
* @details 0 = kernel mode, 3 = user mode.
*/
uint8_t DPL : 2;
typedef enum /** @brief Present bit.
* @details This bit must be 1 for all valid descriptors.
*/
uint8_t P : 1;
} __attribute__((packed));
uint8_t Raw;
};
union GlobalDescriptorTableFlags
{ {
_64BITS = 0b00100000, // TODO: Add more flags.
_32BITS = 0b01000000, struct
_16BITS = 0b00000000, {
/** @brief Unknown. */
uint8_t Unknown : 5;
GRANULARITY_1B = 0b00000000, /** @brief Long mode.
GRANULARITY_4K = 0b10000000 * @details If the long mode bit is clear, the segment is in 32-bit protected mode.
} GDTFlags; * @details If the long mode bit is set, the segment is in 64-bit long mode.
*/
uint8_t L : 1;
} __attribute__((packed));
uint8_t Raw;
};
typedef struct _TaskStateSegmentEntry typedef struct _TaskStateSegmentEntry
{ {
@ -63,17 +96,17 @@ namespace GlobalDescriptorTable
typedef struct _GlobalDescriptorTableEntry typedef struct _GlobalDescriptorTableEntry
{ {
/** @brief Length [Bits 0-15] */ /** @brief Length */
uint16_t Length; uint16_t Length;
/** @brief Low Base [Bits 0-15] */ /** @brief Low Base */
uint16_t BaseLow; uint16_t BaseLow;
/** @brief Middle Base [Bits 0-23] */ /** @brief Middle Base */
uint8_t BaseMiddle; uint8_t BaseMiddle;
/** @brief Access */ /** @brief Access */
uint8_t Access; GlobalDescriptorTableAccess Access;
/** @brief Flags [Bits 16-19] */ /** @brief Flags */
uint8_t Flags; GlobalDescriptorTableFlags Flags;
/** @brief High Base [Bits 24-31] */ /** @brief High Base */
uint8_t BaseHigh; uint8_t BaseHigh;
} __attribute__((packed)) GlobalDescriptorTableEntry; } __attribute__((packed)) GlobalDescriptorTableEntry;