summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJérémy Zurcher <jeremy.zurcher@heraeus.com>2015-11-02 11:15:48 +0100
committerJérémy Zurcher <jeremy.zurcher@heraeus.com>2015-11-02 11:15:48 +0100
commitd968266a3be79c449f62fdf6f19b8f8b5344eece (patch)
tree75c3596106e4d7b92a7223adb22f4f6cb5f5f928
downloados_skeleton-d968266a3be79c449f62fdf6f19b8f8b5344eece.zip
os_skeleton-d968266a3be79c449f62fdf6f19b8f8b5344eece.tar.gz
Initial commit
-rw-r--r--TP1-Mini-kernel.pdfbin0 -> 130414 bytes
-rw-r--r--common/types.h15
-rw-r--r--grub/grub.cfg5
-rw-r--r--kernel/bootloader.obin0 -> 256816 bytes
-rw-r--r--kernel/bootloader.s57
-rw-r--r--kernel/const.inc3
-rw-r--r--kernel/gdt.c57
-rw-r--r--kernel/gdt.h36
-rw-r--r--kernel/gdt.obin0 -> 1756 bytes
-rw-r--r--kernel/gdt_asm.obin0 -> 608 bytes
-rw-r--r--kernel/gdt_asm.s19
-rw-r--r--kernel/kernel.c15
-rw-r--r--kernel/kernel.ld36
-rw-r--r--kernel/kernel.obin0 -> 932 bytes
-rw-r--r--kernel/kernel_asm.s7
-rw-r--r--kernel/makefile24
-rw-r--r--kernel/x86.h55
-rw-r--r--makefile15
-rw-r--r--mini_kernel/grub.cfg5
19 files changed, 349 insertions, 0 deletions
diff --git a/TP1-Mini-kernel.pdf b/TP1-Mini-kernel.pdf
new file mode 100644
index 0000000..9b82a19
--- /dev/null
+++ b/TP1-Mini-kernel.pdf
Binary files differ
diff --git a/common/types.h b/common/types.h
new file mode 100644
index 0000000..4c911ed
--- /dev/null
+++ b/common/types.h
@@ -0,0 +1,15 @@
+#ifndef _TYPES_H_
+#define _TYPES_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef unsigned char uchar;
+typedef unsigned short ushort;
+typedef unsigned int uint;
+typedef unsigned long ulong;
+
+#define NULL 0
+
+#endif
+
diff --git a/grub/grub.cfg b/grub/grub.cfg
new file mode 100644
index 0000000..420d048
--- /dev/null
+++ b/grub/grub.cfg
@@ -0,0 +1,5 @@
+set timeout=0
+
+menuentry "Your_OS_name" {
+ multiboot /boot/kernel.elf
+}
diff --git a/kernel/bootloader.o b/kernel/bootloader.o
new file mode 100644
index 0000000..96a1d55
--- /dev/null
+++ b/kernel/bootloader.o
Binary files differ
diff --git a/kernel/bootloader.s b/kernel/bootloader.s
new file mode 100644
index 0000000..36d516f
--- /dev/null
+++ b/kernel/bootloader.s
@@ -0,0 +1,57 @@
+global entrypoint ; the entry point symbol defined in kernel.ld
+extern mainKernel ; indique la fonction ne se trouve pas dans ce fichier
+
+; Values for the multiboot header
+MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
+MULTIBOOT_HEADER_FLAGS equ 0x0
+; magic + checksum + flags must equal 0
+MULTIBOOT_HEADER_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
+STACK_SIZE equ 256000
+;---------------------------------------------------------------------------------------------------
+; bootloader section
+; This section must be located at the very beginning of the kernel image.
+
+section .bootloader
+align 4 ; section aligned to a 4 bytes boundary
+
+; Minimum multiboot header
+dd MULTIBOOT_HEADER_MAGIC
+dd MULTIBOOT_HEADER_FLAGS
+dd MULTIBOOT_HEADER_CHECKSUM
+
+entrypoint:
+ ; Bootloader code starts executing here
+ cli ; disable hardware interrupts
+
+ ; TODO : initialiser le pointeur de pile ainsi qu'EBP (à la même valeur)
+ ; Rappel : la pile "grandi" en descendant !
+ ; ...
+ mov esp, stack ; l'adresse de la pile est defini par le label 'stack'
+ add esp, STACK_SIZE ; on deplace le pointeur de pile a la fin de la pile
+ mov ebp, esp
+
+
+ ; TODO : appeler la fonction principale du kernel (code C)
+ ; Celle-ci doit etre visible par le linker
+ ; ...
+
+ call mainKernel
+
+ ; infinite loop (should never get here)
+.forever:
+ hlt
+ jmp .forever
+
+;---------------------------------------------------------------------------------------------------
+; stack section
+
+; TODO : ajouter une section pour la pile kernel dans laquelle
+
+
+; reserver au moins 256KB grace a la directive "resb".
+; Cette section devra etre alignee sur 4 bytes.
+; ...
+section .stack
+
+stack:
+ resb STACK_SIZE
diff --git a/kernel/const.inc b/kernel/const.inc
new file mode 100644
index 0000000..17d17d0
--- /dev/null
+++ b/kernel/const.inc
@@ -0,0 +1,3 @@
+; Must match the values of the same constants in gdt.h!
+GDT_KERNEL_CODE_SELECTOR equ 0x08
+GDT_KERNEL_DATA_SELECTOR equ 0x10
diff --git a/kernel/gdt.c b/kernel/gdt.c
new file mode 100644
index 0000000..0a7cfdc
--- /dev/null
+++ b/kernel/gdt.c
@@ -0,0 +1,57 @@
+#include "../common/types.h"
+#include "gdt.h"
+#include "x86.h"
+
+// TODO: déclarer la table GDT
+// Pointeur sur la table GDT
+static gdt_ptr_t gdt_ptr;
+
+// Build and return a GDT entry given the various arguments (see Intel manuals).
+static gdt_entry_t build_entry(uint32_t base, uint32_t limit, uint8_t type, uint8_t s, uint8_t db, uint8_t granularity, uint8_t dpl) {
+ gdt_entry_t entry;
+ // For a TSS and LDT, base is the addresse of the TSS/LDT structure
+ // and limit is the size of the structure.
+ entry.lim15_0 = limit & 0xffff;
+ entry.base15_0 = base & 0xffff;
+ entry.base23_16 = (base >> 16) & 0xff;
+ entry.type = type; // See TYPE_xxx flags
+ entry.s = s; // 1 for segments; 0 for system (TSS, LDT, gates)
+ entry.dpl = dpl; // privilege level
+ entry.present = 1; // present in memory
+ entry.lim19_16 = (limit >> 16) & 0xf;
+ entry.avl = 0; // available for use
+ entry.l = 0; // should be 0 (64-bit code segment)
+ entry.db = db; // 1 for 32-bit code and data segments; 0 for system (TSS, LDT, gate)
+ entry.granularity = granularity; // granularity of the limit value: 0 = 1 byte; 1 = 4096 bytes
+ entry.base31_24 = (base >> 24) & 0xff;
+ return entry;
+}
+
+// Return a NULL entry.
+static gdt_entry_t null_segment() {
+ gdt_entry_t entry;
+ //memset(&entry, 0, sizeof(gdt_entry_t));
+ return entry;
+}
+
+// Return a code segment specified by the base, limit and privilege level passed in arguments.
+static gdt_entry_t code_segment(uint32_t base, uint32_t limit, uint8_t dpl) {
+ return build_entry(base, limit, TYPE_CODE_EXECREAD, S_CODE_OR_DATA, DB_SEG, 1, dpl);
+}
+
+// Return a data segment specified by the base, limit and privilege level passed in arguments.
+static gdt_entry_t data_segment(uint32_t base, uint32_t limit, uint8_t dpl) {
+ return build_entry(base, limit, TYPE_DATA_READWRITE, S_CODE_OR_DATA, DB_SEG, 1, dpl);
+}
+
+// Initialize the GDT
+void gdt_init() {
+ // TODO: fixer la limite de gdt_ptr, puis la faire pointer sur la GDT
+
+ // TODO: initialisation des trois descripteurs de segment: NULL, segment code, segment data
+ // Les descripteurs de code et data doivent avoir un DPL de 0.
+
+ // Load the GDT
+ gdt_flush(&gdt_ptr);
+}
+
diff --git a/kernel/gdt.h b/kernel/gdt.h
new file mode 100644
index 0000000..03f575e
--- /dev/null
+++ b/kernel/gdt.h
@@ -0,0 +1,36 @@
+#ifndef _GDT_H_
+#define _GDT_H_
+
+// Structure of a GDT descriptor. There are 2 types of descriptors: segments and TSS.
+// Section 3.4.5 of Intel 64 & IA32 architectures software developer's manual describes
+// segment descriptors while section 6.2.2 describes TSS descriptors.
+typedef struct gdt_entry_st {
+ uint16_t lim15_0;
+ uint16_t base15_0;
+ uint8_t base23_16;
+
+ uint8_t type : 4;
+ uint8_t s : 1;
+ uint8_t dpl : 2;
+ uint8_t present : 1;
+
+ uint8_t lim19_16 : 4;
+ uint8_t avl : 1;
+ uint8_t l : 1;
+ uint8_t db : 1;
+ uint8_t granularity : 1;
+
+ uint8_t base31_24;
+} __attribute__((packed)) gdt_entry_t;
+
+// Structure describing a pointer to the GDT descriptor table.
+// This format is required by the lgdt instruction.
+typedef struct gdt_ptr_st {
+ uint16_t limit; // Limit of the table (ie. its size)
+ uint32_t base; // Address of the first entry
+} __attribute__((packed)) gdt_ptr_t;
+
+extern void gdt_init();
+extern void gdt_flush(gdt_ptr_t *gdt_ptr);
+
+#endif
diff --git a/kernel/gdt.o b/kernel/gdt.o
new file mode 100644
index 0000000..da9ac7d
--- /dev/null
+++ b/kernel/gdt.o
Binary files differ
diff --git a/kernel/gdt_asm.o b/kernel/gdt_asm.o
new file mode 100644
index 0000000..f6e32e2
--- /dev/null
+++ b/kernel/gdt_asm.o
Binary files differ
diff --git a/kernel/gdt_asm.s b/kernel/gdt_asm.s
new file mode 100644
index 0000000..9e59544
--- /dev/null
+++ b/kernel/gdt_asm.s
@@ -0,0 +1,19 @@
+%include "const.inc"
+
+global gdt_flush
+
+section .text: ; start of the text (code) section
+align 4 ; the code must be 4 byte aligned
+
+gdt_flush:
+ mov eax,[esp+4] ; Get the pointer to the GDT, passed as a parameter.
+ lgdt [eax] ; Load the new GDT pointer
+ mov ax,GDT_KERNEL_DATA_SELECTOR ; offset in the GDT of the kernel data segment
+ mov ds,ax ; Load all data segment selectors
+ mov es,ax
+ mov fs,ax
+ mov gs,ax
+ mov ss,ax
+ jmp GDT_KERNEL_CODE_SELECTOR:.flush ; far jump [selector:offset]
+.flush:
+ret
diff --git a/kernel/kernel.c b/kernel/kernel.c
new file mode 100644
index 0000000..d01eada
--- /dev/null
+++ b/kernel/kernel.c
@@ -0,0 +1,15 @@
+extern void smiley();
+
+void mainKernel(){
+
+ #ifdef TEST
+ // MODE TEST
+ smiley();
+
+ #else
+ //MODE NORMAL
+ #endif
+
+
+ while(1);
+}
diff --git a/kernel/kernel.ld b/kernel/kernel.ld
new file mode 100644
index 0000000..da9e019
--- /dev/null
+++ b/kernel/kernel.ld
@@ -0,0 +1,36 @@
+ENTRY(entrypoint) /* the entry point */
+
+SECTIONS {
+ . = 0x100000; /* all sections located above 1MB */
+
+ .bootloader ALIGN(4K): /* multiboot header first (needs to reside within the first 8KB) */
+ {
+ *(.bootloader)
+ }
+
+ .stack ALIGN(4K): /* kernel stack */
+ {
+ *(.stack)
+ }
+
+ .text ALIGN(4K) : /* code */
+ {
+ *(.text*)
+ }
+
+ .rodata ALIGN(4K) : /* read-only data */
+ {
+ *(.rodata*)
+ }
+
+ .data ALIGN(4K) : /* initialized data */
+ {
+ *(.data*)
+ }
+
+ .bss ALIGN(4K) : /* unitialized data */
+ {
+ *(COMMON)
+ *(.bss*)
+ }
+}
diff --git a/kernel/kernel.o b/kernel/kernel.o
new file mode 100644
index 0000000..b000856
--- /dev/null
+++ b/kernel/kernel.o
Binary files differ
diff --git a/kernel/kernel_asm.s b/kernel/kernel_asm.s
new file mode 100644
index 0000000..6005121
--- /dev/null
+++ b/kernel/kernel_asm.s
@@ -0,0 +1,7 @@
+global smiley
+
+section .text
+
+smiley:
+ mov eax,0xB8000
+ mov word [eax],0x0E01
diff --git a/kernel/makefile b/kernel/makefile
new file mode 100644
index 0000000..0173172
--- /dev/null
+++ b/kernel/makefile
@@ -0,0 +1,24 @@
+all: run
+
+run : ld
+
+ld: kernel.o bootloader.o gdt.o gdt_asm.o
+ ld -Tkernel.ld -melf_i386 gdt_asm.o bootloader.o kernel.o gdt.o -o kernel.elf
+
+kernel.o: kernel.c kernel_asm.o
+ gcc -DTEST -std=gnu99 -m32 -fno-builtin -ffreestanding -Wall -Wextra -c kernel.c
+
+kernel_asm.o: kernel_asm.s
+ nasm -f elf32 $<
+
+bootloader.o: bootloader.s
+ nasm -f elf32 bootloader.s
+
+gdt.o: gdt.c gdt.h
+ gcc -std=gnu99 -m32 -fno-builtin -ffreestanding -Wall -Wextra -c gdt.c
+
+gdt_asm.o: gdt_asm.s
+ nasm -f elf32 $<
+
+clean:
+ rm -f *.o \ No newline at end of file
diff --git a/kernel/x86.h b/kernel/x86.h
new file mode 100644
index 0000000..716cb6c
--- /dev/null
+++ b/kernel/x86.h
@@ -0,0 +1,55 @@
+#ifndef _X86_H_
+#define _X86_H_
+
+// Privilege levels
+#define DPL_USER 0x3
+#define DPL_KERNEL 0x0
+
+// Selectors
+#define LDT_SELECTOR 0x4
+
+// Descriptor types for code and data segments
+#define TYPE_DATA_READONLY 1
+#define TYPE_DATA_READWRITE 3
+#define TYPE_CODE_EXECONLY 9
+#define TYPE_CODE_EXECREAD 11
+
+// Descriptor types for system segments and gates
+#define TYPE_LDT 2
+#define TYPE_TASK_GATE 5
+#define TYPE_TSS 9
+#define TYPE_CALL_GATE 12
+#define TYPE_TRAP_GATE 15
+#define TYPE_INTERRUPT_GATE 14
+
+// Descriptor system bit (S)
+// For code or data segments
+#define S_CODE_OR_DATA 1
+// For TSS segment, LDT, call gate, interrupt gate, trap gate, task gate
+#define S_SYSTEM 0
+
+// D/B bit
+#define DB_SEG 1
+#define DB_SYS 0
+
+// kernel code and data selectors in the GDT
+#define GDT_KERNEL_CODE_SELECTOR 0x08
+#define GDT_KERNEL_DATA_SELECTOR 0x10
+
+// Disable hardware interrupts.
+static inline void cli() {
+ asm volatile("cli");
+}
+
+// Enable hardware interrupts.
+static inline void sti() {
+ asm volatile("sti");
+}
+
+// Halt the processor.
+// External interrupts wake up the CPU, hence the cli instruction.
+static inline void halt() {
+ while (1) asm volatile("cli\nhlt");
+}
+
+#endif
diff --git a/makefile b/makefile
new file mode 100644
index 0000000..24f21aa
--- /dev/null
+++ b/makefile
@@ -0,0 +1,15 @@
+all: run
+
+run: create_iso
+ qemu-system-i386 -hda mini_kernel/mini_kernel.iso
+
+create_iso: cpy
+ grub-mkrescue -o mini_kernel/mini_kernel.iso mini_kernel
+
+cpy:
+ cp grub/grub.cfg mini_kernel/
+ cp kernel/kernel.elf mini_kernel/
+
+clean:
+ rm mini_kernel/*.iso mini_kernel/*.cfg mini_kernel/*.elf
+ \ No newline at end of file
diff --git a/mini_kernel/grub.cfg b/mini_kernel/grub.cfg
new file mode 100644
index 0000000..420d048
--- /dev/null
+++ b/mini_kernel/grub.cfg
@@ -0,0 +1,5 @@
+set timeout=0
+
+menuentry "Your_OS_name" {
+ multiboot /boot/kernel.elf
+}