Init sources

This commit is contained in:
Loic Guegan 2021-04-19 19:06:28 +02:00
parent f5146ca9c9
commit ca1e725b0d
17 changed files with 678 additions and 0 deletions

29
src/Makefile Normal file
View file

@ -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

128
src/boot/boot.S Normal file
View file

@ -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

9
src/boucane.c Normal file
View file

@ -0,0 +1,9 @@
#include "libc/stdio.h"
void boucane(){
clear();
print("Boucane is booting...");
while(1);
}

9
src/core/types.h Normal file
View file

@ -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

58
src/drivers/framebuffer.c Normal file
View file

@ -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';
}
}

35
src/drivers/framebuffer.h Normal file
View file

@ -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

32
src/libc/math.c Normal file
View file

@ -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;
}

9
src/libc/math.h Normal file
View file

@ -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

25
src/libc/stdio.c Normal file
View file

@ -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);
}

21
src/libc/stdio.h Normal file
View file

@ -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

29
src/libc/string.c Normal file
View file

@ -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';
}

9
src/libc/string.h Normal file
View file

@ -0,0 +1,9 @@
#ifndef STRING_H
#define STRING_H
/**
* Convert int to char
*/
void itoa(int i, char *a);
#endif

29
src/linker.ld Normal file
View file

@ -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);
}
}