diff --git a/Makefile b/Makefile index 97dea92..6ed38d0 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -OBJECTS = loader.o load_gdt.o gdt.o serial.o framebuffer.o io.o kmain.o +OBJECTS = loader.o serial.o framebuffer.o io.o kmain.o CC = gcc CFLAGS = -m32 -nostdlib -nostdinc -fno-builtin -fno-stack-protector \ diff --git a/include/gdt.h b/include/gdt.h deleted file mode 100644 index 9eb56f6..0000000 --- a/include/gdt.h +++ /dev/null @@ -1,144 +0,0 @@ -/** @file gdt.h - * @brief Configuration de la Table de Description Globale ou GDT. Utilisée - * pour pouvoir gerer la memoire sous forme de segments. - * - * 1. Il faut en premier initialiser le registre @c gdtr avec l'adresse et la - * taille de la GDT. - * 2. Charger ensuite dans les registres @c cs et @c ds des sélecteurs de - * segments - * 3. Charger dans la GDT des descripteurs de segments. Le premier est toujours - * nul, le deuxième est le segment pour le code du noyau et le troisième pour - * les données. - * - * Références: - * - Documentation Intel (volume 3A): - * https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html - * - De manière globale : les parties 2 et 3 - * - Partie 3.4.3 : registres de segments - * - Figure 3-11 : structure à charger dans le registre @c gdtr - * - Figure 3-5 : illustration de la transformation d'une adresse logique - * en adresse linéaire - * - Figure 3-6 : anatomie d'un sélecteur de segment - * - Figure 3-8 : anatomie d'un descripteur de segment - * - Table 3-1 : type de segment (donnée et code) - * - chargement de @c gdtr https://www.felixcloutier.com/x86/lgdt:lidt - * - explication sur les sélecteurs de segments - * https://wiki.osdev.org/Segment_Selector - * - explication sur la segmentation et plus particulièrement les registres de - * segmentation : https://wiki.osdev.org/Segmentation - * - tutoriel pour inialiser la GDT : https://wiki.osdev.org/GDT_Tutorial - * - documentation en français (rapidement survolée) : - * https://wiki.osdev.org/GDT_Tutorial - */ - -/** @struct gdt_entry - * - * Structure qui sera passée à la fonction load_gdt(). Elle est utilisée pour - * rassembler la taille et l'adresse de la GDT en un seul type de 6 bytes. - * - * Voir section 3.5.1 du volume 3A du manuel d'Intel. - */ -struct gdt_entry -{ - /** - * La taille de la GDT en bytes. Elle doit être éguale à 8N - 1, à cause de - * la taille des segments (1 segment = 8 bytes). - */ - unsigned short size; - /** - * L'adresse de la GDT, doit être alignée sur un multiple de 8 pour avoir - * de meilleures performances. - */ - unsigned int address; -}__attribute__((packed)); - -/** @struct segment_descriptor - * - * Un descripteur de segment est chargé dans la GDT. Il contient 8 bytes, - * séparés en 2 @c unsigned @c int. - * - * Premier int : - * | 0 - 15 | 16 - 31 | - * |----------------------------|--------------------------| - * | Limite du segment (0 - 15) | Adresse de base (0 - 15) | - * - * Deuxième int : - * | 0 - 7 | 8 - 11 | 12 | 13 - 14 | 15 | 16 - 19 | 20 | 21 | 22 | 23 | 24 - 31 | - * |---------------------------|--------------|-----------------|------------------------------------|-----------------|-----------------------------|---------------|--------------------|------------------------|-------------|----------------------------| - * | Adresse de base (16 - 23) | Segment type | Descriptor Type | Niveau de privilège du descripteur | Segment present | Limite du segment (16 - 19) | Disponibilité | 64bit code semgent | Default operation size | Granularité | Adresse de base (24 - -31) | - * - * @note Cette structure a été codée pour répondre à un besoin : comment - * simplifier la création de descripteurs de segments. Il s'agit d'un choix - * d'implémentation que j'ai fait et qui n'est pas indiqué dans la - * documentation Intel ou dans <EM> The little book about OS development </EM>. - */ -struct segment_descriptor -{ - /** Contient les bytes 0 à 3 (base + limite). */ - unsigned int first_bytes; - /** Contient les bytes 4 à 7 (base + limite + drapeaux). */ - unsigned int last_bytes; -}__attribute__((packed)); - -/** - * Créer une valeur de sélecteur de segment. - * - * @param index l'index du segment dans la GDT - * @param type le type de table (0 = GDT, 1 = LDT) - * @param rpl le niveau de privilège (0 = le +, 3 = le -) - */ -unsigned short create_selector(unsigned short index, unsigned char type, - unsigned char rpl); - -/** - * Va charger la structure passée en paramètre comme GDT au processeur. Appelle - * l'instruction @c lgdt, qui prend en paramètre 6 bytes, d'où l'utilisation de - * la structure. - * - * @param entry les informations de la GDT à charger - */ -void load_gdt(struct gdt_entry *entry); - -/** - * Charge dans le registre @c cs le sélecteur 0x08. - */ -void load_cs(void); - -/** - * Charge dans les registres @c ds, @c es et @c ss un sélecteur de segment. - * - * @param selector le sélecteur à charger - */ -void load_registers(void); - -/** - * Créer une structure gdt_entry. - * - * @param start : l'adresse de départ - * @param n : le nombre d'éléments dedans - */ -struct gdt_entry create_gdt_entry(unsigned int start, unsigned short n); - -/** - * Créer un descripteur de segment. - * - * @param base l'adresse de base en mémoire - * @param limit la limite du segment - * @param dpl niveau de privilège du semgent (0 le +, 3 le -) - * @param segment_type les autorisations en écriture / exécution du segment - * (cf. table 3-1) - */ -struct segment_descriptor create_descriptor(unsigned int base, unsigned int - limit, unsigned char dpl, unsigned char segment_type); - -/** - * Ajoute un descripteur de segment dans la GDT. - * - * @param i : l'index dans la GDT (sera calculé pour l'insérer au bon endroit) - * @param start : l'adresse du début de la GDT - * @param desc : le descripteur à insérer - */ -void add_in_gdt(unsigned int i, unsigned int start, struct segment_descriptor - desc); - -void config_gdt(void); diff --git a/kmain.c b/kmain.c index 1420d57..e706548 100644 --- a/kmain.c +++ b/kmain.c @@ -1,6 +1,4 @@ #include "framebuffer.h" -#include "serial.h" -#include "gdt.h" unsigned int write(char *buf, unsigned int len) { @@ -29,13 +27,7 @@ int strlen(char *buf) void kmain(void) { - char *str = "Port série prêt pour la communication."; - char *fb_str = "Framebuffer fonctionnel."; - int len = strlen(fb_str); - write(fb_str, len); - - config_gdt(); - serial_set_baud(COM1_PORT, 5); - serial_config(COM1_PORT); - serial_write(COM1_PORT, str, strlen(str)); + char *str = "pouet pouet"; + int len = strlen(str); + write(str, len); } diff --git a/src/gdt.c b/src/gdt.c deleted file mode 100644 index cd42df2..0000000 --- a/src/gdt.c +++ /dev/null @@ -1,65 +0,0 @@ -#include "gdt.h" - -unsigned short create_selector(unsigned short index, unsigned char type, - unsigned char rpl) -{ - unsigned short ret = 0; - ret += index << 3; - ret += type & 0x0004; - ret += rpl & 0x0003; - return ret; -} - -struct gdt_entry create_gdt_entry(unsigned int start, unsigned short n) -{ - struct gdt_entry ret; - ret.size = ((n * 8) - 1) & 0xFFFF; - ret.address = start; - return ret; -} - -struct segment_descriptor create_descriptor(unsigned int base, unsigned int - limit, unsigned char dpl, unsigned char segment_type) -{ - /* - unsigned short base_1 = (base & 0x0000FFFF) << 4; - unsigned char base_2 = (base & 0x00FF0000) << 2; - unsigned char base_3 = (base & 0xFF000000); - unsigned short limit_1 = (limit & 0x0000FFFF) << 4; - */ - - struct segment_descriptor ret; - ret.first_bytes = (base & 0x0000FFFF) + ((limit & 0x0000FFFF) << 16); - ret.last_bytes = ((base & 0x00FF0000) >> 16) + (((segment_type & 0x0F) + - ((dpl & 0x03) << 5) + 0x90) << 8 ) + (limit & 0x000F0000) + - (base & 0xFF000000); - - return ret; -} - -void add_in_gdt(unsigned int i, unsigned int start, struct segment_descriptor - desc) -{ - int index = i * 8; - struct segment_descriptor *ptr = (struct segment_descriptor *) start; - - *(ptr + index) = desc; -} - -void config_gdt(void) -{ - /* int base = 0x00000010; */ - int base = 0x00008f60; - struct gdt_entry entry = create_gdt_entry(base, 10); - /* unsigned short data_selector = create_selector(2, 0, 0); */ - struct segment_descriptor null = {0, 0}; - struct segment_descriptor code_kernel = create_descriptor(0, 0xFFFFFFFF, 0, 0x0A); - struct segment_descriptor data_kernel = create_descriptor(0, 0xFFFFFFFF, 0, 0x02); - - load_cs(); - load_registers(); - add_in_gdt(0, base, null); - add_in_gdt(1, base, code_kernel); - add_in_gdt(2, base, data_kernel); - load_gdt(&entry); -} diff --git a/src/load_gdt.s b/src/load_gdt.s deleted file mode 100644 index 2049533..0000000 --- a/src/load_gdt.s +++ /dev/null @@ -1,22 +0,0 @@ -global load_gdt -global load_cs -global load_registers - -load_gdt: - mov eax, [esp + 4] - lgdt [eax] - ret - -; https://www.felixcloutier.com/x86/jmp -load_cs: - jmp 0x08:flush_cs -flush_cs: - ret - -load_registers: - ;mov ax, [esp + 4] - mov ax, 0x0010 - mov ds, ax - mov ss, ax - mov es, ax - ret diff --git a/src/serial.c b/src/serial.c index c30bbca..0430fd6 100644 --- a/src/serial.c +++ b/src/serial.c @@ -1,5 +1,4 @@ #include "io.h" -#include "serial.h" void serial_set_baud(unsigned short port, unsigned short div) {