From 15c7d247151bc35de3031b12e9862668b3bb6251 Mon Sep 17 00:00:00 2001 From: Malo Lecomte Date: Tue, 13 Jul 2021 05:05:58 +0200 Subject: [PATCH 1/8] feat(gdt): add gdt_entry struct --- k/gdt.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 k/gdt.h diff --git a/k/gdt.h b/k/gdt.h new file mode 100644 index 0000000..096dbd5 --- /dev/null +++ b/k/gdt.h @@ -0,0 +1,24 @@ +#ifndef GDT_H +#define GDT_H + +#include + +struct gdt_entry +{ + uint8_t base_3 : 8; + uint8_t granularity : 1; + uint8_t db : 1; + uint8_t l : 1; + uint8_t available : 1; + uint8_t limit_2 : 4; + uint8_t present : 1; + uint8_t desc_priv : 2; + uint8_t desc_type : 1; + uint8_t seg_type : 4; + uint8_t base_2 : 8; + uint16_t base_1 : 16; + uint16_t limit_1 : 16; + +}; + +#endif /* !GDT_H */ From 2ee5432c9add9119c4a255f3564d3bde1c67fc05 Mon Sep 17 00:00:00 2001 From: Julien CLEMENT Date: Tue, 13 Jul 2021 18:19:12 +0200 Subject: [PATCH 2/8] feat(gdt): pack gdt_entry struct Signed-off-by: Julien CLEMENT --- k/gdt.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/k/gdt.h b/k/gdt.h index 096dbd5..672678c 100644 --- a/k/gdt.h +++ b/k/gdt.h @@ -5,20 +5,19 @@ struct gdt_entry { - uint8_t base_3 : 8; + uint8_t base_3 : 8; uint8_t granularity : 1; uint8_t db : 1; uint8_t l : 1; uint8_t available : 1; uint8_t limit_2 : 4; - uint8_t present : 1; + uint8_t present : 1; uint8_t desc_priv : 2; uint8_t desc_type : 1; uint8_t seg_type : 4; uint8_t base_2 : 8; uint16_t base_1 : 16; uint16_t limit_1 : 16; - -}; +} __attribute__ ((packed)); #endif /* !GDT_H */ From 67ec69bdde5e56a9edb04edd5f85da5b10923452 Mon Sep 17 00:00:00 2001 From: Julien CLEMENT Date: Tue, 13 Jul 2021 20:10:35 +0200 Subject: [PATCH 3/8] fix(gdt): put lsb first in gdt-entry bitfields Signed-off-by: Julien CLEMENT --- k/gdt.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/k/gdt.h b/k/gdt.h index 672678c..2272b7f 100644 --- a/k/gdt.h +++ b/k/gdt.h @@ -5,19 +5,19 @@ struct gdt_entry { - uint8_t base_3 : 8; - uint8_t granularity : 1; - uint8_t db : 1; - uint8_t l : 1; - uint8_t available : 1; - uint8_t limit_2 : 4; - uint8_t present : 1; - uint8_t desc_priv : 2; - uint8_t desc_type : 1; - uint8_t seg_type : 4; - uint8_t base_2 : 8; - uint16_t base_1 : 16; uint16_t limit_1 : 16; + uint16_t base_1 : 16; + uint8_t base_2 : 8; + uint8_t seg_type : 4; + uint8_t desc_type : 1; + uint8_t desc_priv : 2; + uint8_t present : 1; + uint8_t limit_2 : 4; + uint8_t available : 1; + uint8_t l : 1; + uint8_t db : 1; + uint8_t granularity : 1; + uint8_t base_3 : 8; } __attribute__ ((packed)); #endif /* !GDT_H */ From e862a4185bcb64bf1e39c6a746ac06cd39fb23da Mon Sep 17 00:00:00 2001 From: Julien CLEMENT Date: Tue, 13 Jul 2021 21:38:19 +0200 Subject: [PATCH 4/8] feat(gdt): add gdt loading Signed-off-by: Julien CLEMENT --- k/Makefile | 3 ++- k/gdt.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ k/gdt.h | 26 +++++++++++++++++++ k/serial.c | 4 +-- 4 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 k/gdt.c diff --git a/k/Makefile b/k/Makefile index 52aacbd..02ba1c9 100644 --- a/k/Makefile +++ b/k/Makefile @@ -30,7 +30,8 @@ OBJS = \ libvga.o \ list.o \ memory.o \ - serial.o + serial.o \ + gdt.o DEPS = $(OBJS:.o=.d) diff --git a/k/gdt.c b/k/gdt.c new file mode 100644 index 0000000..7901109 --- /dev/null +++ b/k/gdt.c @@ -0,0 +1,74 @@ +#include "gdt.h" + +static struct gdt gdt = { 0 }; + +static void create_kernel_ds() +{ +} + +static void create_kernel_cs() +{ +} + +static void create_gdt() +{ + create_kernel_ds(); + create_kernel_cs(); +} + +static void load_gdt() +{ + struct gdt_r gdtr; + gdtr.addr = (uint32_t)&gdt; + gdtr.limit = GDT_SIZE - 1; + + asm volatile("lgdt %0\n" + : + : "m" (gdtr) + : "memory"); +} + +static void load_ds() +{ + struct segment_selector selector; + selector.index = KERNEL_DS_INDEX; + selector.table_indicator = 0; + selector.rpl = 0; + + asm volatile("movw %0, %%ax\n" + "movw %%ax, %%ds\n" + "movw %%ax, %%fs\n" + "movw %%ax, %%gs\n" + "movw %%ax, %%ss\n" + : + : "m" (selector) + : "ax"); +} + +static void load_cs() +{ + struct segment_selector selector; + selector.index = KERNEL_CS_INDEX; + selector.table_indicator = 0; + selector.rpl = 0; + + asm volatile("pushl %0\n" + "pushl $1f\n" + "lret\n" + "1:\n" + : + : "m" (selector)); +} + +static void reload_segment_selectors() +{ + load_ds(); + load_cs(); +} + +void init_gdt() +{ + create_gdt(); + load_gdt(); + reload_segment_selectors(); +} diff --git a/k/gdt.h b/k/gdt.h index 2272b7f..269fb60 100644 --- a/k/gdt.h +++ b/k/gdt.h @@ -3,6 +3,12 @@ #include +#define GDT_NB_ENTRIES 3 +#define GDT_SIZE (GDT_NB_ENTRIES * sizeof(struct gdt_entry)) + +#define KERNEL_CS_INDEX 1 +#define KERNEL_DS_INDEX 2 + struct gdt_entry { uint16_t limit_1 : 16; @@ -20,4 +26,24 @@ struct gdt_entry uint8_t base_3 : 8; } __attribute__ ((packed)); +struct gdt +{ + struct gdt_entry entries[GDT_NB_ENTRIES]; +}; + +struct gdt_r +{ + uint32_t addr; + uint16_t limit; +} __attribute__ ((packed)); + +struct segment_selector +{ + uint8_t rpl : 2; + uint8_t table_indicator : 1; + uint16_t index : 13; +} __attribute__ ((packed)); + +void init_gdt(); + #endif /* !GDT_H */ diff --git a/k/serial.c b/k/serial.c index d18469c..570b7fe 100644 --- a/k/serial.c +++ b/k/serial.c @@ -24,12 +24,12 @@ void init_serial(void) int write(const char *buf, size_t count) { - int sent; + size_t sent; for(sent = 0; sent < count; ++sent) { u8 line_status = inb(COM1 + 5); - if (!line_status & EMPTY_TRANSMITTER) + if (!(line_status & EMPTY_TRANSMITTER)) break; outb(COM1, buf[sent]); } From a5ff8a6a9288e4386140fe6db934edc49264374d Mon Sep 17 00:00:00 2001 From: Julien CLEMENT Date: Tue, 13 Jul 2021 22:31:01 +0200 Subject: [PATCH 5/8] feat(gdt): add gdt kernel entries creation Signed-off-by: Julien CLEMENT --- k/gdt.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ k/gdt.h | 5 ++++- k/k.c | 1 + 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/k/gdt.c b/k/gdt.c index 7901109..7677c59 100644 --- a/k/gdt.c +++ b/k/gdt.c @@ -4,10 +4,58 @@ static struct gdt gdt = { 0 }; static void create_kernel_ds() { + struct gdt_entry *entry = gdt.entries + KERNEL_DS_INDEX; + + uint32_t limit = 0xffff; + uint32_t base = 0x0; + + entry->granularity = 1; + entry->db = 1; + entry->l = 0; + entry->available = 0; + + entry->present = 1; + entry->desc_priv = 0; + entry->desc_type = 1; + entry->ex = 0; + entry->dc = 0; + entry->rw = 1; + entry->accessed = 0; + + entry->limit_1 = limit & 0xffff; + entry->limit_2 = (limit >> 16) & 0xf; + + entry->base_1 = base & 0xffff; + entry->base_2 = (base >> 16) & 0xff; + entry->base_3 = (base >> 24) & 0xff; } static void create_kernel_cs() { + struct gdt_entry *entry = gdt.entries + KERNEL_CS_INDEX; + + uint32_t limit = 0xffff; + uint32_t base = 0x0; + + entry->granularity = 1; + entry->db = 1; + entry->l = 0; + entry->available = 0; + + entry->present = 1; + entry->desc_priv = 0; + entry->desc_type = 1; + entry->ex = 1; + entry->dc = 0; + entry->rw = 1; + entry->accessed = 0; + + entry->limit_1 = limit & 0xffff; + entry->limit_2 = (limit >> 16) & 0xf; + + entry->base_1 = base & 0xffff; + entry->base_2 = (base >> 16) & 0xff; + entry->base_3 = (base >> 24) & 0xff; } static void create_gdt() @@ -62,13 +110,18 @@ static void load_cs() static void reload_segment_selectors() { + printf("Before load_ds\r\n"); load_ds(); load_cs(); } void init_gdt() { + printf("Before create_gdt\r\n"); create_gdt(); + printf("Before load_gdt\r\n"); load_gdt(); + printf("Before reload_segment_selectors\r\n"); reload_segment_selectors(); + printf("All good\r\n"); } diff --git a/k/gdt.h b/k/gdt.h index 269fb60..9e1adbb 100644 --- a/k/gdt.h +++ b/k/gdt.h @@ -14,7 +14,10 @@ struct gdt_entry uint16_t limit_1 : 16; uint16_t base_1 : 16; uint8_t base_2 : 8; - uint8_t seg_type : 4; + uint8_t accessed : 1; + uint8_t rw : 1; + uint8_t dc : 1; + uint8_t ex : 1; uint8_t desc_type : 1; uint8_t desc_priv : 2; uint8_t present : 1; diff --git a/k/k.c b/k/k.c index 3fce470..a66b1e0 100644 --- a/k/k.c +++ b/k/k.c @@ -30,6 +30,7 @@ static void k_init(void) { init_serial(); + init_gdt(); } void k_main(unsigned long magic, multiboot_info_t *info) From 5ed734fae5a4ccae8559e9114c4a47789bb10f15 Mon Sep 17 00:00:00 2001 From: Malo Lecomte Date: Tue, 13 Jul 2021 22:47:20 +0200 Subject: [PATCH 6/8] fix(gdt): set limit to 0xfffff --- k/gdt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/k/gdt.c b/k/gdt.c index 7677c59..64dde20 100644 --- a/k/gdt.c +++ b/k/gdt.c @@ -6,7 +6,7 @@ static void create_kernel_ds() { struct gdt_entry *entry = gdt.entries + KERNEL_DS_INDEX; - uint32_t limit = 0xffff; + uint32_t limit = 0xfffff; uint32_t base = 0x0; entry->granularity = 1; @@ -34,7 +34,7 @@ static void create_kernel_cs() { struct gdt_entry *entry = gdt.entries + KERNEL_CS_INDEX; - uint32_t limit = 0xffff; + uint32_t limit = 0xfffff; uint32_t base = 0x0; entry->granularity = 1; From 2f06fe3f8b997e3e266423b84add9381dac903dc Mon Sep 17 00:00:00 2001 From: Malo Lecomte Date: Wed, 14 Jul 2021 03:15:58 +0200 Subject: [PATCH 7/8] feat(bochsrc): add magic breakpoints for bochs --- .bochsrc | 1 + 1 file changed, 1 insertion(+) diff --git a/.bochsrc b/.bochsrc index 10c2e4f..4808a27 100644 --- a/.bochsrc +++ b/.bochsrc @@ -11,6 +11,7 @@ clock: sync=realtime ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 ata0-master: type=cdrom, path="k.iso", status=inserted boot: cdrom +magic_break: enabled=1 # write serial logs to stdout com1: enabled=1, mode=file, dev=/dev/stdout From 5a2f104d9a0e85fa6947c6da6a4916c4e82d0422 Mon Sep 17 00:00:00 2001 From: Malo Lecomte Date: Wed, 14 Jul 2021 03:16:49 +0200 Subject: [PATCH 8/8] fix(gdt): revert gdt_r bitfield --- k/gdt.c | 5 ----- k/gdt.h | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/k/gdt.c b/k/gdt.c index 64dde20..c8e0182 100644 --- a/k/gdt.c +++ b/k/gdt.c @@ -110,18 +110,13 @@ static void load_cs() static void reload_segment_selectors() { - printf("Before load_ds\r\n"); load_ds(); load_cs(); } void init_gdt() { - printf("Before create_gdt\r\n"); create_gdt(); - printf("Before load_gdt\r\n"); load_gdt(); - printf("Before reload_segment_selectors\r\n"); reload_segment_selectors(); - printf("All good\r\n"); } diff --git a/k/gdt.h b/k/gdt.h index 9e1adbb..95028f7 100644 --- a/k/gdt.h +++ b/k/gdt.h @@ -36,8 +36,8 @@ struct gdt struct gdt_r { - uint32_t addr; uint16_t limit; + uint32_t addr; } __attribute__ ((packed)); struct segment_selector