diff options
| author | Loic Guegan <manzerbredes@mailbox.org> | 2021-04-12 10:13:21 +0200 |
|---|---|---|
| committer | Loic Guegan <manzerbredes@mailbox.org> | 2021-04-12 10:13:21 +0200 |
| commit | 39713a3736145483dd3310c3605f940ca34f05c3 (patch) | |
| tree | d4dcdf0f3b667a5d706aa4b04501a71facf186bd /src/core | |
| parent | 6edeba8fe208fb019aec00fdc72b97407a8078d3 (diff) | |
Refactoring
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/asm.h | 13 | ||||
| -rw-r--r-- | src/core/framebuffer.c | 58 | ||||
| -rw-r--r-- | src/core/framebuffer.h | 35 | ||||
| -rw-r--r-- | src/core/gdt.c | 98 | ||||
| -rw-r--r-- | src/core/gdt.h | 77 | ||||
| -rw-r--r-- | src/core/mem.c | 8 | ||||
| -rw-r--r-- | src/core/mem.h | 11 | ||||
| -rw-r--r-- | src/core/paging.c | 31 | ||||
| -rw-r--r-- | src/core/paging.h | 13 | ||||
| -rw-r--r-- | src/core/syscall.c | 19 | ||||
| -rw-r--r-- | src/core/syscall.h | 9 | ||||
| -rw-r--r-- | src/core/types.h | 9 |
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 |
