Skip to content

Commit

Permalink
Removing the magic numbers from the GDT initialization (and adding a …
Browse files Browse the repository at this point in the history
…TSS descriptor)
  • Loading branch information
ilmmatias committed Jan 21, 2025
1 parent 9a8ef4e commit 682a6bf
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 29 deletions.
35 changes: 19 additions & 16 deletions src/boot/osloader/include/amd64/page.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,25 @@

#include <stdint.h>

typedef struct __attribute__((packed)) {
uint64_t Present : 1;
uint64_t Writable : 1;
uint64_t User : 1;
uint64_t WriteThrough : 1;
uint64_t CacheDisable : 1;
uint64_t Accessed : 1;
uint64_t Dirty : 1;
uint64_t PageSize : 1;
uint64_t Global : 1;
uint64_t Available0 : 2;
uint64_t Pat : 1;
uint64_t Address : 40;
uint64_t Available1 : 7;
uint64_t ProtectionKey : 4;
uint64_t NoExecute : 1;
typedef union {
struct __attribute__((packed)) {
uint64_t Present : 1;
uint64_t Writable : 1;
uint64_t User : 1;
uint64_t WriteThrough : 1;
uint64_t CacheDisable : 1;
uint64_t Accessed : 1;
uint64_t Dirty : 1;
uint64_t PageSize : 1;
uint64_t Global : 1;
uint64_t Available0 : 2;
uint64_t Pat : 1;
uint64_t Address : 40;
uint64_t Available1 : 7;
uint64_t ProtectionKey : 4;
uint64_t NoExecute : 1;
};
uint64_t RawData;
} PageFrame;

#endif /* _AMD64_PAGE_H_ */
58 changes: 50 additions & 8 deletions src/kernel/hal/amd64/gdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,40 @@

extern void HalpFlushGdt(void);

/*-------------------------------------------------------------------------------------------------
* PURPOSE:
* This function initializes an entry inside the GDT.
*
* PARAMETERS:
* Processor - Pointer to the processor-specific structure.
* EntryOffset - Which entry to initialize.
*
* RETURN VALUE:
* None.
*-----------------------------------------------------------------------------------------------*/
static void InitializeEntry(
KeProcessor *Processor,
uint8_t EntryOffset,
uint64_t Base,
uint32_t Limit,
uint8_t Type,
uint8_t Dpl) {
HalpGdtEntry *Entry = (HalpGdtEntry *)(Processor->GdtEntries + EntryOffset);
Entry->LimitLow = Limit & 0xFFFF;
Entry->BaseLow = Base & 0xFFFFFF;
Entry->Type = Type;
Entry->Dpl = Dpl;
Entry->Present = 1;
Entry->LimitHigh = (Limit >> 16) & 0x0F;
Entry->System = 0;
Entry->LongMode = 1;
Entry->DefaultBig = 0;
Entry->Granularity = 1;
Entry->BaseHigh = (Base >> 24) & 0xFF;
Entry->BaseUpper = (Base >> 32) & 0xFFFFFFFF;
Entry->MustBeZero = 0;
}

/*-------------------------------------------------------------------------------------------------
* PURPOSE:
* This function initializes the Global Descriptor Table. This, in combination with
Expand All @@ -17,15 +51,23 @@ extern void HalpFlushGdt(void);
* None.
*-----------------------------------------------------------------------------------------------*/
void HalpInitializeGdt(KeProcessor *Processor) {
Processor->GdtEntries[0] = 0x0000000000000000;
Processor->GdtEntries[1] = 0x00AF9A000000FFFF;
Processor->GdtEntries[2] = 0x00AF92000000FFFF;
Processor->GdtEntries[3] = 0x00AFFA000000FFFF;
Processor->GdtEntries[4] = 0x00AFF2000000FFFF;
/* The NULL descriptor should have already been zeroed out during the processor block
* allocation. */
InitializeEntry(Processor, GDT_ENTRY_KCODE, 0, 0xFFFFF, GDT_TYPE_CODE, GDT_DPL_KERNEL);
InitializeEntry(Processor, GDT_ENTRY_KDATA, 0, 0xFFFFF, GDT_TYPE_DATA, GDT_DPL_KERNEL);
InitializeEntry(Processor, GDT_ENTRY_UCODE, 0, 0xFFFFF, GDT_TYPE_CODE, GDT_DPL_USER);
InitializeEntry(Processor, GDT_ENTRY_UDATA, 0, 0xFFFFF, GDT_TYPE_DATA, GDT_DPL_USER);

Processor->GdtDescriptor.Limit = sizeof(Processor->GdtEntries) - 1;
Processor->GdtDescriptor.Base = (uint64_t)Processor->GdtEntries;
uint64_t TssBase = (uint64_t)&Processor->TssEntry;
uint16_t TssSize = sizeof(HalpTssEntry);
InitializeEntry(Processor, GDT_ENTRY_TSS, TssBase, TssSize, GDT_TYPE_TSS, GDT_DPL_KERNEL);
Processor->TssEntry.Rsp0 = (uint64_t)&Processor->SystemStack;
Processor->TssEntry.IoMapBase = TssSize;

__asm__ volatile("lgdt %0" : : "m"(Processor->GdtDescriptor));
HalpGdtDescriptor Descriptor;
Descriptor.Limit = sizeof(Processor->GdtEntries) - 1;
Descriptor.Base = (uint64_t)Processor->GdtEntries;
__asm__ volatile("lgdt %0" : : "m"(Descriptor));
HalpFlushGdt();
__asm__ volatile("mov $0x28, %%ax; ltr %%ax" : : : "%rax");
}
63 changes: 63 additions & 0 deletions src/kernel/include/public/amd64/gdt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/* SPDX-FileCopyrightText: (C) 2025 ilmmatias
* SPDX-License-Identifier: GPL-3.0-or-later */

#ifndef _AMD64_GDT_H_
#define _AMD64_GDT_H_

#include <stdint.h>

#define GDT_ENTRY_NULL 0x00
#define GDT_ENTRY_KCODE 0x08
#define GDT_ENTRY_KDATA 0x10
#define GDT_ENTRY_UCODE 0x18
#define GDT_ENTRY_UDATA 0x20
#define GDT_ENTRY_TSS 0x28

#define GDT_TYPE_TSS 0x09
#define GDT_TYPE_CODE 0x1A
#define GDT_TYPE_DATA 0x12

#define GDT_DPL_KERNEL 0x00
#define GDT_DPL_USER 0x03

typedef struct __attribute__((packed)) {
uint32_t Reserved0;
uint64_t Rsp0;
uint64_t Rsp1;
uint64_t Rsp2;
uint64_t Ist[8];
uint64_t Reserved1;
uint16_t Reserved2;
uint16_t IoMapBase;
} HalpTssEntry;

typedef union {
struct __attribute__((packed)) {
struct __attribute__((packed)) {
uint64_t LimitLow : 16;
uint64_t BaseLow : 24;
uint64_t Type : 5;
uint64_t Dpl : 2;
uint64_t Present : 1;
uint64_t LimitHigh : 4;
uint64_t System : 1;
uint64_t LongMode : 1;
uint64_t DefaultBig : 1;
uint64_t Granularity : 1;
uint64_t BaseHigh : 8;
};
uint32_t BaseUpper;
uint32_t MustBeZero;
};
struct __attribute__((packed)) {
uint64_t DataLow;
uint64_t DataHigh;
};
} HalpGdtEntry;

typedef struct __attribute__((packed)) {
uint16_t Limit;
uint64_t Base;
} HalpGdtDescriptor;

#endif /* _AMD64_GDT_H_ */
8 changes: 3 additions & 5 deletions src/kernel/include/public/amd64/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#ifndef _AMD64_PROCESSOR_H_
#define _AMD64_PROCESSOR_H_

#include <amd64/gdt.h>
#include <ps.h>
#include <rt/list.h>

Expand All @@ -20,11 +21,8 @@ typedef struct {
RtDList DpcQueue;
RtDList EventQueue;
char SystemStack[8192] __attribute__((aligned(4096)));
uint64_t GdtEntries[5];
struct __attribute__((packed)) __attribute__((aligned(4))) {
uint16_t Limit;
uint64_t Base;
} GdtDescriptor;
char GdtEntries[56];
HalpTssEntry TssEntry;
struct __attribute__((packed)) {
uint16_t BaseLow;
uint16_t Cs;
Expand Down

0 comments on commit 682a6bf

Please sign in to comment.