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 "hal.h"
|
||||||
|
#include "../arch/i686/gdt.h"
|
||||||
#include "../arch/i686/idt.h"
|
#include "../arch/i686/idt.h"
|
||||||
|
|
||||||
void hal_initialize(){
|
void hal_initialize(){
|
||||||
|
i686_gdt_initialize();
|
||||||
i686_idt_initialize();
|
i686_idt_initialize();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Referencia en una nova incidència