From ca1e725b0dc9b10997897dd2ac6d44028601d9bb Mon Sep 17 00:00:00 2001 From: Loic Guegan Date: Mon, 19 Apr 2021 19:06:28 +0200 Subject: Init sources --- src/Makefile | 29 +++++++++++ src/boot/boot.S | 128 ++++++++++++++++++++++++++++++++++++++++++++++ src/boucane.c | 9 ++++ src/core/types.h | 9 ++++ src/drivers/framebuffer.c | 58 +++++++++++++++++++++ src/drivers/framebuffer.h | 35 +++++++++++++ src/libc/math.c | 32 ++++++++++++ src/libc/math.h | 9 ++++ src/libc/stdio.c | 25 +++++++++ src/libc/stdio.h | 21 ++++++++ src/libc/string.c | 29 +++++++++++ src/libc/string.h | 9 ++++ src/linker.ld | 29 +++++++++++ 13 files changed, 422 insertions(+) create mode 100644 src/Makefile create mode 100644 src/boot/boot.S create mode 100644 src/boucane.c create mode 100644 src/core/types.h create mode 100644 src/drivers/framebuffer.c create mode 100644 src/drivers/framebuffer.h create mode 100644 src/libc/math.c create mode 100644 src/libc/math.h create mode 100644 src/libc/stdio.c create mode 100644 src/libc/stdio.h create mode 100644 src/libc/string.c create mode 100644 src/libc/string.h create mode 100644 src/linker.ld (limited to 'src') 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;iy) + return x; + return y; +} + +int min(int x,int y){ + if(x=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 -- cgit v1.2.3