Hello World!

This commit is contained in:
vanten-s 2025-11-12 16:16:50 +01:00
parent e75c7b9f69
commit 837996f72b
Signed by: vanten-s
GPG key ID: DE3060396884D3F2
7 changed files with 175 additions and 0 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
.envrc
.ccls-cache

View file

@ -0,0 +1,82 @@
TARGET=i686
ARCHDIR=arch/$(TARGET)/
SOURCEDIR=src/
BUILDDIR=build/
INCLUDEDIR=$(SOURCEDIR)include/
CFLAGS?=
ASFLAGS?=
# Define flags for C files
CFLAGS:=\
-O2 \
-std=gnu99 \
-ffreestanding \
-Wall -Wextra \
-Wno-incompatible-pointer-types\
-I$(INCLUDEDIR) \
$(CFLAGS)
# Define flags for assembly files
ASFLAGS:=\
-I$(SOURCEIDR)$(INCLUDEDIR) \
-I$(SOURCEDIR)$(ARCHDIR) \
$(ASFLAGS)
LINKERFLAGS:=\
-ffreestanding \
-O2 \
-nostdlib \
-lgcc
LIB_OBJS=\
$(BUILDDIR)$(ARCHDIR)bootstrap.o
KERNEL_OBJS=\
$(BUILDDIR)kernel/kernel.o
OBJS=$(LIB_OBJS) $(KERNEL_OBJS)
LINKER_PATH=$(SOURCEDIR)$(ARCHDIR)linker.ld
.PHONY: all clean snowstorm.iso debug
.SUFFIXES: .c .o .s
$(BUILDDIR)%.o : $(SOURCEDIR)%.c
i686-elf-gcc -c $< -o $@ $(CFLAGS)
$(BUILDDIR)%.o : $(SOURCEDIR)%.s
i686-elf-as $< -o $@ $(ASFLAGS)
all: snowstorm.iso
# Take the kernel file and make a bootable ISO through GRUB
snowstorm.iso: snowstorm.kernel
cp build/snowstorm.kernel build/isodir/boot/snowstorm.kernel
grub-mkrescue -o build/snowstorm.iso build/isodir
# link all object files together
snowstorm.kernel: $(OBJS)
i686-elf-gcc -T $(LINKER_PATH) -o build/snowstorm.kernel $(OBJS) $(LINKERFLAGS)
grub-file --is-x86-multiboot build/snowstorm.kernel
debug: CFLAGS += -g -O0
debug: ASFLAGS += -g
debug: all
clean:
rm -f $(OBJS)
rm -f build/snowstorm.kernel
rm -f build/snowstorm.iso
rm -f build/isodir/boot/snowstorm.kernel
run: all
qemu-system-i386 -d int -no-reboot -kernel build/snowstorm.kernel
run-debug: debug
qemu-system-i386 -d int -no-reboot -S -gdb tcp::9000 build/snowstorm.iso
run-debug-kernel: debug
qemu-system-i386 -d int -no-reboot -S -gdb tcp::9000 -kernel build/snowstorm.kernel

View file

@ -0,0 +1,3 @@
menuentry "snowstorm" {
multiboot /boot/snowstorm.kernel
}

View file

@ -1 +1,42 @@
# Declare constants for the multiboot header.
.set ALIGN, 1<<0 # align loaded modules on page boundaries
.set MEMINFO, 1<<1 # provide memory map
.set FLAGS, ALIGN | MEMINFO # this is the Multiboot 'flag' field
.set MAGIC, 0x1BADB002 # 'magic number' lets bootloader find the header
.set CHECKSUM, -(MAGIC + FLAGS) # checksum of above, to prove we are multiboot
# Declare a multiboot header that marks the program as a kernel.
.section .multiboot.data, "aw"
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM
.section .bss, "aw", @nobits
.align 16
stack_bottom:
.skip (1 << 16) # 64 KiB
stack_top:
.global boot_page_directory
.align 4096
boot_page_directory:
.skip 4096
boot_page_table1:
.skip 4096
.section .multiboot.text, "a"
.global _start
.type _start, @function
.extern kernel_main
_start:
mov $stack_top, %esp # The stack grows downwards so it starts at the top
# (We kind of need to have a stack to do anything)
call kernel_main
# Infinite loop if kernel_main returns, (which it shouldn't do)
cli
1: hlt
jmp 1b

29
src/arch/i686/linker.ld Normal file
View file

@ -0,0 +1,29 @@
ENTRY(_start)
SECTIONS
{
/* Leave 1 Megabyte for GRUB */
. = 1M;
.multiboot.data :
{
*(.multiboot.data) /* Take the data from label .multiboot.data from all files and put it in our output file */
}
.multiboot.text :
{
*(.multiboot.text) /* Take the data from label .multiboot.data from all files and put it in our output file */
}
.bss :
{
*(.bss) /* Take the data from label .multiboot.data from all files and put it in our output file */
}
.data :
{
*(.data) /* Take the data from label .multiboot.data from all files and put it in our output file */
}
}

7
src/include/strlib.h Normal file
View file

@ -0,0 +1,7 @@
static inline int strlen(char *str) {
int len = 0;
while (str[len] != '\0') {
len += 1;
}
return len;
}

View file

@ -0,0 +1,12 @@
#include <stdbool.h>
#include <stdint.h>
#include "strlib.h"
uint16_t* VGA_screen = (uint16_t*)0xB8000;
char* text = "Hello World!";
void kernel_main() {
for (int i = 0; i < strlen(text); i++) {
VGA_screen[i] = text[i] | 0x0F00; // 0x0F00: two bytes color, two bytes to combine it with text
}
}