From 6edeba8fe208fb019aec00fdc72b97407a8078d3 Mon Sep 17 00:00:00 2001 From: Loic Guegan Date: Sun, 11 Apr 2021 20:53:06 +0200 Subject: Enable paging --- src/Makefile | 3 +- src/boot/boot.S | 2 +- src/bringelle.c | 21 +++++++--- src/int/8042.c | 16 ++++++++ src/int/8042.h | 64 +++++++++++++++++++++++++++++ src/int/int.S | 0 src/int/pic.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/int/pic.h | 23 +++++++++++ src/utils/8042.c | 16 -------- src/utils/8042.h | 64 ----------------------------- src/utils/gdt.c | 4 +- src/utils/paging.c | 31 ++++++++++++++ src/utils/paging.h | 10 +++++ src/utils/pic.c | 105 ----------------------------------------------- src/utils/pic.h | 23 ----------- src/utils/syscall.c | 3 +- 16 files changed, 281 insertions(+), 219 deletions(-) create mode 100644 src/int/8042.c create mode 100644 src/int/8042.h create mode 100644 src/int/int.S create mode 100644 src/int/pic.c create mode 100644 src/int/pic.h delete mode 100644 src/utils/8042.c delete mode 100644 src/utils/8042.h create mode 100644 src/utils/paging.c create mode 100644 src/utils/paging.h delete mode 100644 src/utils/pic.c delete mode 100644 src/utils/pic.h (limited to 'src') diff --git a/src/Makefile b/src/Makefile index a7a8586..2151883 100644 --- a/src/Makefile +++ b/src/Makefile @@ -8,11 +8,12 @@ LD_SCRIPT := linker.ld BOOT_OBJ := $(addsuffix .o,$(basename $(shell find ./boot -name "*.[c|S]" ! -name "boot.S"))) UTILS_OBJ := $(addsuffix .o,$(basename $(shell find ./utils -name "*.[c|S]"))) LIBC_OBJ := $(addsuffix .o,$(basename $(shell find ./libc -name "*.[c|S]"))) +INT_OBJ := $(addsuffix .o,$(basename $(shell find ./int -name "*.[c|S]"))) all: $(EXEC) -$(EXEC): boot/boot.o $(BOOT_OBJ) $(UTILS_OBJ) $(LIBC_OBJ) bringelle.o +$(EXEC): boot/boot.o $(BOOT_OBJ) $(UTILS_OBJ) $(LIBC_OBJ) $(INT_OBJ) bringelle.o ld -n -T $(LD_SCRIPT) -nostdlib -o bringelle $^ %.o: %.S diff --git a/src/boot/boot.S b/src/boot/boot.S index 0092567..e436cbb 100644 --- a/src/boot/boot.S +++ b/src/boot/boot.S @@ -4,7 +4,7 @@ .extern gdt_memcpy .extern mb_load_fb_tag -.set STACK_LOCATION, 0x50000 +.set STACK_LOCATION, 0x1FFFFF .section .multiboot diff --git a/src/bringelle.c b/src/bringelle.c index 8faaecc..340e884 100644 --- a/src/bringelle.c +++ b/src/bringelle.c @@ -1,8 +1,10 @@ #include "libc/stdio.h" -#include "utils/pic.h" +#include "int/pic.h" #include "boot/multiboot.h" #include "utils/mem.h" #include "utils/gdt.h" +#include "utils/paging.h" + char show_tics=0; @@ -21,11 +23,14 @@ void bringelle(){ // Kernel boot sequence pic_enable_interrupt(); print("Interrupts enabled\n"); - print("Kernel started !\n"); + paging_enable(); + print("Paging enable!\n"); + print("Kernel started !"); + + show_tics=1; // Utask print("Launch user task "); - show_tics=1; memcpy((void*)utask,(void*)0x300000, 100); // 100 bytes seems reasonable to load utask asm ( "cli \n\t" // Ensure we do not get interrupted @@ -33,20 +38,22 @@ void bringelle(){ "movl %%eax, %0 \n\t" // Save kernel ss segment into the TSS "movl %%esp, %1 \n\t" // Save kernel esp into the TSS BEFORE setting up the stack "pushl $0x33 \n\t" // Push task ss which is 0x30 along with prlv which is 0x3 - "pushl $0x400000 \n\t" // Push task esp + "pushl $0x30FFFF \n\t" // Push task esp "pushfl \n\t" // Retrieve flags "popl %%eax \n\t" "orl $0x200, %%eax \n\t" // Enable interrupt for the user task "and $0xffffbfff, %%eax \n\t" // Clear the NT flags "push %%eax \n\t" // Push task flags "push $0x23 \n\t" // Push task cs which is 0x20 along with prlv which is 0x3 - "push $0 \n\t" // Push task entry point + "push $0x300000 \n\t" // Push task entry point "mov $0x2B, %%eax \n\t" // GDT entry 0x28 along with prlv which is 0x3 "mov %%eax, %%ds \n\t" // Setting up user data segment "iret \n\t" // Launch user task : "=m" (TSS.ss0), "=m" (TSS.esp0) ); + + while(1); } @@ -63,3 +70,7 @@ void clock(){ } +void page_fault(){ + print("Page fault!"); +} + diff --git a/src/int/8042.c b/src/int/8042.c new file mode 100644 index 0000000..f0a987f --- /dev/null +++ b/src/int/8042.c @@ -0,0 +1,16 @@ +#include "8042.h" +#include "utils/framebuffer.h" +#include "utils/asm.h" + +DEFINE_AZERTY; + +void _8042_keypress(){ + u8 data; + do { + inb(0x64,data); + } + while((data&0x01) == 0); + inb(0x60,data); + if(data<0x80) + putchar(AZERTY[data]); +} diff --git a/src/int/8042.h b/src/int/8042.h new file mode 100644 index 0000000..e35e5a0 --- /dev/null +++ b/src/int/8042.h @@ -0,0 +1,64 @@ +#ifndef _8042_H +#define _8042_H + +#include "utils/types.h" + +void _8042_keypress(); + +#define DEFINE_AZERTY char AZERTY[]={\ + '\0',\ + '\0',\ + '&',\ + '\0',\ + '"',\ + '\'',\ + '(',\ + '-',\ + '\0',\ + '_',/* 10 */\ + '\0',\ + '\0',\ + ')',\ + '=',\ + '\0',\ + '\t',\ + 'a',\ + 'z',\ + 'e',\ + 'r',\ + 't',\ + 'y',\ + 'u',\ + 'i',\ + 'o',\ + 'p',\ + '^',\ + '$',\ + '\0',\ + '\0',\ + 'q',/* 0x1E (30) */\ + 's',\ + 'd',\ + 'f',\ + 'g',\ + 'h',\ + 'j',\ + 'k',\ + 'l',\ + 'm',\ + '\0',\ + '\0',\ + '\0',\ + '*',\ + 'w',\ + 'x',\ + 'c',\ + 'v',\ + 'b',/* 0x30 (48) */\ + 'n',\ + ',',\ + ';',\ + ':',\ +} + +#endif \ No newline at end of file diff --git a/src/int/int.S b/src/int/int.S new file mode 100644 index 0000000..e69de29 diff --git a/src/int/pic.c b/src/int/pic.c new file mode 100644 index 0000000..472e50c --- /dev/null +++ b/src/int/pic.c @@ -0,0 +1,115 @@ +#include "pic.h" +#include "utils/asm.h" +#include "utils/mem.h" +#include "utils/syscall.h" + +struct IDT_REGISTER IDTR={ + 200*8, + 0x0 +}; + +/// Bridge between IDT and functions call +asm ( +".macro SAVE_REGS \n\t" + "pushal \n\t" + "push %ds \n\t" + "push %es \n\t" + "push %fs \n\t" + "push %gs \n\t" + "push %ebx \n\t" + "mov $0x10,%bx \n\t" + "mov %bx,%ds \n\t" + "pop %ebx \n\t" +".endm \n\t" +".macro RESTORE_REGS \n\t" + "pop %gs \n\t" + "pop %fs \n\t" + "pop %es \n\t" + "pop %ds \n\t" + "popal \n\t" +".endm \n\t" +"PIC_IRQ_DEFAULT: \n\t" + "SAVE_REGS \n\t" + "movb $0x20, %al \n\t" + "outb %al, $0x20 \n\t" + "RESTORE_REGS \n\t" + "iret \n\t" +"PIC_IRQ_PRINT: \n\t" + "SAVE_REGS \n\t" + "call _8042_keypress \n\t" + "movb $0x20, %al \n\t" + "outb %al, $0x20 \n\t" + "RESTORE_REGS \n\t" + "iret \n\t" +"PIC_IRQ_CLOCK: \n\t" + "SAVE_REGS \n\t" + "call clock \n\t" + "movb $0x20, %al \n\t" + "outb %al, $0x20 \n\t" + "RESTORE_REGS \n\t" + "iret \n\t" +"PIC_IRQ_SYSCALL: \n\t" + "SAVE_REGS \n\t" + "call syscall \n\t" + "movb $0x20, %al \n\t" + "outb %al, $0x20 \n\t" + "RESTORE_REGS \n\t" + "iret \n\t" +"INT_PAGE_FAULT: \n\t" + "SAVE_REGS \n\t" + "call page_fault \n\t" + "hlt \n\t" + "movb $0x20, %al \n\t" + "outb %al, $0x20 \n\t" + "RESTORE_REGS \n\t" + "iret \n\t" +); + +extern u32 PIC_IRQ_DEFAULT,PIC_IRQ_PRINT,PIC_IRQ_CLOCK, PIC_IRQ_SYSCALL,INT_PAGE_FAULT; + +void pic_enable_interrupt(){ + // Map first default 32 entries + for(int i=0;i<200;i++){ + pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&PIC_IRQ_DEFAULT,IDT_INT_GATE},i); + if(i==14) + pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&INT_PAGE_FAULT,IDT_INT_GATE},i); + if(i==32) + pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&PIC_IRQ_CLOCK,IDT_INT_GATE},i); + if(i==33) + pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&PIC_IRQ_PRINT,IDT_INT_GATE},i); + if(i==48) + pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&PIC_IRQ_SYSCALL,IDT_TRAP_GATE},i); + } + + // Now configure 8952A + + // ICW1: Initialisation + outbj(0x20,0x11); // Master + outbj(0xA0,0x11); // Slave + + // ICW2: Map IRQ index to entry into the IDT + outbj(0x21,0x20); // Start interrupt at offset 0x20 in IDT (index 32) + outbj(0xA1,0x70); // Start interrupt at offset 0x50 in IDT (index 80) + + // ICW3: Indicate the connection between master and slave + outbj(0x21,0x02); // Slave connected to pin 2 + outbj(0xA1,0x01); // Indicate pin id to the slave (2-1) + + // ICW4: Operating mode + outbj(0x21,0x01); // Default operating mode + outbj(0xA1,0x01); // Default operating mode + + // OCW: Masking + outbj(0x21,0b11111100); + + + asm("lidtl (IDTR)"); + asm("sti"); +} + +void pic_add_idt_entry(IDT_ENTRY entry, int id){ + int descriptor[2]; + descriptor[0]=entry.offset & 0xFFFF | entry.segment << 16; + descriptor[1]=entry.type & 0xFFFF | entry.offset & 0xFFFF0000; + memcpy((void*)descriptor, (void *)(IDTR.base+(id*8)),8); +} diff --git a/src/int/pic.h b/src/int/pic.h new file mode 100644 index 0000000..db1ccec --- /dev/null +++ b/src/int/pic.h @@ -0,0 +1,23 @@ +#ifndef PIC_H +#define PIC_H + +#include "utils/types.h" + +#define IDT_INT_GATE 0x8E00 +#define IDT_TRAP_GATE 0xEF00 + +typedef struct IDT_ENTRY { + u16 segment; + u32 offset; + u16 type; +} IDT_ENTRY; + +struct IDT_REGISTER { + u16 limit; + u32 base; +} __attribute__((packed)); + +void pic_enable_interrupt(); +void pic_add_idt_entry(IDT_ENTRY entry,int id); + +#endif \ No newline at end of file diff --git a/src/utils/8042.c b/src/utils/8042.c deleted file mode 100644 index 1d22152..0000000 --- a/src/utils/8042.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "8042.h" -#include "framebuffer.h" -#include "asm.h" - -DEFINE_AZERTY; - -void _8042_keypress(){ - u8 data; - do { - inb(0x64,data); - } - while((data&0x01) == 0); - inb(0x60,data); - if(data<0x80) - putchar(AZERTY[data]); -} diff --git a/src/utils/8042.h b/src/utils/8042.h deleted file mode 100644 index 8efa8ce..0000000 --- a/src/utils/8042.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef _8042_H -#define _8042_H - -#include "types.h" - -void _8042_keypress(); - -#define DEFINE_AZERTY char AZERTY[]={\ - '\0',\ - '\0',\ - '&',\ - '\0',\ - '"',\ - '\'',\ - '(',\ - '-',\ - '\0',\ - '_',/* 10 */\ - '\0',\ - '\0',\ - ')',\ - '=',\ - '\0',\ - '\t',\ - 'a',\ - 'z',\ - 'e',\ - 'r',\ - 't',\ - 'y',\ - 'u',\ - 'i',\ - 'o',\ - 'p',\ - '^',\ - '$',\ - '\0',\ - '\0',\ - 'q',/* 0x1E (30) */\ - 's',\ - 'd',\ - 'f',\ - 'g',\ - 'h',\ - 'j',\ - 'k',\ - 'l',\ - 'm',\ - '\0',\ - '\0',\ - '\0',\ - '*',\ - 'w',\ - 'x',\ - 'c',\ - 'v',\ - 'b',/* 0x30 (48) */\ - 'n',\ - ',',\ - ';',\ - ':',\ -} - -#endif \ No newline at end of file diff --git a/src/utils/gdt.c b/src/utils/gdt.c index c380283..8c1c70d 100644 --- a/src/utils/gdt.c +++ b/src/utils/gdt.c @@ -35,13 +35,13 @@ void gdt_memcpy(){ // ----- User Segments GDT_ENTRY ucs_desc; - ucs_desc.base=0x300000; + ucs_desc.base=0; // With paging will take care of allocating the right address for each task ucs_desc.limit=0xFFFFF; ucs_desc.flags=GDT_SZ|GDT_GR; ucs_desc.access=GDT_PR|GDT_PRVL_3|GDT_S|GDT_EXEC|GDT_RW|GDT_DC; GDT_ENTRY uds_desc; - uds_desc.base=0x300000; + uds_desc.base=0; uds_desc.limit=0xFFFFF; uds_desc.flags=GDT_SZ|GDT_GR; uds_desc.access=GDT_PR|GDT_PRVL_3|GDT_S|GDT_RW; diff --git a/src/utils/paging.c b/src/utils/paging.c new file mode 100644 index 0000000..b1f462f --- /dev/null +++ b/src/utils/paging.c @@ -0,0 +1,31 @@ +#include "paging.h" + +void paging_enable(){ + int *page_dir=(int*)PAGING_DIR_LOCATION; + int *page_table=(int*)PAGING_TABLE_LOCATION; + + // Init page directory + for(int i=0;i<1024;i++) + page_dir[i]=0; + page_dir[0]=(int)page_table; + page_dir[0] |=7; // Permissions + + // Init page table 0 + int addr_offset=0; + for(int i=0;i<1024;i++){ + page_table[i]=addr_offset; + page_table[i]|=7; // Permission + addr_offset+=4096; // 4Ko pages + } + + // Turns on paging + asm( + "movl %0, %%eax \n\t" + "movl %%eax, %%cr3 \n\t" // Configure page table location + "movl %%cr0, %%eax \n\t" + "orl %1, %%eax \n\t" + "movl %%eax, %%cr0 \n\t" // Turn on paging + :: "i" (PAGING_DIR_LOCATION), "i" (PAGING_CR0_BIT) + ); + +} \ No newline at end of file diff --git a/src/utils/paging.h b/src/utils/paging.h new file mode 100644 index 0000000..3e6b3f8 --- /dev/null +++ b/src/utils/paging.h @@ -0,0 +1,10 @@ +#ifndef PAGING_H +#define PAGING_H + +#define PAGING_CR0_BIT 0x80000000 +#define PAGING_DIR_LOCATION 0x1000 +#define PAGING_TABLE_LOCATION 0x5000 + +void paging_enable(); + +#endif \ No newline at end of file diff --git a/src/utils/pic.c b/src/utils/pic.c deleted file mode 100644 index 7681a13..0000000 --- a/src/utils/pic.c +++ /dev/null @@ -1,105 +0,0 @@ -#include "pic.h" -#include "asm.h" -#include "mem.h" -#include "syscall.h" - -struct IDT_REGISTER IDTR={ - 200*8, - 0x0 -}; - -/// Bridge between IDT and functions call -asm ( -".macro SAVE_REGS \n\t" - "pushal \n\t" - "push %ds \n\t" - "push %es \n\t" - "push %fs \n\t" - "push %gs \n\t" - "push %ebx \n\t" - "mov $0x10,%bx \n\t" - "mov %bx,%ds \n\t" - "pop %ebx \n\t" -".endm \n\t" -".macro RESTORE_REGS \n\t" - "pop %gs \n\t" - "pop %fs \n\t" - "pop %es \n\t" - "pop %ds \n\t" - "popal \n\t" -".endm \n\t" -"PIC_IRQ_DEFAULT: \n\t" - "SAVE_REGS \n\t" - "movb $0x20, %al \n\t" - "outb %al, $0x20 \n\t" - "RESTORE_REGS \n\t" - "iret \n\t" -"PIC_IRQ_PRINT: \n\t" - "SAVE_REGS \n\t" - "call _8042_keypress \n\t" - "movb $0x20, %al \n\t" - "outb %al, $0x20 \n\t" - "RESTORE_REGS \n\t" - "iret \n\t" -"PIC_IRQ_CLOCK: \n\t" - "SAVE_REGS \n\t" - "call clock \n\t" - "movb $0x20, %al \n\t" - "outb %al, $0x20 \n\t" - "RESTORE_REGS \n\t" - "iret \n\t" -"PIC_IRQ_SYSCALL: \n\t" - "SAVE_REGS \n\t" - "call syscall \n\t" - "movb $0x20, %al \n\t" - "outb %al, $0x20 \n\t" - "RESTORE_REGS \n\t" - "iret \n\t" -); - -extern u32 PIC_IRQ_DEFAULT,PIC_IRQ_PRINT,PIC_IRQ_CLOCK, PIC_IRQ_SYSCALL; - -void pic_enable_interrupt(){ - // Map first default 32 entries - for(int i=0;i<200;i++){ - pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&PIC_IRQ_DEFAULT,IDT_INT_GATE},i); - if(i==32) - pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&PIC_IRQ_CLOCK,IDT_INT_GATE},i); - if(i==33) - pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&PIC_IRQ_PRINT,IDT_INT_GATE},i); - if(i==48) - pic_add_idt_entry((IDT_ENTRY){0x08,(u32)&PIC_IRQ_SYSCALL,IDT_TRAP_GATE},i); - } - - // Now configure 8952A - - // ICW1: Initialisation - outbj(0x20,0x11); // Master - outbj(0xA0,0x11); // Slave - - // ICW2: Map IRQ index to entry into the IDT - outbj(0x21,0x20); // Start interrupt at offset 0x20 in IDT (index 32) - outbj(0xA1,0x70); // Start interrupt at offset 0x50 in IDT (index 80) - - // ICW3: Indicate the connection between master and slave - outbj(0x21,0x02); // Slave connected to pin 2 - outbj(0xA1,0x01); // Indicate pin id to the slave (2-1) - - // ICW4: Operating mode - outbj(0x21,0x01); // Default operating mode - outbj(0xA1,0x01); // Default operating mode - - // OCW: Masking - outbj(0x21,0b11111100); - - - asm("lidtl (IDTR)"); - asm("sti"); -} - -void pic_add_idt_entry(IDT_ENTRY entry, int id){ - int descriptor[2]; - descriptor[0]=entry.offset & 0xFFFF | entry.segment << 16; - descriptor[1]=entry.type & 0xFFFF | entry.offset & 0xFFFF0000; - memcpy((void*)descriptor, (void *)(IDTR.base+(id*8)),8); -} diff --git a/src/utils/pic.h b/src/utils/pic.h deleted file mode 100644 index 5ee1ab2..0000000 --- a/src/utils/pic.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef PIC_H -#define PIC_H - -#include "types.h" - -#define IDT_INT_GATE 0x8E00 -#define IDT_TRAP_GATE 0xEF00 - -typedef struct IDT_ENTRY { - u16 segment; - u32 offset; - u16 type; -} IDT_ENTRY; - -struct IDT_REGISTER { - u16 limit; - u32 base; -} __attribute__((packed)); - -void pic_enable_interrupt(); -void pic_add_idt_entry(IDT_ENTRY entry,int id); - -#endif \ No newline at end of file diff --git a/src/utils/syscall.c b/src/utils/syscall.c index f3b14c4..300b7aa 100644 --- a/src/utils/syscall.c +++ b/src/utils/syscall.c @@ -5,11 +5,10 @@ void syscall(){ int call_number; asm("movl %%eax, %0":"=m"(call_number)); - int user_ds=gdt_user_ds_base(); if(call_number==1){ int msg_addr; asm("movl %%ebx, %0":"=m"(msg_addr)); - char *msg=(char*)user_ds+msg_addr; + char *msg=(char*)msg_addr; print(msg); } else{ -- cgit v1.2.3