From: John Tsiombikas Date: Fri, 11 Jun 2021 02:36:14 +0000 (+0300) Subject: gdt X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=3sys;a=commitdiff_plain;h=0d2d1730817f3ef5fc766149f2598480094cbae8 gdt --- diff --git a/sys1/kern/src/desc.c b/sys1/kern/src/desc.c new file mode 100644 index 0000000..d02c5fc --- /dev/null +++ b/sys1/kern/src/desc.c @@ -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 index 0000000..9d9f700 --- /dev/null +++ b/sys1/kern/src/desc.h @@ -0,0 +1,14 @@ +#ifndef DESC_H_ +#define DESC_H_ + +#include + +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_ */ diff --git a/sys1/kern/src/main.c b/sys1/kern/src/main.c index 2e7a280..3d89aa9 100644 --- a/sys1/kern/src/main.c +++ b/sys1/kern/src/main.c @@ -2,6 +2,7 @@ #include #include #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 index 0000000..3a4bf85 --- /dev/null +++ b/sys1/kern/src/mem.asm @@ -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 index 0000000..898ef3f --- /dev/null +++ b/sys1/kern/src/mem.c @@ -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 index 0000000..1517e3e --- /dev/null +++ b/sys1/kern/src/mem.h @@ -0,0 +1,6 @@ +#ifndef MEM_H_ +#define MEM_H_ + +void mem_init(void); + +#endif /* MEM_H_ */