réplica de
https://github.com/Arnau478/quark.git
synced 2024-11-23 12:58:07 +01:00
Implemented GDT
This commit is contained in:
pare
29093837a3
commit
15386c43ba
S'han modificat 4 arxius amb 130 adicions i 0 eliminacions
31
src/kernel/arch/i686/gdt.asm
Normal file
31
src/kernel/arch/i686/gdt.asm
Normal file
|
@ -0,0 +1,31 @@
|
|||
[bits 32]
|
||||
|
||||
global i686_gdt_load
|
||||
i686_gdt_load:
|
||||
; New call frame
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
|
||||
; Load GDT
|
||||
mov eax, [ebp + 8]
|
||||
lgdt [eax]
|
||||
|
||||
; Reload code segment
|
||||
mov eax, [ebp + 12]
|
||||
push eax
|
||||
push .reload_cs
|
||||
retf
|
||||
|
||||
.reload_cs:
|
||||
; Reload data segments
|
||||
mov ax, [ebp + 16]
|
||||
mov dx, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
|
||||
; Restore old call frame
|
||||
mov esp, ebp
|
||||
push ebp
|
||||
ret
|
91
src/kernel/arch/i686/gdt.c
Normal file
91
src/kernel/arch/i686/gdt.c
Normal file
|
@ -0,0 +1,91 @@
|
|||
#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,
|
||||
0xFFFF,
|
||||
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,
|
||||
0xFFFF,
|
||||
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);
|
||||
}
|
6
src/kernel/arch/i686/gdt.h
Normal file
6
src/kernel/arch/i686/gdt.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#define i686_GDT_CODE_SEGMENT 0x08
|
||||
#define i686_GDT_DATA_SEGMENT 0x10
|
||||
|
||||
void i686_gdt_initialize();
|
|
@ -1,6 +1,8 @@
|
|||
#include "hal.h"
|
||||
#include "../arch/i686/gdt.h"
|
||||
#include "../arch/i686/idt.h"
|
||||
|
||||
void hal_initialize(){
|
||||
i686_gdt_initialize();
|
||||
i686_idt_initialize();
|
||||
}
|
||||
|
|
Loading…
Referencia en una nova incidència