-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4 from iomonad/gdt-implementation
GDT Kernel Implementation
- Loading branch information
Showing
15 changed files
with
292 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
;; | ||
;; (c) 2020 iomonad <clement@trosa.io> | ||
;; This is part of the KFS Project | ||
;; See: https://github.com/iomonad/KFS | ||
;; | ||
|
||
bits 32 | ||
|
||
;; Global Descriptor Table Implementation | ||
;; See: | ||
;; - https://wiki.osdev.org/Global_descriptor_table | ||
;; | ||
;; A vital part of the 386's various protection | ||
;; measures is the GDT. It defines base accecss privilege | ||
;; for certain parts of memory. | ||
;; -- | ||
;; One of the key use is to generate violation exceptions | ||
;; that give kernel a way to end process that | ||
;; doing unauthorized memory access. | ||
;; -- | ||
;; An important thing to know is that GRUB AUTOMATICALLY install | ||
;; GDT when create rescue disk or installed on device. | ||
;; If grub memory area is overrided, the GDT is trashed up | ||
;; and will cause a 'Triple-Fault' (Basically will reset machine) | ||
;; To prevent that, we should implement our own GDT in a place that | ||
;; we know and have possibility to access. | ||
;; -- | ||
;; * In short terms, to build our GDT, we should: | ||
;; - Tell processor were it is located | ||
;; - Load [CS-DS-ES-FS-GS] Registers to our entry. | ||
;; * Behaviour to keep in mind: | ||
;; - The Code Segment (CS) tell processor which offset into | ||
;; the GDT that it will find the access privileges in which to | ||
;; execute the current code. | ||
;; - The Data Segment (DS) have the same idea but not for code, | ||
;; it's the Data segment and defines the access privileges for. | ||
;; the current data. | ||
;; - [ES,FS,GS] are used as alternate DS registers. | ||
;; * GDT Architecture | ||
;; - It's a list of 64-bits long entries. | ||
;; - These entries define where in memory that the allowed region | ||
;; will start, as well as the limit of this region, and the | ||
;; access privileges associated with this entry. | ||
;; - It's important to have the first entry of our GDT set as NULL, | ||
;; also known as the `NULL Descriptor`. | ||
;; - Also, no segments regisers should be set to 0, otherwise it | ||
;; will raise a General Protection fault, an protection | ||
;; feature of the processor. | ||
global _gdt_commit | ||
extern _gdtptr ; GDT Pointer globally defined | ||
|
||
_gdt_commit: | ||
lgdt [_gdtptr] ; Load GDT to our global ptr | ||
mov ax, 0x10 ; Data segment offset from our GDT | ||
mov ds, ax | ||
mov es, ax | ||
mov fs, ax | ||
mov gs, ax | ||
mov ss, ax | ||
jmp 0x08:_kflush ; Code segment offset jump | ||
_kflush: | ||
ret ; Leave state and return to C implementation |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
* | ||
* (c) 2020 iomonad <clement@trosa.io> | ||
* | ||
* This is part of the KFS Project | ||
* See: https://github.com/iomonad/KFS | ||
* | ||
*/ | ||
#ifndef GDT_H | ||
#define GDT_H | ||
|
||
#include <types.h> | ||
#include <kernel.h> | ||
|
||
#define GDT_SIZE 3 | ||
|
||
/* | ||
* Modelize an GDT entry | ||
*/ | ||
struct _kgdt_entry { | ||
uint16_t limit_low; | ||
uint16_t base_low; | ||
uint8_t base_middle; | ||
uint8_t access; | ||
uint8_t granularity; | ||
uint8_t base_high; | ||
} __attribute__ ((packed)); | ||
|
||
/* | ||
* Modelize a pointer that implement | ||
* an limit wich basically is the max | ||
* bytes taken up by the GDT-1. | ||
*/ | ||
struct _kgdt_ptr { | ||
uint16_t limit; | ||
uint32_t base; | ||
} __attribute__ ((packed)); | ||
|
||
/* | ||
* Flush function that reload | ||
* our Segment registers. | ||
*/ | ||
extern void _gdt_commit(void); | ||
|
||
/* Prototypes */ | ||
|
||
void install_system_gdt(void);; | ||
void kgdt_add_entry(uint8_t index, uint64_t base, uint64_t limit, | ||
uint8_t access, uint8_t granularity); | ||
|
||
#endif /* GDT_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/* | ||
* | ||
* (c) 2020 iomonad <clement@trosa.io> | ||
* | ||
* This is part of the KFS Project | ||
* See: https://github.com/iomonad/KFS | ||
* | ||
*/ | ||
#include <gdt.h> | ||
#include <kernel.h> | ||
|
||
/* Global In memory GDT datastructure */ | ||
struct _kgdt_entry gdt[GDT_SIZE]; | ||
struct _kgdt_ptr _gdtptr; | ||
|
||
/* | ||
* Add new descriptor to the table wo/ flush | ||
*/ | ||
void kgdt_add_entry(uint8_t index, uint64_t base, uint64_t limit, | ||
uint8_t access, uint8_t granularity) | ||
{ | ||
/* BASE ADDR SETUP */ | ||
gdt[index].base_low = (base & 0xFFFF); | ||
gdt[index].base_middle = (base >> 16) & 0xFF; | ||
gdt[index].base_high = (base >> 24) & 0xFF; | ||
|
||
/* LIMIT SETUP */ | ||
gdt[index].limit_low = (limit & 0xFFFF); | ||
gdt[index].granularity = ((limit >> 16) & 0x0F); | ||
|
||
/* GRANULARITY & ACCESS */ | ||
gdt[index].granularity |= (granularity & 0xF0); | ||
gdt[index].access = access; | ||
} | ||
|
||
/* | ||
* GDT Setup | ||
*/ | ||
void install_system_gdt(void) | ||
{ | ||
/* | ||
* Initialize convenient structure | ||
*/ | ||
_gdtptr.limit = (sizeof(struct _kgdt_entry) * GDT_SIZE) - 1; | ||
_gdtptr.base = (uint32_t)&gdt; | ||
|
||
/* Stick to standard guideline */ | ||
kgdt_add_entry(0x00, 0, 0, 0, 0); | ||
|
||
/* | ||
* Code Segment: | ||
* ------------- | ||
* Parameters: | ||
* -> Slot: 1 | ||
* -> Base Address: 0 | ||
* -> Segment Limit: 4GB | ||
* -> Access: 0x9A (for code) | ||
* -> Granularity: 4kb | ||
*/ | ||
kgdt_add_entry(0x01, 0, 0xFFFFFFFF, 0x9A, 0xCF); | ||
|
||
/* | ||
* Data Segment: | ||
* ------------- | ||
* -> Slot: 1 | ||
* -> Base Address: 0 | ||
* -> Segment Limit: 4GB | ||
* -> Access: 0x92 (for data) | ||
* -> Granularity: 4kb | ||
*/ | ||
kgdt_add_entry(0x02, 0, 0xFFFFFFFF, 0x92, 0xCF); | ||
|
||
_gdt_commit(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* entry point of our kernel */ | ||
ENTRY(kfs_entry) | ||
|
||
SECTIONS | ||
{ | ||
/* we need 1MB of space atleast */ | ||
. = 1M; | ||
|
||
/* text section */ | ||
.text BLOCK(4K) : ALIGN(4K) { | ||
*(.multiboot) | ||
*(.text) | ||
} | ||
|
||
/* read only data section */ | ||
.rodata BLOCK(4K) : ALIGN(4K) { | ||
*(.rodata) | ||
} | ||
|
||
/* data section */ | ||
.data BLOCK(4K) : ALIGN(4K) { | ||
*(.data) | ||
} | ||
|
||
/* bss section */ | ||
.bss BLOCK(4K) : ALIGN(4K) { | ||
*(COMMON) | ||
*(.bss) | ||
} | ||
} |
Oops, something went wrong.