aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorLoic Guegan <manzerbredes@mailbox.org>2021-04-12 10:13:21 +0200
committerLoic Guegan <manzerbredes@mailbox.org>2021-04-12 10:13:21 +0200
commit39713a3736145483dd3310c3605f940ca34f05c3 (patch)
treed4dcdf0f3b667a5d706aa4b04501a71facf186bd /src/core
parent6edeba8fe208fb019aec00fdc72b97407a8078d3 (diff)
Refactoring
Diffstat (limited to 'src/core')
-rw-r--r--src/core/asm.h13
-rw-r--r--src/core/framebuffer.c58
-rw-r--r--src/core/framebuffer.h35
-rw-r--r--src/core/gdt.c98
-rw-r--r--src/core/gdt.h77
-rw-r--r--src/core/mem.c8
-rw-r--r--src/core/mem.h11
-rw-r--r--src/core/paging.c31
-rw-r--r--src/core/paging.h13
-rw-r--r--src/core/syscall.c19
-rw-r--r--src/core/syscall.h9
-rw-r--r--src/core/types.h9
12 files changed, 381 insertions, 0 deletions
diff --git a/src/core/asm.h b/src/core/asm.h
new file mode 100644
index 0000000..be265d8
--- /dev/null
+++ b/src/core/asm.h
@@ -0,0 +1,13 @@
+#ifndef ASM_H
+#define ASM_H
+
+#define outb(port,value) \
+ asm volatile ("outb %%al, %%dx" :: "a"(value), "d" (port) )
+
+#define outbj(port,value) \
+ asm volatile ("outb %%al, %%dx;" :: "a" (value), "d"(port) )
+
+#define inb(port,dst) \
+ asm volatile ("inb %%dx, %%al": "=a" (dst) : "d" (port))
+
+#endif \ No newline at end of file
diff --git a/src/core/framebuffer.c b/src/core/framebuffer.c
new file mode 100644
index 0000000..110dc73
--- /dev/null
+++ b/src/core/framebuffer.c
@@ -0,0 +1,58 @@
+#include "framebuffer.h"
+
+#define MAX_COL 80
+#define MAX_LINE 25
+
+VIDEO_STATE VS={
+ (u8 *)0xB8000,
+ 0,
+ 0,
+ BLACK,
+ GRAY,
+};
+
+void putchar(char c){
+ // Handle newline here
+ if(c=='\n'){
+ VS.col=0;
+ VS.line+=1;
+ if(VS.line>=MAX_LINE){
+ VS.line=MAX_LINE-1;
+ scrollup();
+ }
+ return;
+ }
+
+ // Print char
+ 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
+ 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();
+ }
+ }
+}
+
+void clear(){
+ for(char i=0;i<MAX_LINE;i++){
+ scrollup();
+ }
+}
+
+void scrollup(){
+ // Move VS.line up
+ for(char i=1;i<=MAX_LINE;i++){
+ for(char j=0;j<=MAX_COL;j++)
+ VS.mem[j*2+MAX_COL*(i-1)*2]=VS.mem[j*2+MAX_COL*i*2];
+ }
+ // Clear last VS.line
+ for(char i=0;i<=MAX_COL;i++){
+ VS.mem[i*2+MAX_COL*(MAX_LINE-1)*2]='\0';
+ }
+}
diff --git a/src/core/framebuffer.h b/src/core/framebuffer.h
new file mode 100644
index 0000000..3d862d6
--- /dev/null
+++ b/src/core/framebuffer.h
@@ -0,0 +1,35 @@
+#ifndef FRAMEBUFFER_H
+#define FRAMEBUFFER_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 {
+ u8 *mem;
+ u8 col;
+ u8 line;
+ u8 bg;
+ u8 fg;
+} VIDEO_STATE;
+
+/**
+ * Print char
+ */
+void putchar(char);
+
+/**
+ * Scroll the framebuffer from one line
+ */
+void scrollup();
+
+/**
+ * Clear all char from the framebuffer
+ */
+void clear();
+
+#endif
diff --git a/src/core/gdt.c b/src/core/gdt.c
new file mode 100644
index 0000000..8c1c70d
--- /dev/null
+++ b/src/core/gdt.c
@@ -0,0 +1,98 @@
+#include "gdt.h"
+#include "mem.h"
+
+struct GDT_REGISTER GDTR = { 0, 0 };
+GDT_TSS TSS;
+
+void gdt_memcpy(){
+ GDTR.limit=8*GDT_MAX_ENTRIES; // Each entry is 8 bytes and 8 entries
+ GDTR.base=0x800;
+ gdt_write_entry((GDT_ENTRY){0,0,0,0},0); // First one must be null
+
+ // ----- Kernel Segments
+ 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(cs_desc, 1);
+ gdt_write_entry(ds_desc, 2);
+ gdt_write_entry(ss_desc, 3);
+
+ // ----- User Segments
+ GDT_ENTRY ucs_desc;
+ ucs_desc.base=0; // With paging will take care of allocating the right address for each task
+ ucs_desc.limit=0xFFFFF;
+ ucs_desc.flags=GDT_SZ|GDT_GR;
+ ucs_desc.access=GDT_PR|GDT_PRVL_3|GDT_S|GDT_EXEC|GDT_RW|GDT_DC;
+
+ GDT_ENTRY uds_desc;
+ uds_desc.base=0;
+ uds_desc.limit=0xFFFFF;
+ uds_desc.flags=GDT_SZ|GDT_GR;
+ uds_desc.access=GDT_PR|GDT_PRVL_3|GDT_S|GDT_RW;
+
+ GDT_ENTRY uss_desc;
+ uss_desc.base=0; // Not used in stack descriptor
+ uss_desc.limit=0x64; // Define how much entry it can contains
+ uss_desc.flags=GDT_SZ|GDT_GR;
+ uss_desc.access=GDT_PR|GDT_PRVL_3|GDT_S|GDT_RW|GDT_DC;
+
+ // Write GDT descriptors into memory
+ gdt_write_entry(ucs_desc, 4); // Each entry is 64 bits (8 bytes)
+ gdt_write_entry(uds_desc, 5);
+ gdt_write_entry(uss_desc, 6);
+
+ // Init TSS segment
+ TSS.t_reserved=0;
+ TSS.io_map=0;
+
+ GDT_ENTRY tss_desc;
+ tss_desc.base=(u32)&TSS; // Not used in stack descriptor
+ tss_desc.limit=0x68; // Define how much bytes it occupies
+ tss_desc.flags=0;
+ tss_desc.access=0x89 | GDT_PRVL_3; // Note that 0x89 is specific to TSS!
+ gdt_write_entry(tss_desc, 7);
+
+}
+
+void gdt_write_entry(GDT_ENTRY entry, u32 id){
+ 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*)GDTR.base+8*id,8); // Each entry is 64 bits (8 bytes)
+}
+
+int gdt_user_ds_base(){
+ char *addr=(char*)GDTR.base+48;
+ int *base0_15=(int*)addr+2;
+ int *base16_31=(int*)addr+7;
+ int base0_15_content=*base0_15 & 0xFFFF;
+ int base16_21_content=*base16_31 & 0xFFFF;
+ return(base16_21_content<<16 & base0_15_content);
+} \ No newline at end of file
diff --git a/src/core/gdt.h b/src/core/gdt.h
new file mode 100644
index 0000000..f010891
--- /dev/null
+++ b/src/core/gdt.h
@@ -0,0 +1,77 @@
+#ifndef GDT_H
+#define GDT_H
+
+#include "types.h"
+
+#define GDT_MAX_ENTRIES 8
+
+// 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));
+
+typedef struct GDT_TSS {
+ u16 previous_task,previous_task_unused;
+ u32 esp0;
+ u16 ss0, ss0_unused;
+ u32 esp1;
+ u16 ss1, ss1_unused;
+ u32 esp2;
+ u16 ss2, ss2_unused;
+ u32 cr3;
+ u32 eip;
+ u32 eflags;
+ u32 eax;
+ u32 ecx;
+ u32 edx;
+ u32 ebx;
+ u32 esp;
+ u32 ebp;
+ u32 esi;
+ u32 edi;
+ u16 es, es_reserved;
+ u16 cs, cs_reserved;
+ u16 ss, ss_reserved;
+ u16 ds, ds_reserved;
+ u16 fs, fs_reserved;
+ u16 gs, gs_reserved;
+ u16 ldtss, ldtss_reserved;
+ u16 t_reserved, io_map;
+} __attribute__((packed)) GDT_TSS;
+
+/**
+ * Copy GDT in memory
+ */
+void gdt_memcpy();
+
+/**
+ * Write a GDT entry at address addr
+ */
+void gdt_write_entry(GDT_ENTRY entry, u32 id);
+
+int gdt_user_ds_base();
+
+#endif
diff --git a/src/core/mem.c b/src/core/mem.c
new file mode 100644
index 0000000..4cefd6d
--- /dev/null
+++ b/src/core/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/core/mem.h b/src/core/mem.h
new file mode 100644
index 0000000..5bef441
--- /dev/null
+++ b/src/core/mem.h
@@ -0,0 +1,11 @@
+#ifndef MEM_H
+#define MEM_H
+
+#include "types.h"
+
+/**
+ * Copy size byte from *src to *dst
+ */
+void memcpy(void *src, void *dst, int size);
+
+#endif
diff --git a/src/core/paging.c b/src/core/paging.c
new file mode 100644
index 0000000..b1f462f
--- /dev/null
+++ b/src/core/paging.c
@@ -0,0 +1,31 @@
+#include "paging.h"
+
+void paging_enable(){
+ int *page_dir=(int*)PAGING_DIR_LOCATION;
+ int *page_table=(int*)PAGING_TABLE_LOCATION;
+
+ // Init page directory
+ for(int i=0;i<1024;i++)
+ page_dir[i]=0;
+ page_dir[0]=(int)page_table;
+ page_dir[0] |=7; // Permissions
+
+ // Init page table 0
+ int addr_offset=0;
+ for(int i=0;i<1024;i++){
+ page_table[i]=addr_offset;
+ page_table[i]|=7; // Permission
+ addr_offset+=4096; // 4Ko pages
+ }
+
+ // Turns on paging
+ asm(
+ "movl %0, %%eax \n\t"
+ "movl %%eax, %%cr3 \n\t" // Configure page table location
+ "movl %%cr0, %%eax \n\t"
+ "orl %1, %%eax \n\t"
+ "movl %%eax, %%cr0 \n\t" // Turn on paging
+ :: "i" (PAGING_DIR_LOCATION), "i" (PAGING_CR0_BIT)
+ );
+
+} \ No newline at end of file
diff --git a/src/core/paging.h b/src/core/paging.h
new file mode 100644
index 0000000..1e8f4e3
--- /dev/null
+++ b/src/core/paging.h
@@ -0,0 +1,13 @@
+#ifndef PAGING_H
+#define PAGING_H
+
+#define PAGING_CR0_BIT 0x80000000
+#define PAGING_DIR_LOCATION 0x1000
+#define PAGING_TABLE_LOCATION 0x5000
+
+/*
+ * Configure and enable paging
+ */
+void paging_enable();
+
+#endif \ No newline at end of file
diff --git a/src/core/syscall.c b/src/core/syscall.c
new file mode 100644
index 0000000..300b7aa
--- /dev/null
+++ b/src/core/syscall.c
@@ -0,0 +1,19 @@
+#include "syscall.h"
+#include "gdt.h"
+#include "libc/stdio.h"
+
+void syscall(){
+ int call_number;
+ asm("movl %%eax, %0":"=m"(call_number));
+ if(call_number==1){
+ int msg_addr;
+ asm("movl %%ebx, %0":"=m"(msg_addr));
+ char *msg=(char*)msg_addr;
+ print(msg);
+ }
+ else{
+ print("Syscall ");
+ printi(call_number);
+ print(" unknown");
+ }
+} \ No newline at end of file
diff --git a/src/core/syscall.h b/src/core/syscall.h
new file mode 100644
index 0000000..1f0c584
--- /dev/null
+++ b/src/core/syscall.h
@@ -0,0 +1,9 @@
+#ifndef SYSCALL_H
+#define SYSCALL_H
+
+/*
+ * Perform a syscall
+ */
+void syscall();
+
+#endif \ No newline at end of file
diff --git a/src/core/types.h b/src/core/types.h
new file mode 100644
index 0000000..071d8d6
--- /dev/null
+++ b/src/core/types.h
@@ -0,0 +1,9 @@
+#ifndef TYPES_H
+#define TYPES_H
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+typedef unsigned long long u64;
+
+#endif