[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[tyndur-devel] [PATCH] kernel2: GDT für AMD64
+ amd64/gdt.c: ordentliche GDT angelegt und init-Funktionen implementiert
* amd64/loader/startup.S: die SYSCALL- und SYSRET-Instruktion geht von einer
bestimmten Reihenfolge der Segmente aus, deshalb sollte das
64-Bit-Code-Segment auf der 0x18 hinter dem Data-Segment landen.
- amd64/header.S: das Laden der GDT entfernt, da das in der init-Funktion
geschieht
* amd64/smp/trampoline.S: das richtige Segment nach CS laden
Signed-off-by: Andreas Freimuth <m.nemo@xxxxxxx>
---
src/kernel2/src/arch/amd64/gdt.c | 89 +++++++++++++++++++++++++++++
src/kernel2/src/arch/amd64/header.S | 29 ----------
src/kernel2/src/arch/amd64/loader/startup.S | 42 ++++----------
src/kernel2/src/arch/amd64/smp/trampoline.S | 32 +----------
4 files changed, 102 insertions(+), 90 deletions(-)
create mode 100644 src/kernel2/src/arch/amd64/gdt.c
diff --git a/src/kernel2/src/arch/amd64/gdt.c b/src/kernel2/src/arch/amd64/gdt.c
new file mode 100644
index 0000000..f4117e1
--- /dev/null
+++ b/src/kernel2/src/arch/amd64/gdt.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright © 2012 The týndur Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+
+#include "gdt.h"
+
+#define SEGMENT_DATA 0x0000120000000000ULL
+#define SEGMENT_CODE 0x0000180000000000ULL
+#define SEGMENT_TSS 0x0000090000000000ULL
+#define SEGMENT_USER 0x0000600000000000ULL
+#define SEGMENT_PRESENT 0x0000800000000000ULL
+#define SEGMENT_LM 0x0020000000000000ULL
+#define SEGMENT_32BIT 0x0040000000000000ULL
+#define SEGMENT_GRAN 0x0080000000000000ULL
+#define SEGMENT_BASE(x) (((x & 0xffffULL) << 16) | ((x & 0xff0000ULL) << 16) | ((x & 0xff000000ULL) << 32))
+#define SEGMENT_BASE64(x) ((x >> 32) & 0xffffffffULL)
+#define SEGMENT_SIZE(x) ((x & 0xffffULL) | ((x & 0xf0000ULL) << 32))
+
+struct {
+ uint16_t limit;
+ uintptr_t base;
+} gdtr;
+
+/// Global Descritpor Table
+uint64_t gdt[9] = {
+ // NULL Deskriptor
+ 0,
+
+ // Kernel Code-Segment 32Bit
+ SEGMENT_BASE(0LL) | SEGMENT_SIZE(0xfffffLL) | SEGMENT_GRAN | SEGMENT_CODE |
+ SEGMENT_32BIT | SEGMENT_PRESENT,
+
+ // Kernel Data-Segment
+ SEGMENT_BASE(0LL) | SEGMENT_SIZE(0xfffffLL) | SEGMENT_GRAN | SEGMENT_DATA |
+ SEGMENT_32BIT | SEGMENT_PRESENT,
+
+ // Kernel Code-Segment 64Bit
+ SEGMENT_CODE | SEGMENT_LM | SEGMENT_PRESENT,
+
+ // User Code-Segment 32Bit
+ SEGMENT_BASE(0LL) | SEGMENT_SIZE(0xfffffLL) | SEGMENT_GRAN | SEGMENT_CODE |
+ SEGMENT_32BIT | SEGMENT_USER | SEGMENT_PRESENT,
+
+ // User Data-Segment
+ SEGMENT_BASE(0LL) | SEGMENT_SIZE(0xfffffLL) | SEGMENT_GRAN | SEGMENT_DATA |
+ SEGMENT_32BIT | SEGMENT_USER | SEGMENT_PRESENT,
+
+ // User Code-Segment 64Bit
+ SEGMENT_CODE | SEGMENT_LM | SEGMENT_USER | SEGMENT_PRESENT,
+
+ // Task State - Segment
+ SEGMENT_BASE((uintptr_t) 0 /*TODO*/) |
+ SEGMENT_SIZE(0x67) | SEGMENT_TSS | SEGMENT_PRESENT,
+ SEGMENT_BASE64((uintptr_t) 0 /*TODO*/)
+};
+
+void gdt_init()
+{
+ gdtr.base = (uintptr_t) gdt;
+ gdtr.limit = sizeof(gdt) - 1;
+}
+
+void gdt_init_local()
+{
+ asm volatile ("lgdt %0\n" : : "m"(gdtr));
+}
diff --git a/src/kernel2/src/arch/amd64/header.S b/src/kernel2/src/arch/amd64/header.S
index e272487..9dc6240 100644
--- a/src/kernel2/src/arch/amd64/header.S
+++ b/src/kernel2/src/arch/amd64/header.S
@@ -40,7 +40,6 @@
.section .text
_start:
- lgdt gdtr64
// Stack initalisieren
lea kernelstack, %rsp
@@ -67,31 +66,3 @@ _start:
.space 16384
kernelstack:
-.section .data
- gdt64:
- // Der Nulldeskriptor
- .word 0x0000
- .word 0x0000
- .word 0x0000
- .word 0x0000
-
- // Der Code-Deskriptor
- .word 0x0000
- .word 0x0000
- .word 0x9800
- .word 0x0020
-
- // Der Daten-Deskriptor:
- .word 0x0000
- .word 0x0000
- .word 0x9000
- .word 0x0000
-
- // Struktur um die GDT laden zu koennen
- .globl gdtr64
- gdtr64:
- // Wir haben 3 Eintraege
- .word 3 * 8
- .quad gdt64
-
-
diff --git a/src/kernel2/src/arch/amd64/loader/startup.S b/src/kernel2/src/arch/amd64/loader/startup.S
index 6a620de..c08d067 100644
--- a/src/kernel2/src/arch/amd64/loader/startup.S
+++ b/src/kernel2/src/arch/amd64/loader/startup.S
@@ -151,8 +151,8 @@
movl %eax, %cr0
// Die neue GDT laden
- lgdt gdtr64
- jmp $0x8, $longmode
+ lgdt init_gdtr
+ jmp $0x18, $longmode
.code64
longmode:
@@ -226,13 +226,13 @@
stack_space:
.section .data
-.code16
- // Die GDT besteht nur aus 3 Deskriptoren: Null, Code und Daten
- gdt32:
+ // Die GDT besteht nur aus 4 Deskriptoren: Null, 32-Bit-Code, Daten und
+ // 64-Bit-Code
+ init_gdt:
// Null-Deskriptor
.quad 0
- // Code-Deskriptor
+ // 32-Bit-Code-Deskriptor
.word 0xFFFF
.word 0x0000
.byte 0x00
@@ -247,38 +247,16 @@
.byte 0x92
.byte 0xCF
.byte 0x00
-
- gdtr32:
- .word 3 * 8
- .int gdt32
-
-.code32
- // Die GDT besteht nur aus 3 Deskriptoren: Null, Code und Daten
- .globl gdt64
- gdt64:
- // Der Nulldeskriptor
- .quad 0
- // Der Code-Deskriptor
+ // 64-Bit-Code-Deskriptor
.int 0
.byte 0
.byte 0x98
.byte 0x20
.byte 0
- // Der Daten-Deskriptor:
- .int 0
- .byte 0
- .byte 0x92
- .byte 0
- .byte 0
-
- // Struktur um die GDT laden zu koennen
- .globl gdtr64
- gdtr64:
- // Wir haben 3 Eintraege
- .word 3 * 8
- .quad gdt64
-
+ init_gdtr:
+ .word 4 * 8
+ .int init_gdt
diff --git a/src/kernel2/src/arch/amd64/smp/trampoline.S b/src/kernel2/src/arch/amd64/smp/trampoline.S
index be87b58..18929cb 100644
--- a/src/kernel2/src/arch/amd64/smp/trampoline.S
+++ b/src/kernel2/src/arch/amd64/smp/trampoline.S
@@ -76,9 +76,9 @@ smp_entry_lock_loop:
movl %eax, %cr0
// Die neue GDT laden
- .extern gdtr64
- lgdt gdtr64
- jmp $0x8, $smp_entry_longmode
+ .extern gdtr
+ lgdt gdtr
+ jmp $0x18, $smp_entry_longmode
.code64
smp_entry_longmode:
@@ -119,32 +119,6 @@ smp_entry_longmode:
// Geschieht nie
hlt
-/*.section .data
- gdt64:
- // Der Nulldeskriptor
- .word 0x0000
- .word 0x0000
- .word 0x0000
- .word 0x0000
-
- // Der Code-Deskriptor
- .word 0x0000
- .word 0x0000
- .word 0x9800
- .word 0x0020
-
- // Der Daten-Deskriptor:
- .word 0x0000
- .word 0x0000
- .word 0x9000
- .word 0x0000
-
- // Struktur um die GDT laden zu koennen
- gdtr64:
- // Wir haben 3 Eintraege
- .word 3 * 8
- .quad gdt64
-*/
.section .bss
// Wird fuer den Stack waehrend der SMP-Initialisierung benutzt, solange noch
--
1.7.11.7