réplica de
https://github.com/Arnau478/quark.git
synced 2024-05-19 20:36:31 +02:00
92 líneas
2,3 KiB
C
92 líneas
2,3 KiB
C
#include <stdint.h>
|
|
#include "gdt.h"
|
|
|
|
typedef struct{
|
|
uint16_t limit_low;
|
|
uint16_t base_low;
|
|
uint8_t base_middle;
|
|
uint8_t access;
|
|
uint8_t flags_limit_high;
|
|
uint8_t base_high;
|
|
} __attribute__((packed)) gdt_entry;
|
|
|
|
typedef struct{
|
|
uint16_t limit;
|
|
gdt_entry *ptr;
|
|
} __attribute__((packed)) gdt_descriptor;
|
|
|
|
typedef enum{
|
|
GDT_ACCESS_CODE_READABLE = 0x02,
|
|
GDT_ACCESS_DATA_WRITEABLE = 0x02,
|
|
|
|
GDT_ACCESS_CODE_CONFORMING = 0x04,
|
|
GDT_ACCESS_DATA_DIRECTION_NORMAL = 0x00,
|
|
GDT_ACCESS_DATA_DIRECTION_DOWN = 0x04,
|
|
|
|
GDT_ACCESS_DATA_SEGMENT = 0x10,
|
|
GDT_ACCESS_CODE_SEGMENT = 0x18,
|
|
|
|
GDT_ACCESS_DESCRIPTOR_TSS = 0x00,
|
|
|
|
GDT_ACCESS_RING0 = 0x00,
|
|
GDT_ACCESS_RING1 = 0x20,
|
|
GDT_ACCESS_RING2 = 0x40,
|
|
GDT_ACCESS_RING3 = 0x60,
|
|
|
|
GDT_ACCESS_PRESENT = 0x80,
|
|
} GDT_ACCESS;
|
|
|
|
typedef enum{
|
|
GDT_FLAG_64BIT = 0x20,
|
|
GDT_FLAG_32BIT = 0x40,
|
|
GDT_FLAG_16BIT = 0x00,
|
|
|
|
GDT_FLAG_GRANULARITY_1B = 0x00,
|
|
GDT_FLAG_GRANULARITY_4K = 0x80,
|
|
} GDT_FLAGS;
|
|
|
|
// Helpful macros
|
|
#define GDT_LIMIT_LOW(limit) ((limit) & 0xFFFF)
|
|
#define GDT_BASE_LOW(base) ((base) & 0xFFFF)
|
|
#define GDT_BASE_MIDDLE(base) (((base) >> 16) & 0xFF)
|
|
#define GDT_FLAGS_LIMIT_HIGH(limit, flags) ((((limit) >> 16) & 0xF) | ((flags) & 0xF0))
|
|
#define GDT_BASE_HIGH(base) (((base) >> 24) & 0xFF)
|
|
|
|
#define GDT_ENTRY(base, limit, access, flags) { \
|
|
GDT_LIMIT_LOW(limit), \
|
|
GDT_BASE_LOW(base), \
|
|
GDT_BASE_MIDDLE(base), \
|
|
access, \
|
|
GDT_FLAGS_LIMIT_HIGH(limit, flags), \
|
|
GDT_BASE_HIGH(base), \
|
|
}
|
|
|
|
static gdt_entry g_gdt[] = {
|
|
// Null descriptor
|
|
GDT_ENTRY(0, 0, 0, 0),
|
|
|
|
// Kernel 32-bit code segment
|
|
GDT_ENTRY(
|
|
0,
|
|
0xFFFFF,
|
|
GDT_ACCESS_PRESENT | GDT_ACCESS_RING0 | GDT_ACCESS_CODE_SEGMENT | GDT_ACCESS_CODE_READABLE,
|
|
GDT_FLAG_32BIT | GDT_FLAG_GRANULARITY_4K
|
|
),
|
|
|
|
// Kernel 32-bit data segment
|
|
GDT_ENTRY(
|
|
0,
|
|
0xFFFFF,
|
|
GDT_ACCESS_PRESENT | GDT_ACCESS_RING0 | GDT_ACCESS_DATA_SEGMENT | GDT_ACCESS_DATA_WRITEABLE,
|
|
GDT_FLAG_32BIT | GDT_FLAG_GRANULARITY_4K
|
|
),
|
|
};
|
|
|
|
static gdt_descriptor g_gdt_descriptor = {sizeof(g_gdt) - 1, g_gdt};
|
|
|
|
void __attribute__((cdecl)) i686_gdt_load(gdt_descriptor *descriptor, uint16_t code_segment, int16_t data_segment);
|
|
|
|
void i686_gdt_initialize(){
|
|
i686_gdt_load(&g_gdt_descriptor, i686_GDT_CODE_SEGMENT, i686_GDT_DATA_SEGMENT);
|
|
}
|