diff --git a/README.md b/README.md index 41c4102..065bb37 100644 --- a/README.md +++ b/README.md @@ -109,10 +109,22 @@ Commandes de compilation de COS2000 * ```make test64``` lance l'émulation QEMU en 64 bits sur disque dur UEFI * ```make clean``` supprime les fichers compilés -Pour tester fait donc un simple ```make test``` qui compilera et émulera le système directement. - #### Utilisation +##### Sur un ordinateur émulé + +Pour tester l'OS en émulation taper donc la commande ```make test``` qui compilera avant de lancer Qemu. + +##### Sur un ordinateur physique + +Il faut d'abord copier l'image sur une clé (Attention l'opération effacera le contenu de la clé) : + +```dd if=./final/harddisk.img.final of=/dev/sdx bs=1M``` (ou sdx est votre périphérique) + +Bootez sur votre clé en mode bios (legacy). Il est possible que des dysfonctionnement apparaissent sur des machine x86_64 (en cours de résolution). + +##### Usage de COS2000 + Pour l'instant quelques commandes seulement sont disponibles: * REBOOT redémarre le PC, diff --git a/include/gdt.h b/include/gdt.h index f7afc17..fff1490 100755 --- a/include/gdt.h +++ b/include/gdt.h @@ -1,19 +1,43 @@ #include /* Ordre imposé par SYSENTER */ -#define SEL_KERNEL_CODE 0x8 /* selecteur code du kernel */ -#define SEL_KERNEL_STACK 0x10 /* selecteur pile du kernel */ -#define SEL_USER_CODE 0x18 /* selecteur code utilisateur */ -#define SEL_USER_STACK 0x20 /* selecteur pile utilisateur */ -#define SEL_KERNEL_DATA 0x28 /* selecteur data du kernel */ -#define SEL_USER_DATA 0x30 /* selecteur data utilisateur */ +#define SEL_KERNEL_CODE 0x8 /* Selecteur code du kernel */ +#define SEL_KERNEL_STACK 0x10 /* Selecteur pile du kernel */ +#define SEL_USER_CODE 0x18 /* Selecteur code utilisateur */ +#define SEL_USER_STACK 0x20 /* Selecteur pile utilisateur */ +#define SEL_KERNEL_DATA 0x28 /* Selecteur data du kernel */ +#define SEL_USER_DATA 0x30 /* Selecteur data utilisateur */ -#define SEL_TSS 0x38 /* selecteur TSR */ +#define SEL_TSS 0x38 /* Selecteur TSR */ -#define STACK_OFFSET 0xFFFF /* adresse de la pile du kernel */ +#define GDT_SIZE 0x8 /* Nombre de descripteurs */ -#define SIZEGDT 0x8 /* nombre de descripteurs */ -#define BASEGDT 0x00000800 /* addr de la GDT */ +/* Drapeau des descripteurs GDT */ +#define GRANULARITY_4K 0b00001000 /* Granularité alignement 4096 octet*/ +#define GRANULARITY_1B 0b00000000 /* Granularité alignement 1 octet */ +#define OPSIZE_32B 0b00000100 /* Taille opérandes 32 bits*/ +#define OPSIZE_16B 0b00000000 /* Taille opérandes 16 bits*/ +#define SYS_AVAILABLE 0b00000001 /* Disponible pour le système (à définir)*/ + +#define SEG_ACCESSED 0b00000001 /* Segment accédé (code ou data) */ + +#define SEG_DATA 0b00000000 /* Segment de données */ +#define SEG_CODE 0b00001000 /* Segment de données */ + +#define SEG_READ_WRITE 0b00000010 /* Segment lecture-ecriture (data) */ +#define SEG_EXPAND_DOWN 0b00000100 /* Segment avec expand-down (data) */ + +#define SEG_READ 0b00000010 /* Segment lecture (code) */ +#define SEG_CONFORMING 0b00000100 /* Segment conforming (code) */ + +#define SEG_PRESENT 0b10000000 /* Segment défini (obligatoire) */ + +#define SEG_RING0 0b00000000 /* Segment anneau 0 */ +#define SEG_RING1 0b00100000 /* Segment anneau 0 */ +#define SEG_RING2 0b01000000 /* Segment anneau 0 */ +#define SEG_RING3 0b01100000 /* Segment anneau 0 */ + +#define SEG_NORMAL 0b00010000 /* Segment normal pile/data/code (0 pour système) */ typedef struct gdtdes { u16 lim0_15; diff --git a/include/interrupts.h b/include/interrupts.h index 0b28e20..d0aee52 100755 --- a/include/interrupts.h +++ b/include/interrupts.h @@ -20,11 +20,11 @@ #define ICW4_BUF_MASTER 0x0C /* mode/master avec tampon*/ #define ICW4_SFNM 0x10 /* Complètement lié ou non */ -#define INTGATE 0x8E00 /* utilise pour gerer les interruptions */ -#define TRAPGATE 0x8F00 /* utilise pour faire des appels systemes */ -#define TASKGATE 0x8500 /* utilise pour commuter des taches */ -#define CALLGATE 0x8C00 /* utilise pour appeler du code */ -#define LDTDES 0x8200 /* utilise pour pointer une LDT */ +#define INTGATE 0x8E00 /* utilise pour gerer les interruptions */ +#define TRAPGATE 0x8F00 /* utilise pour faire des appels systemes */ +#define TASKGATE 0x8500 /* utilise pour commuter des taches */ +#define CALLGATE 0x8C00 /* utilise pour appeler du code */ +#define LDTDES 0x8200 /* utilise pour pointer une LDT */ /* 00-11-010-0 : Compteur 0 - LSB puis MSB - generateur taux - binaire */ #define TIMER0 0x40 /* port E/S pour le timer canal 0 */ diff --git a/include/memory.h b/include/memory.h index c4ea666..7ee7064 100755 --- a/include/memory.h +++ b/include/memory.h @@ -3,6 +3,29 @@ /* */ #include "types.h" +#define PAGESIZE 4096 /* Taille d'une page */ +#define PAGENUMBER 1024 /* Nombre de pages */ + +#define IDT_ADDR 0x00000000 /* adresse de la IDT */ +#define GDT_ADDR 0x00000800 /* adresse de la GDT */ +#define KERNEL_PGD_ADDR 0x00001000 /* adresse de la page directory */ +#define KERNEL_STACK_ADDR 0x0009FFFF /* adresse de la pile du kernel */ +#define KERNEL_CODE_ADDR 0x00100000 + +/* page directory */ +#define PAGE_PRESENT 0b000000001/* page directory / table */ +#define PAGE_WRITE 0b000000010 /* page lecture ecriture */ +#define PAGE_ALL 0b000000100 /* accessible user & supervisor */ +#define PAGE_WTROUGH 0b000001000 /* write-through cache */ +#define PAGE_NOCACHE 0b000010000 /* cache desactivé */ +#define PAGE_ACCESS 0b000100000 /* cache desactivé */ +#define PAGE_4MB 0b010000000 /* page de 4mb au lieu de 4k (NECESSITE PSE)*/ + +/* page table */ +#define PAGE_CACHE 0b000010000 /* page en cache */ +#define PAGE_DIRTY 0b001000000 /* page écrite */ +#define PAGE_GLOBAL 0b100000000 /* évite que le TLB mette à jour l'adresse dans le cache si CR4 est remis à zéro (NECESSITE CR4) */ + void memset(void *dst, u8 val, u32 count,u32 size); void memcpy(void *src, void *dst, u32 count, u32 size); u32 memcmp(void *src, void *dst, u32 count, u32 size); diff --git a/lib/gdt.c b/lib/gdt.c index 999d201..77c12b7 100755 --- a/lib/gdt.c +++ b/lib/gdt.c @@ -4,12 +4,13 @@ #include "gdt.h" #include "asm.h" #include "types.h" +#include "memory.h" /* registre gdt */ static struct gdtr gdtreg; /* table de GDT */ -static gdtdes gdt[SIZEGDT]; +static gdtdes gdt[GDT_SIZE]; /* TSS */ static struct tss tss0; @@ -20,23 +21,23 @@ static struct tss tss0; void initgdt(u32 offset) { makegdtdes(0x0, 0x00000, 0x00, 0x00, &gdt[0]); /* descripteur nul */ - makegdtdes(0x0, 0xFFFFF, 0x9B, 0x0D, &gdt[1]); /* code -> SEL_KERNEL_CODE */ - makegdtdes(0x0, 0x00000, 0x97, 0x0D, &gdt[2]); /* pile -> SEL_KERNEL_STACK */ - makegdtdes(0x0, 0xFFFFF, 0xFF, 0x0D, &gdt[3]); /* code -> SEL_USER_CODE */ - makegdtdes(0x0, 0x00000, 0xF7, 0x0D, &gdt[4]); /* pile -> SEL_USER_STACK */ - makegdtdes(0x0, 0xFFFFF, 0x93, 0x0D, &gdt[5]); /* data -> SEL_KERNEL_DATA */ - makegdtdes(0x0, 0xFFFFF, 0xF3, 0x0D, &gdt[6]); /* data -> SEL_USER_DATA */ + makegdtdes(0x0, 0xFFFFF, SEG_PRESENT | SEG_NORMAL | SEG_CODE | SEG_RING0 | SEG_READ | SEG_ACCESSED, GRANULARITY_4K | OPSIZE_32B | SYS_AVAILABLE, &gdt[1]); /* code -> SEL_KERNEL_CODE */ + makegdtdes(0x0, 0x00000, SEG_PRESENT | SEG_NORMAL | SEG_DATA | SEG_RING0 | SEG_EXPAND_DOWN | SEG_READ_WRITE | SEG_ACCESSED, GRANULARITY_4K | OPSIZE_32B | SYS_AVAILABLE, &gdt[2]); /* pile -> SEL_KERNEL_STACK */ + makegdtdes(0x0, 0xFFFFF, SEG_PRESENT | SEG_NORMAL | SEG_CODE | SEG_RING3 | SEG_CONFORMING | SEG_READ | SEG_ACCESSED, GRANULARITY_4K | OPSIZE_32B | SYS_AVAILABLE, &gdt[3]); /* code -> SEL_USER_CODE */ + makegdtdes(0x0, 0x00000, SEG_PRESENT | SEG_NORMAL | SEG_DATA | SEG_RING3 | SEG_EXPAND_DOWN | SEG_READ_WRITE | SEG_ACCESSED, GRANULARITY_4K | OPSIZE_32B | SYS_AVAILABLE, &gdt[4]); /* pile -> SEL_USER_STACK */ + makegdtdes(0x0, 0xFFFFF, SEG_PRESENT | SEG_NORMAL | SEG_DATA | SEG_RING0 | SEG_READ_WRITE | SEG_ACCESSED, GRANULARITY_4K | OPSIZE_32B | SYS_AVAILABLE, &gdt[5]); /* data -> SEL_KERNEL_DATA */ + makegdtdes(0x0, 0xFFFFF, SEG_PRESENT | SEG_NORMAL | SEG_DATA | SEG_RING3 | SEG_READ_WRITE | SEG_ACCESSED, GRANULARITY_4K | OPSIZE_32B | SYS_AVAILABLE, &gdt[6]); /* data -> SEL_USER_DATA */ tss0.trapflag = 0x00; tss0.iomap = 0x00; tss0.esp0 = 0x1FFF0; tss0.ss0 = SEL_TSS; - makegdtdes(&tss0, 0x67, 0xE9, 0x00, &gdt[7]); /* descripteur de tss */ + makegdtdes(&tss0, 0x67, SEG_PRESENT | SEG_CODE | SEG_RING3 | SEG_ACCESSED , 0x00, &gdt[7]); /* descripteur de tss */ /* initialise le registre gdt */ - gdtreg.limite = SIZEGDT * 8; - gdtreg.base = BASEGDT; + gdtreg.limite = GDT_SIZE * 8; + gdtreg.base = GDT_ADDR; /* recopie de la GDT a son adresse */ memcpy(&gdt, (u8 *) gdtreg.base, gdtreg.limite, 1); /* chargement du registre GDT */ @@ -70,7 +71,7 @@ void initselectors(u32 executingoffset) ljmp %[code], $raz \n \ raz: \n \ pushl %%ebx \n \ - ret\n"::[data] "i"(SEL_KERNEL_DATA),[code] "i"(SEL_KERNEL_CODE),[stack] "i"(SEL_KERNEL_STACK),[stackoff] "i"(STACK_OFFSET),[offset] "m"(executingoffset)); + ret\n"::[data] "i"(SEL_KERNEL_DATA),[code] "i"(SEL_KERNEL_CODE),[stack] "i"(SEL_KERNEL_STACK),[stackoff] "i"(KERNEL_STACK_ADDR),[offset] "m"(executingoffset)); } /*******************************************************************************/ diff --git a/lib/interrupts.c b/lib/interrupts.c index 57418f1..f3daebe 100755 --- a/lib/interrupts.c +++ b/lib/interrupts.c @@ -6,16 +6,15 @@ #include "asm.h" #include "memory.h" #include "video.h" +#include "gdt.h" -#define SIZEIDT 256 /* nombre de descripteurs */ - -#define BASEIDT 0x00000000 /* addr de la IDT */ +#define IDT_SIZE 256 /* nombre de descripteurs */ /* registre idt */ static struct idtr idtreg; /* table de IDT */ -static idtdes idt[256]; +static idtdes idt[IDT_SIZE]; /******************************************************************************/ /* Initialise le controleur d'interruption 8259A */ @@ -131,9 +130,9 @@ void cpuerror(const u8 * src) print("\033[31m***** ERREUR CPU ****\r\n -"); print(src); dump_regs(); - while (true) { + /*while (true) { nop(); - } + }*/ } /******************************************************************************/ @@ -492,53 +491,53 @@ void irq15() void initidt(void) { u16 i; - putidt((u32) exception0, 0x20, INTGATE, 0); - putidt((u32) exception1, 0x20, INTGATE, 1); - putidt((u32) exception2, 0x20, INTGATE, 2); - putidt((u32) exception3, 0x20, INTGATE, 3); - putidt((u32) exception4, 0x20, INTGATE, 4); - putidt((u32) exception5, 0x20, INTGATE, 5); - putidt((u32) exception6, 0x20, INTGATE, 6); - putidt((u32) exception7, 0x20, INTGATE, 7); - putidt((u32) exception8, 0x20, INTGATE, 8); - putidt((u32) exception9, 0x20, INTGATE, 9); - putidt((u32) exception10, 0x20, INTGATE, 10); - putidt((u32) exception11, 0x20, INTGATE, 11); - putidt((u32) exception12, 0x20, INTGATE, 12); - putidt((u32) exception13, 0x20, INTGATE, 13); - putidt((u32) exception14, 0x20, INTGATE, 14); - putidt((u32) exception15, 0x20, INTGATE, 15); - putidt((u32) exception16, 0x20, INTGATE, 16); - putidt((u32) exception17, 0x20, INTGATE, 17); - putidt((u32) exception18, 0x20, INTGATE, 18); + putidt((u32) exception0, SEL_KERNEL_CODE, INTGATE, 0); + putidt((u32) exception1, SEL_KERNEL_CODE, INTGATE, 1); + putidt((u32) exception2, SEL_KERNEL_CODE, INTGATE, 2); + putidt((u32) exception3, SEL_KERNEL_CODE, INTGATE, 3); + putidt((u32) exception4, SEL_KERNEL_CODE, INTGATE, 4); + putidt((u32) exception5, SEL_KERNEL_CODE, INTGATE, 5); + putidt((u32) exception6, SEL_KERNEL_CODE, INTGATE, 6); + putidt((u32) exception7, SEL_KERNEL_CODE, INTGATE, 7); + putidt((u32) exception8, SEL_KERNEL_CODE, INTGATE, 8); + putidt((u32) exception9, SEL_KERNEL_CODE, INTGATE, 9); + putidt((u32) exception10, SEL_KERNEL_CODE, INTGATE, 10); + putidt((u32) exception11, SEL_KERNEL_CODE, INTGATE, 11); + putidt((u32) exception12, SEL_KERNEL_CODE, INTGATE, 12); + putidt((u32) exception13, SEL_KERNEL_CODE, INTGATE, 13); + putidt((u32) exception14, SEL_KERNEL_CODE, INTGATE, 14); + putidt((u32) exception15, SEL_KERNEL_CODE, INTGATE, 15); + putidt((u32) exception16, SEL_KERNEL_CODE, INTGATE, 16); + putidt((u32) exception17, SEL_KERNEL_CODE, INTGATE, 17); + putidt((u32) exception18, SEL_KERNEL_CODE, INTGATE, 18); for (i = 19; i < 32; i++) { putidt((u32) interruption, 0x20, TRAPGATE, i); } - putidt((u32) irq0, 0x20, INTGATE, 32); - putidt((u32) irq1, 0x20, INTGATE, 33); - putidt((u32) irq2, 0x20, INTGATE, 34); - putidt((u32) irq3, 0x20, INTGATE, 35); - putidt((u32) irq4, 0x20, INTGATE, 36); - putidt((u32) irq5, 0x20, INTGATE, 37); - putidt((u32) irq6, 0x20, INTGATE, 38); - putidt((u32) irq7, 0x20, INTGATE, 39); + putidt((u32) irq0, SEL_KERNEL_CODE, INTGATE, 32); + putidt((u32) irq1, SEL_KERNEL_CODE, INTGATE, 33); + putidt((u32) irq2, SEL_KERNEL_CODE, INTGATE, 34); + putidt((u32) irq3, SEL_KERNEL_CODE, INTGATE, 35); + putidt((u32) irq4, SEL_KERNEL_CODE, INTGATE, 36); + putidt((u32) irq5, SEL_KERNEL_CODE, INTGATE, 37); + putidt((u32) irq6, SEL_KERNEL_CODE, INTGATE, 38); + putidt((u32) irq7, SEL_KERNEL_CODE, INTGATE, 39); for (i = 40; i < 96; i++) { putidt((u32) interruption, 0x20, TRAPGATE, i); } - putidt((u32) irq8, 0x20, INTGATE, 96); - putidt((u32) irq9, 0x20, INTGATE, 97); - putidt((u32) irq10, 0x20, INTGATE, 98); - putidt((u32) irq11, 0x20, INTGATE, 99); - putidt((u32) irq12, 0x20, INTGATE, 100); - putidt((u32) irq13, 0x20, INTGATE, 101); - putidt((u32) irq14, 0x20, INTGATE, 102); - putidt((u32) irq15, 0x20, INTGATE, 103); - for (i = 104; i < SIZEIDT; i++) { + putidt((u32) irq8, SEL_KERNEL_CODE, INTGATE, 96); + putidt((u32) irq9, SEL_KERNEL_CODE, INTGATE, 97); + putidt((u32) irq10, SEL_KERNEL_CODE, INTGATE, 98); + putidt((u32) irq11, SEL_KERNEL_CODE, INTGATE, 99); + putidt((u32) irq12, SEL_KERNEL_CODE, INTGATE, 100); + putidt((u32) irq13, SEL_KERNEL_CODE, INTGATE, 101); + putidt((u32) irq14, SEL_KERNEL_CODE, INTGATE, 102); + putidt((u32) irq15, SEL_KERNEL_CODE, INTGATE, 103); + for (i = 104; i < IDT_SIZE; i++) { putidt((u32) interruption, 0x20, TRAPGATE, i); } /* initialise le registre idt */ - idtreg.limite = SIZEIDT * 8; - idtreg.base = BASEIDT; + idtreg.limite = IDT_SIZE * 8; + idtreg.base = IDT_ADDR; /* recopie de la IDT a son adresse */ memcpy(&idt, (u8 *) idtreg.base, idtreg.limite, 1); /* chargement du registre IDTR */ diff --git a/lib/memory.c b/lib/memory.c index 8324166..d87f855 100755 --- a/lib/memory.c +++ b/lib/memory.c @@ -2,6 +2,34 @@ /* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ /* */ #include "types.h" +#include "memory.h" + +u32 *pd0 = (u32 *) KERNEL_PGD_ADDR; /* page directory */ +u8 *pg0 = (u8 *) 0; /* page 0 */ +u8 *pg1 = (u8 *) (PAGESIZE*PAGENUMBER); /* page 1 */ + +/*******************************************************************************/ +/* Initialisation de la mémoire paginée */ + +void initpaging(void) +{ + u16 i; + pd0[0] = ((u32) pg0 | (PAGE_PRESENT | PAGE_WRITE | PAGE_4MB)); + pd0[1] = ((u32) pg1 | (PAGE_PRESENT | PAGE_WRITE | PAGE_4MB)); + for (i = 2; i < 1023; i++) + pd0[i] = ((u32) pg1 + PAGESIZE * i) | (PAGE_PRESENT | PAGE_WRITE); + + pd0[1023] = ((u32) pd0 | (PAGE_PRESENT | PAGE_WRITE)); + + asm("mov %[pd0_addr], %%eax \n \ + mov %%eax, %%cr3 \n \ + mov %%cr4, %%eax \n \ + or $0x00000010, %%eax \n \ + mov %%eax, %%cr4 \n \ + mov %%cr0, %%eax \n \ + or $0x80000001, %%eax \n \ + mov %%eax, %%cr0"::[pd0_addr]"m"(pd0)); +} /*******************************************************************************/ /* Copie un octet une ou plusieurs fois en mémoire */ diff --git a/lib/shell.c b/lib/shell.c index 4bff224..18c2d63 100644 --- a/lib/shell.c +++ b/lib/shell.c @@ -173,7 +173,7 @@ int readgdt() gdtdes *desc; struct gdtr gdtreg; sgdt(&gdtreg); - printf("Information sur la LGDT\r\nAdresse:%X Limite:%hX", gdtreg.base, + printf("Information sur la GDT\r\nAdresse:%X Limite:%hX", gdtreg.base, (u32) gdtreg.limite); desc = gdtreg.base; for (index = 0; index < gdtreg.limite / sizeof(gdtdes); index++) { @@ -205,7 +205,7 @@ int readgdt() print("Normal "); } else { print("Data."); - if ((acces >> 3) & 1 == 1) + if ((acces >> 2) & 1 == 1) print("Down "); else print("up "); diff --git a/lib/syscall.c b/lib/syscall.c index 0841e94..fef832a 100644 --- a/lib/syscall.c +++ b/lib/syscall.c @@ -4,6 +4,7 @@ #include #include #include +#include /* 32bit SYSENTER instruction entry. * @@ -33,7 +34,7 @@ void sysenter_handler(void) void initsyscall(void) { wrmsr(0x174, SEL_KERNEL_CODE, 0x0); - wrmsr(0x175, STACK_OFFSET, 0x0); + wrmsr(0x175, KERNEL_STACK_ADDR, 0x0); wrmsr(0x176, &sysenter_handler, 0x0); } diff --git a/system/system.c b/system/system.c index f94bc73..379f5cc 100755 --- a/system/system.c +++ b/system/system.c @@ -74,6 +74,10 @@ int main(u32 magic, u32 addr) inittr(); ok(); + print("\033[37m\033[0m -Initilisation de la pagination (PAGING)"); + initpaging(); + ok(); + print("\033[37m\033[0m -Initilisation des interruptions (IDT/PIC)"); initidt(); initpic(); @@ -103,5 +107,10 @@ int main(u32 magic, u32 addr) initsyscall(); ok(); + print(" -Create a double fault error"); + asm("mov $0x66666666, %eax \n \ + mov %eax,0xE0000000"); + error(); + shell(); }