aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoic Guegan <manzerbredes@mailbox.org>2021-04-05 14:46:31 +0200
committerLoic Guegan <manzerbredes@mailbox.org>2021-04-05 14:46:31 +0200
commitba7e57138c9e41cf944afb91c146fea23713c1d1 (patch)
tree3a57bd313ee7a7fd8535286e3364ef47bb7aa705
parentb54b87ad2d41e60e9be1e299140dbf59e76c8fc6 (diff)
Reload GDT
-rw-r--r--src/Makefile11
-rw-r--r--src/boot/boot.S26
-rw-r--r--src/utils/gdt.c52
-rw-r--r--src/utils/gdt.h44
-rw-r--r--src/utils/mem.c8
-rw-r--r--src/utils/mem.h9
-rw-r--r--src/utils/print.c42
-rw-r--r--src/utils/print.h9
8 files changed, 182 insertions, 19 deletions
diff --git a/src/Makefile b/src/Makefile
index 0dee4ff..f5f9c83 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,5 +1,5 @@
EXEC := bringelle
-CC := gcc -c -m32 -fno-pie -fno-builtin
+CC := gcc -c -m32 -fno-pie -fno-builtin -fno-stack-protector
UTILS_SRC := $(wildcard utils/*.c)
@@ -16,14 +16,19 @@ bringelle.o: bringelle.c
$(CC) $^
utils.o: $(UTILS_SRC)
- $(CC) $^ -o $@
+ for src in $^ ;\
+ do \
+ obj=$$(basename $${src} ".c")".o" ;\
+ $(CC) $${src} -o utils/$${obj} ;\
+ done
+ ld -melf_i386 -relocatable utils/*.o -o utils.o
boot.o: ./boot/boot.S
as --32 -o $@ $^ -mx86-used-note=no
clean:
+ find ./ -name "*.o" -delete
- rm $(EXEC)
- - rm ./*.o
.PHONY: clean
diff --git a/src/boot/boot.S b/src/boot/boot.S
index 746f858..e3830eb 100644
--- a/src/boot/boot.S
+++ b/src/boot/boot.S
@@ -1,4 +1,5 @@
.extern bringelle
+.extern gdt_memcpy
.globl _start
.text
@@ -23,5 +24,28 @@ mb_header:
.long MB_ENTRY_ADDR
_start:
- call bringelle
+
+# Copy GDT into memory then load its register
+call gdt_memcpy
+lgdtl (GDTR)
+
+# Update all segments register
+# with the new GDT offset
+movw $0x10, %ax
+movw %ax, %ds
+movw %ax, %es
+movw %ax, %fs
+movw %ax, %gs
+
+# Update code segment
+ljmp $0x08, $cs_new
+cs_new:
+
+# Update stack segment
+movw $0x18, %ax
+movw %ax, %ss
+movl $0x20000,%esp
+
+# Start kernel main function
+call bringelle
diff --git a/src/utils/gdt.c b/src/utils/gdt.c
new file mode 100644
index 0000000..85c4a09
--- /dev/null
+++ b/src/utils/gdt.c
@@ -0,0 +1,52 @@
+#include "gdt.h"
+#include "print.h"
+#include "mem.h"
+
+struct GDT_REGISTER GDTR = { 0, 0 };
+
+void gdt_memcpy(){
+ GDTR.limit=8*4; // Each entry is 8 bytes and 4 entries
+ GDTR.base=0x800;
+
+ GDT_ENTRY cs_desc;
+ cs_desc.base=0;
+ cs_desc.limit=0xFFFFF;
+ cs_desc.flags=GDT_SZ|GDT_GR;
+ cs_desc.access=GDT_PR|GDT_PRVL_0|GDT_S|GDT_EXEC|GDT_RW;
+
+ GDT_ENTRY ds_desc;
+ ds_desc.base=0;
+ ds_desc.limit=0xFFFFF;
+ ds_desc.flags=GDT_SZ|GDT_GR;
+ ds_desc.access=GDT_PR|GDT_PRVL_0|GDT_S|GDT_RW;
+
+ GDT_ENTRY ss_desc;
+ ss_desc.base=0;
+ ss_desc.limit=0;
+ ss_desc.flags=GDT_SZ|GDT_GR;
+ ss_desc.access=GDT_PR|GDT_PRVL_0|GDT_S|GDT_RW|GDT_DC;
+
+ // Write GDT descriptors into memory
+ gdt_write_entry((GDT_ENTRY){0,0,0,0},GDTR.base); // First one must be null
+ gdt_write_entry(cs_desc, GDTR.base+8); // Each entry is 64 bits (8 bytes)
+ gdt_write_entry(ds_desc, GDTR.base+8*2);
+ gdt_write_entry(ss_desc, GDTR.base+8*3);
+}
+
+void gdt_write_entry(GDT_ENTRY entry, u32 addr){
+ int descriptor[2];
+
+ // First row of the descriptor
+ descriptor[0]=(entry.limit & 0xFFFF)|(entry.base << 16);
+
+ // Format second row of the descriptor
+ u16 base=(entry.base >> 16) & 0xFF;
+ u16 access=entry.access & 0xFF;
+ u16 limit=(entry.limit >> 16) & 0xF; // Remember: limits it is on 20 bits so 4 last bits
+ u8 flags=entry.flags & 0xF;
+ u8 base2=entry.base >> 24; // Take the last 8 bits
+ descriptor[1]=base|access<<8|limit<<16|flags<<20|base2<<24;
+
+ // Copy descriptor into memory
+ memcpy(descriptor,(void*)addr,8);
+}
diff --git a/src/utils/gdt.h b/src/utils/gdt.h
new file mode 100644
index 0000000..85a75aa
--- /dev/null
+++ b/src/utils/gdt.h
@@ -0,0 +1,44 @@
+#ifndef GDT_H
+#define GDT_H
+
+#include "types.h"
+
+// Access byte
+#define GDT_AC 1 // Access bit
+#define GDT_RW 1 << 1 // Read/Write bit
+#define GDT_DC 1 << 2 // Direction bit/Conforming bit
+#define GDT_EXEC 1 << 3 // Executable bit
+#define GDT_S 1 << 4 // Descriptor type
+#define GDT_PRVL_0 0 // Privilege (from 0 to 3)
+#define GDT_PRVL_1 1 << 5
+#define GDT_PRVL_2 2 << 5
+#define GDT_PRVL_3 3 << 5
+#define GDT_PR 1 << 7 // Present Bit
+
+// Flags
+#define GDT_SZ 1 << 2 // Size bit
+#define GDT_GR 1 << 3 // Granularity bit
+
+typedef struct GDT_ENTRY {
+ u32 base;
+ u32 limit;
+ u8 flags;
+ u8 access;
+} GDT_ENTRY;
+
+struct GDT_REGISTER {
+ u16 limit;
+ u32 base;
+} __attribute__((packed));
+
+/**
+ * Copy GDT in memory
+ */
+void gdt_memcpy();
+
+/**
+ * Write a GDT entry at address addr
+ */
+void gdt_write_entry(GDT_ENTRY entry, u32 addr);
+
+#endif
diff --git a/src/utils/mem.c b/src/utils/mem.c
new file mode 100644
index 0000000..4cefd6d
--- /dev/null
+++ b/src/utils/mem.c
@@ -0,0 +1,8 @@
+#include "mem.h"
+
+void memcpy(void *src, void *dst, int size){
+ u8 *char_src=(u8 *)src;
+ u8 *char_dst=(u8 *)dst;
+ for(int i=0;i<size;i++)
+ char_dst[i]=char_src[i];
+}
diff --git a/src/utils/mem.h b/src/utils/mem.h
new file mode 100644
index 0000000..b09c3f0
--- /dev/null
+++ b/src/utils/mem.h
@@ -0,0 +1,9 @@
+#ifndef MEM_H
+#define MEM_H
+
+#include "types.h"
+
+
+void memcpy(void *src, void *dst, int size);
+
+#endif
diff --git a/src/utils/print.c b/src/utils/print.c
index 8fab941..dbed000 100644
--- a/src/utils/print.c
+++ b/src/utils/print.c
@@ -1,24 +1,36 @@
#include "print.h"
-#include "types.h"
#define MAX_COL 80
#define MAX_LINE 25
-char *video=(char *)0xB8000;
-u8 col=0;
-u8 line=0;
+struct VIDEO_STATE {
+ u8 *mem;
+ u8 col;
+ u8 line;
+ u8 bg;
+ u8 fg;
+};
+VIDEO_STATE VS={
+ (u8 *)0xB8000,
+ 0,
+ 0,
+ BLACK,
+ GRAY,
+};
void putchar(char c){
// Print char
- video[col*2+MAX_COL*line*2]=c;
+ VS.mem[VS.col*2+MAX_COL*VS.line*2]=c;
+ VS.mem[VS.col*2+MAX_COL*VS.line*2+1]=VS.fg|VS.bg<<4;
+
// Refresh location
- col+=1;
- if(col>= MAX_COL){
- col=0;
- line+=1;
- if(line>=MAX_LINE){
- line=MAX_LINE-1;
+ VS.col+=1;
+ if(VS.col>= MAX_COL){
+ VS.col=0;
+ VS.line+=1;
+ if(VS.line>=MAX_LINE){
+ VS.line=MAX_LINE-1;
scrollup();
}
}
@@ -39,13 +51,13 @@ void clear(){
}
void scrollup(){
- // Move line up
+ // Move VS.line up
for(char i=1;i<=MAX_LINE;i++){
for(char j=0;j<=MAX_COL;j++)
- video[j*2+MAX_COL*(i-1)*2]=video[j*2+MAX_COL*i*2];
+ VS.mem[j*2+MAX_COL*(i-1)*2]=VS.mem[j*2+MAX_COL*i*2];
}
- // Clear last line
+ // Clear last VS.line
for(char i=0;i<=MAX_COL;i++){
- video[col*2+MAX_COL*(MAX_LINE-1)*2]='\0';
+ VS.mem[i*2+MAX_COL*(MAX_LINE-1)*2]='\0';
}
}
diff --git a/src/utils/print.h b/src/utils/print.h
index fb1badd..d04fed2 100644
--- a/src/utils/print.h
+++ b/src/utils/print.h
@@ -1,6 +1,15 @@
#ifndef PRINT_H
#define PRINT_H
+#include "types.h"
+
+typedef enum VIDEO_COLORS {
+ BLACK=0, BLUE=1, GREEN=2,CYAN=3, RED=4,PURPLE=5,BROWN=6,GRAY=7,
+ DARK_GRAY=8,LIGHT_BLUE=9,LIGHT_GREEN=10,LIGHT_CYAN=11,LIGHT_RED=12,LIGHT_PURPLE=13,YELLOW=14,WHITE=15
+
+} VIDEO_COLORS;
+
+typedef struct VIDEO_STATE VIDEO_STATE;
/**
* Print char