diff options
| author | Loic Guegan <manzerbredes@mailbox.org> | 2021-04-19 19:06:28 +0200 |
|---|---|---|
| committer | Loic Guegan <manzerbredes@mailbox.org> | 2021-04-19 19:06:28 +0200 |
| commit | ca1e725b0dc9b10997897dd2ac6d44028601d9bb (patch) | |
| tree | 0eb7bd087a2382d1d1a660ceda1eae01d1b8b3ca /src | |
| parent | f5146ca9c987ed5e6ea69a0c67b7ed03444be30c (diff) | |
Init sources
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile | 29 | ||||
| -rw-r--r-- | src/boot/boot.S | 128 | ||||
| -rw-r--r-- | src/boucane.c | 9 | ||||
| -rw-r--r-- | src/core/types.h | 9 | ||||
| -rw-r--r-- | src/drivers/framebuffer.c | 58 | ||||
| -rw-r--r-- | src/drivers/framebuffer.h | 35 | ||||
| -rw-r--r-- | src/libc/math.c | 32 | ||||
| -rw-r--r-- | src/libc/math.h | 9 | ||||
| -rw-r--r-- | src/libc/stdio.c | 25 | ||||
| -rw-r--r-- | src/libc/stdio.h | 21 | ||||
| -rw-r--r-- | src/libc/string.c | 29 | ||||
| -rw-r--r-- | src/libc/string.h | 9 | ||||
| -rw-r--r-- | src/linker.ld | 29 |
13 files changed, 422 insertions, 0 deletions
diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..7c2ee5f --- /dev/null +++ b/src/Makefile @@ -0,0 +1,29 @@ +EXEC := boucane +CC := gcc -c -fno-pie -fno-builtin -fno-stack-protector -I ./ +LD_SCRIPT := linker.ld + +# Note that BOOT_OBJ do not match boot.S +# Indeed boot.o generated by boot.S should appear +# first in the kernel binary (thus it must be linked first, cf the $(EXEC) rule) +BOOT_OBJ := $(addsuffix .o,$(basename $(shell find ./boot -name "*.[c|S]" ! -name "boot.S"))) +DRIVERS_OBJ := $(addsuffix .o,$(basename $(shell find ./drivers -name "*.[c|S]"))) +LIBC_OBJ := $(addsuffix .o,$(basename $(shell find ./libc -name "*.[c|S]"))) + +all: $(EXEC) + +$(EXEC): boot/boot.o $(BOOT_OBJ) $(DRIVERS_OBJ) $(LIBC_OBJ) boucane.o + ld -n -T $(LD_SCRIPT) -nostdlib -o $@ $^ + +%.o: %.S + as -o $@ $^ + +%.o: %.c + $(CC) -o $@ $< + +clean: + rm -f $(EXEC) + find ./ -name "*.o" -delete + +.PHONY: clean cdrom + + diff --git a/src/boot/boot.S b/src/boot/boot.S new file mode 100644 index 0000000..676ace7 --- /dev/null +++ b/src/boot/boot.S @@ -0,0 +1,128 @@ +.globl _start +.globl MB_INFO +.extern boucane +.extern _bss_start +.extern _bss_end +.extern boucane + +.set STACK_LOCATION, 0x1FFFFF + +.section .multiboot + +.set MB_MAGIC, 0xE85250D6 +.set MB_ARCH, 0x00000000 +.set MB_HEADER_LENGTH, (mb_header_end-mb_header_start) +.set MB_CHECKSUM, -(MB_MAGIC+MB_ARCH+MB_HEADER_LENGTH) + +mb_header_start: +.align 8 +.int MB_MAGIC +.int MB_ARCH +.int MB_HEADER_LENGTH +.int MB_CHECKSUM +# ----------- Address tag +.align 8 +.short 2 +.short 0 # Not optional +.int 24 # Size +.int mb_header_start # header_addr +.int mb_header_start # load_addr +.int 0x0 # load_end_addr +.int 0x0 # bss_end_addr +# ----------- Addr tag +.align 8 +.short 0x3 +.short 0 +.int 12 +.int _start +# ----------- End tag +.align 8 +.int 0x0 +.int 0x8 +mb_header_end: + +.section .text +.code32 # Require since grub do not enable long mode + +MB_INFO: + .int 0xABCDEF # Will contains the Multiboot2 information data structure address + +_start: +mov %ebx,(MB_INFO) + +# ----- Setup PAE Paging (identity on the first 10MB) +mov $8192, %ecx # 8*4096/4 (8 tables of 4096 byte each divide by 4 because of movl) +mov $0, %eax +zeroing_paging: +movl $0, (%eax) +add $4, %eax +loop zeroing_paging +# Setup PML4 Table (Address 0x0) +mov $0x0, %edi +mov %edi, %cr3 # Setup PML4 location +movl $0x1003, (%edi) # Setup PDPT location +# Setup PDPT +mov $0x1000, %edi +movl $0x2003, (%edi) # Setup PDPT location +# Setup PDT (5 PT = 10MB) +mov $0x2000, %edi +mov $0x3003, %eax +mov $5, %ecx +pdt_fill: +movl %eax, (%edi) # Setup PDPT location +add $8, %edi # Goto next entry +add $0x1000, %eax # Next PT +loop pdt_fill +# Setup the 5 PT +mov $0x3000, %edi +mov $0x3, %ebx # First map to 0 +mov $2560, %ecx # 512*5 +pt_fill: +mov %ebx, (%edi) +add $8, %edi # Next entry +add $0x1000, %ebx # Next Page +loop pt_fill + +# ----- Switch to compatibility mode +# Set CR4.PAE +mov %cr4, %eax +bts $5, %eax +mov %eax, %cr4 +# Set EFER.LME +mov $0xC0000080, %ecx +rdmsr +bts $8, %eax +wrmsr +# Set CR0.PG +mov %cr0, %eax +bts $31, %eax +mov %eax, %cr0 + +# Now we are in Compatibility mode +# Now we need to set CS.L=1 (setting up a 64 bit GDT) +lgdt (gdtr) +jmp $0x08, $new_cs +new_cs: + +# Run boucane +jmp boucane + +# GDT +gdt64: + gdt64_null: + .long 0 + .long 0 + gdt64_cs: + .long 0 + .byte 0 + .byte 0b10011100 + .byte 0b00100000 + .byte 0 + gdt64_ds: + .long 0 + .byte 0 + .byte 0b10000000 + .word 0 +gdtr: + .word . - gdt64 - 1 + .quad gdt64
\ No newline at end of file diff --git a/src/boucane.c b/src/boucane.c new file mode 100644 index 0000000..1b80891 --- /dev/null +++ b/src/boucane.c @@ -0,0 +1,9 @@ +#include "libc/stdio.h" + + + +void boucane(){ + clear(); + print("Boucane is booting..."); + while(1); +}
\ 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 diff --git a/src/drivers/framebuffer.c b/src/drivers/framebuffer.c new file mode 100644 index 0000000..110dc73 --- /dev/null +++ b/src/drivers/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/drivers/framebuffer.h b/src/drivers/framebuffer.h new file mode 100644 index 0000000..d265015 --- /dev/null +++ b/src/drivers/framebuffer.h @@ -0,0 +1,35 @@ +#ifndef FRAMEBUFFER_H +#define FRAMEBUFFER_H + +#include "core/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/libc/math.c b/src/libc/math.c new file mode 100644 index 0000000..80b1d3a --- /dev/null +++ b/src/libc/math.c @@ -0,0 +1,32 @@ +#include "math.h" + +int pow(int x,int n){ + if(n<0) + return -1; + else if(n==0) + return 1; + else if(n==1) + return x; + int ret=x; + for(int i=0;i<(n-1);i++) + ret*=x; + return ret; +} + +int max(int x,int y){ + if(x>y) + return x; + return y; +} + +int min(int x,int y){ + if(x<y) + return x; + return y; +} + +int abs(int x){ + if(x<0) + return -x; + return x; +}
\ No newline at end of file diff --git a/src/libc/math.h b/src/libc/math.h new file mode 100644 index 0000000..4cc37a9 --- /dev/null +++ b/src/libc/math.h @@ -0,0 +1,9 @@ +#ifndef MATH_H +#define MATH_H + +int pow(int x,int n); +int max(int x,int y); +int min(int x,int y); +int abs(int x); + +#endif
\ No newline at end of file diff --git a/src/libc/stdio.c b/src/libc/stdio.c new file mode 100644 index 0000000..6e0063b --- /dev/null +++ b/src/libc/stdio.c @@ -0,0 +1,25 @@ +#include "stdio.h" +#include "string.h" + +extern VIDEO_STATE VS; + +void print(char *str){ + int i=0; + while(str[i]!='\0'){ + putchar(str[i]); + i++; + } +} + +void printc(char* str,VIDEO_COLORS c){ + VIDEO_COLORS backup=VS.fg; + VS.fg=c; + print(str); + VS.fg=backup; +} + +void printi(int i){ + char str[12]; + itoa(i,str); + print(str); +}
\ No newline at end of file diff --git a/src/libc/stdio.h b/src/libc/stdio.h new file mode 100644 index 0000000..d4bd6b6 --- /dev/null +++ b/src/libc/stdio.h @@ -0,0 +1,21 @@ +#ifndef STDIO_H +#define STDIO_H + +#include "drivers/framebuffer.h" + +/** + * Print a char* in the framebuffer + */ +void print(char*); + +/** + * Print a char in the framebuffer + */ +void printc(char*,VIDEO_COLORS c); + +/** + * Print an integer using itoa() + */ +void printi(int i); + +#endif
\ No newline at end of file diff --git a/src/libc/string.c b/src/libc/string.c new file mode 100644 index 0000000..93a9e63 --- /dev/null +++ b/src/libc/string.c @@ -0,0 +1,29 @@ +#include "string.h" +#include "math.h" + +void itoa(int i, char *a){ + // Check if lower than 0 + char neg=0; + if(i<0){ + neg=1; + i=-i; + a[0]='-'; + } + + // Count number of digits + int len=1; + while(i/pow(10,len)>=1) + { + len++; + } + + // Build string + int max_pow=len-1; + for(int j=0;j<=max_pow;j++){ + int cur_pow=pow(10,max_pow-j); + char digit=i/cur_pow; + a[j+neg]='0'+digit; + i=i-digit*cur_pow; // Remove first digits (most significant) + } + a[len+neg]='\0'; +}
\ No newline at end of file diff --git a/src/libc/string.h b/src/libc/string.h new file mode 100644 index 0000000..c3d3614 --- /dev/null +++ b/src/libc/string.h @@ -0,0 +1,9 @@ +#ifndef STRING_H +#define STRING_H + +/** + * Convert int to char + */ +void itoa(int i, char *a); + +#endif
\ No newline at end of file diff --git a/src/linker.ld b/src/linker.ld new file mode 100644 index 0000000..ed8fc5d --- /dev/null +++ b/src/linker.ld @@ -0,0 +1,29 @@ +ENTRY(_start) +OUTPUT_FORMAT(elf64-x86-64) + +SECTIONS { + + . = 1M; + + .text : ALIGN(4) + { + *(.multiboot) + *(.text) + } + .rodata : ALIGN(4) + { + *(.rodata) + } + .data : ALIGN(4) + { + *(.data) + } + .bss : ALIGN(4) + { + _bss_start = .; + *(.bss); + _bss_end = .; + *(COMMON); + } + +}
\ No newline at end of file |
