From 306cbbf842f7eeb624506ae22a68c7f18bd0cd21 Mon Sep 17 00:00:00 2001 From: rick Date: Tue, 12 Sep 2023 23:35:30 +0200 Subject: [PATCH] add firsts files --- .gitignore | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 40 ++++++++++++++++++++++++++ README.txt | 5 ++++ framebuffer.c | 17 +++++++++++ framebuffer.h | 39 +++++++++++++++++++++++++ io.h | 6 ++++ io.s | 11 +++++++ kmain.c | 33 +++++++++++++++++++++ link.ld | 26 +++++++++++++++++ loader.s | 35 +++++++++++++++++++++++ 10 files changed, 291 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.txt create mode 100644 framebuffer.c create mode 100644 framebuffer.h create mode 100644 io.h create mode 100644 io.s create mode 100644 kmain.c create mode 100644 link.ld create mode 100644 loader.s diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..644583d --- /dev/null +++ b/.gitignore @@ -0,0 +1,79 @@ +# Created by https://www.toptal.com/developers/gitignore/api/c,vim +# Edit at https://www.toptal.com/developers/gitignore?templates=c,vim + +### C ### +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +### Vim ### +# Swap +[._]*.s[a-v][a-z] +!*.svg # comment out if you don't need vector files +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim +Sessionx.vim + +# Temporary +.netrwhist +*~ +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ + +# End of https://www.toptal.com/developers/gitignore/api/c,vim diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a15af4e --- /dev/null +++ b/Makefile @@ -0,0 +1,40 @@ +OBJECTS = loader.o framebuffer.o io.o kmain.o + +CC = gcc +CFLAGS = -m32 -nostdlib -nostdinc -fno-builtin -fno-stack-protector \ + -nostartfiles -nodefaultlibs -c #-Wall -Wextra -Werror -c + +LDFLAGS = -T link.ld -melf_i386 + +AS = nasm +ASFLAGS = -f elf + +all: kernel.elf + +kernel.elf: $(OBJECTS) + ld $(LDFLAGS) $^ -o $@ + +%.o: %.c + $(CC) $(CFLAGS) $< -o $@ + +%.o: %.s + $(AS) $(ASFLAGS) $< -o $@ + +os.iso: kernel.elf + cp kernel.elf iso/boot/kernel.elf + mkisofs -R \ + -b boot/grub/stage2_eltorito \ + -no-emul-boot \ + -boot-load-size 4 \ + -A os \ + -input-charset UTF-8 \ + -quiet \ + -boot-info-table \ + -o os.iso \ + iso + +run: os.iso + qemu-system-i386 -cdrom $< -serial stdio #-d cpu + +clean: + rm *.o kernel.elf os.iso diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..4c0e03e --- /dev/null +++ b/README.txt @@ -0,0 +1,5 @@ +Écriture d'un noyau de test basé sur The little book about OS development +(2015/01/19 - fe83e27dab3c39930354d2dea83f6d4ee2928212) + +Suivez les instructions pour pouvoir compiler l'image avec Grub : +https://littleosbook.github.io/#obtaining-grub diff --git a/framebuffer.c b/framebuffer.c new file mode 100644 index 0000000..bedd7c7 --- /dev/null +++ b/framebuffer.c @@ -0,0 +1,17 @@ +#include "io.h" +#include "framebuffer.h" + +void fb_write_cell(unsigned int i, char c, unsigned char fg, unsigned char bg) +{ + char *fb = (char*) 0xB8000; // adresse du framebuffer + *(fb + i) = c; + *(fb + i + 1) = (fg & 0x0F) | ((bg & 0x0F) << 4); // little endian ?? +} + +void fb_move_cursor(unsigned short pos) +{ + outb(FB_COMMAND_PORT, FB_HIGH_BYTE_COMMAND); + outb(FB_DATA_PORT, (pos >> 8) & 0x00FF); + outb(FB_COMMAND_PORT, FB_HIGH_BYTE_COMMAND); + outb(FB_DATA_PORT, pos & 0x00FF); +} diff --git a/framebuffer.h b/framebuffer.h new file mode 100644 index 0000000..fc29e8a --- /dev/null +++ b/framebuffer.h @@ -0,0 +1,39 @@ +/** @file framebuffer.h */ + +#ifndef FRAMEBUFFER_H +#define FRAMEBUFFER_H + +/** + * @def FB_COMMAND_PORT + * Le port pour pouvoir envoyer des instructions au curseur du framebuffer + */ +#define FB_COMMAND_PORT 0x3D4 +/** + * @def FB_DATA_PORT + * Le port pour pouvoir envoyer des instructions au curseur du framebuffer + */ +#define FB_DATA_PORT 0x3D5 + +#define FB_HIGH_BYTE_COMMAND 14 +#define FB_LOW_BYTE_COMMAND 15 + +#define FB_WHITE 0x0F +#define FB_BLACK 0x00 + +/** + * permet d'écrire dans un emplacement du framebuffer + * + * @param i l'emplacement où il faut écrire + * @param c le caractère + * @param fg la couleur du texte + * @param bg la couleur du fond du texte + */ +void fb_write_cell(unsigned int i, char c, unsigned char fg, unsigned char bg); + +/** + * permet de déplacer le curseur du framebuffer + * + * @param pos la position où déplacer le curseur + */ +void fb_move_cursor(unsigned short pos); +#endif diff --git a/io.h b/io.h new file mode 100644 index 0000000..8b3ea10 --- /dev/null +++ b/io.h @@ -0,0 +1,6 @@ +#ifndef IO_H +#define IO_H + +void outb(unsigned short port, unsigned char data); + +#endif diff --git a/io.s b/io.s new file mode 100644 index 0000000..8e7697e --- /dev/null +++ b/io.s @@ -0,0 +1,11 @@ +global outb + +; permet de communiquer avec des ports +; pile : [ esp + 8 ] la valeur à écrire +; [ esp + 4 ] le port +; [ esp ] l'adresse de retour +outb: + mov al, [esp + 8] + mov dx, [esp + 4] + out dx, al + ret diff --git a/kmain.c b/kmain.c new file mode 100644 index 0000000..0112afa --- /dev/null +++ b/kmain.c @@ -0,0 +1,33 @@ +#include "framebuffer.h" + +int write(char *buf, unsigned int len) +{ + int ret = 0; + int pos = 0; + fb_move_cursor(ret); + + while (ret < len) + { + fb_write_cell(pos, *(buf + ret), FB_WHITE, FB_BLACK); + ret++; + fb_move_cursor(ret); + + pos += 2; + } + + return ret; +} + +int strlen(char *buf) +{ + int ret = 0; + while (*(buf + ret) != '\0') ret++; + return ret; +} + +void kmain(void) +{ + char *str = "pouet pouet"; + int len = strlen(str); + write(str, len); +} diff --git a/link.ld b/link.ld new file mode 100644 index 0000000..b2af580 --- /dev/null +++ b/link.ld @@ -0,0 +1,26 @@ +ENTRY(loader) + +SECTIONS { + . = 0x00100000; + + .text ALIGN (0x1000) : + { + *(.text) + } + + .rodata ALIGN (0x1000) : + { + *(.rodata) + } + + .data ALIGN (0x1000) : + { + *(.data) + } + + .bss ALIGN (0x1000) : + { + *(COMMON) + *(.bss) + } +} diff --git a/loader.s b/loader.s new file mode 100644 index 0000000..f56eb50 --- /dev/null +++ b/loader.s @@ -0,0 +1,35 @@ +global loader ; symbole d'entrée pour le format ELF + +; valeurs pour l'entête de multiboot (https://www.gnu.org/software/grub/manual/multiboot/html_node/Header-magic-fields.html#Header-magic-fields) +MAGIC_NUMBER equ 0x1BADB002 ; obligatoire +FLAGS equ 0x0 ; configuration de multiboot +CHECKSUM equ -MAGIC_NUMBER ; cf. documentation + +KERNEL_STACK_SIZE equ 4096 + +section .bss +align 4 +kernel_stack: + resb KERNEL_STACK_SIZE + +section .text +align 4 + dd MAGIC_NUMBER + dd FLAGS + dd CHECKSUM + +loader: + ; écrite la lettre A dans le framebuffer + ; mov word [0xB8000], 0x0F41 + ; le registre esp contient le pointeur vers la stack + mov esp, kernel_stack + KERNEL_STACK_SIZE + extern kmain + call kmain + ;extern fb_write_cell + ;push dword 0x00 + ;push dword 0x0F + ;push dword 0x41 + ;call fb_write_cell + mov eax, 0xCAFEBABE +.loop: + jmp .loop