gdt
authorJohn Tsiombikas <nuclear@member.fsf.org>
Fri, 11 Jun 2021 02:36:14 +0000 (05:36 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Fri, 11 Jun 2021 02:36:14 +0000 (05:36 +0300)
sys1/kern/src/desc.c [new file with mode: 0644]
sys1/kern/src/desc.h [new file with mode: 0644]
sys1/kern/src/main.c
sys1/kern/src/mem.asm [new file with mode: 0644]
sys1/kern/src/mem.c [new file with mode: 0644]
sys1/kern/src/mem.h [new file with mode: 0644]

diff --git a/sys1/kern/src/desc.c b/sys1/kern/src/desc.c
new file mode 100644 (file)
index 0000000..d02c5fc
--- /dev/null
@@ -0,0 +1,45 @@
+#include "desc.h"
+
+#define SEG_TYPE_SYSTEM        0
+#define SEG_TYPE_CODE  0x00001800
+#define SEG_TYPE_DATA  0x00001000
+#define SEG_TYPE_TSS   0x00000100
+#define SEG_TYPE_INTR  0x00000e00
+#define SEG_TYPE_TRAP  0x00000f00
+
+#define SEG_ACCESSED   0x00000100
+#define SEG_PRESENT            0x00008000
+#define SEG_AVL                        0x00100000
+#define SEG_GRAN               0x00800000
+
+/* data segment type flags */
+#define SEG_WR                 0x00000200
+#define SEG_EXPDN              0x00000400
+#define SEG_BIG                        0x00400000
+/* code segment type flags */
+#define SEG_RD                 0x00000200
+#define SEG_CONFORM            0x00000400
+#define SEG_DEF                        0x00400000
+
+
+void desc_seg(struct desc *desc, int type, uint32_t base, uint32_t limit, int dpl)
+{
+       if(type == SEG_NULL) {
+               desc->d[0] = desc->d[1] = 0;
+               return;
+       }
+
+       desc->d[0] = (limit & 0xffff) | (base << 16);
+       desc->d[1] = ((base >> 16) & 0xff) | (type << 8) | SEG_PRESENT | (dpl << 13);
+       desc->d[1] |= (base & 0xff000000) | (limit & 0xf0000) | SEG_AVL | SEG_GRAN;
+
+       switch(type) {
+       case SEG_CODE:
+               desc->d[1] |= (3 << 11) | SEG_DEF | SEG_RD;
+               break;
+
+       case SEG_DATA:
+               desc->d[1] |= (2 << 11) | SEG_WR;
+               break;
+       }
+}
diff --git a/sys1/kern/src/desc.h b/sys1/kern/src/desc.h
new file mode 100644 (file)
index 0000000..9d9f700
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef DESC_H_
+#define DESC_H_
+
+#include <stdint.h>
+
+struct desc {
+       uint32_t d[2];
+};
+
+enum { SEG_NULL, SEG_CODE, SEG_DATA, SEG_TSS };
+
+void desc_seg(struct desc *desc, int type, uint32_t base, uint32_t limit, int dpl);
+
+#endif /* DESC_H_ */
index 2e7a280..3d89aa9 100644 (file)
@@ -2,6 +2,7 @@
 #include <string.h>
 #include <stdint.h>
 #include "vga.h"
+#include "mem.h"
 
 void drawtext(int x, int y, const char *s)
 {
@@ -19,6 +20,8 @@ void kmain(void)
 
        vga_reset();
 
+       mem_init();
+
        line = 0;
        for(;;) {
                scroll = line <= 24 ? 0 : line - 24;
diff --git a/sys1/kern/src/mem.asm b/sys1/kern/src/mem.asm
new file mode 100644 (file)
index 0000000..3a4bf85
--- /dev/null
@@ -0,0 +1,18 @@
+       bits 32
+       section .text
+
+       global set_gdt
+set_gdt:
+       mov eax, [esp + 4]
+       mov [gdtbase], eax
+       mov ax, [esp + 8]
+       mov [gdtlim], ax
+       lgdt [gdtlim]
+       ret
+
+       align 4
+       dw 0
+gdtlim dw 0
+gdtbase dd 0
+
+; vi:ft=nasm:
diff --git a/sys1/kern/src/mem.c b/sys1/kern/src/mem.c
new file mode 100644 (file)
index 0000000..898ef3f
--- /dev/null
@@ -0,0 +1,22 @@
+#include "mem.h"
+#include "desc.h"
+
+void set_gdt(void *addr, uint16_t limit);
+
+enum {
+       SEG_NULL        = 0,
+       SEG_KCODE       = 1,
+       SEG_KDATA       = 2
+};
+
+#define NUM_SEG                3
+static struct desc gdt[NUM_SEG] __attribute__((aligned(8)));
+
+void mem_init(void)
+{
+       desc_seg(gdt, SEG_NULL, 0, 0, 0);
+       desc_seg(gdt + SEG_KCODE, SEG_CODE, 0, 0xffffffff, 0);
+       desc_seg(gdt + SEG_KDATA, SEG_DATA, 0, 0xffffffff, 0);
+
+       set_gdt(gdt, sizeof gdt - 1);
+}
diff --git a/sys1/kern/src/mem.h b/sys1/kern/src/mem.h
new file mode 100644 (file)
index 0000000..1517e3e
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef MEM_H_
+#define MEM_H_
+
+void mem_init(void);
+
+#endif /* MEM_H_ */