I've just created a basic operating system that prints text onto the screen, based on this youtube tutorial. The method used in the tutorial is fairly convoluted (I assume) because it uses C++ instead of C. Upon selecting the OS in the Grub menu, the menu closes but the screen stays purple. No text is printed to the screen. I've double checked that my code matches the tutorial but it still doesn't work the same way as it does on his machine.
Relevant Hardware:
CPU: Ryzen 5 2600
MOBO: Asrock B450-M HDV
The files are fairly small, included below.
kernel.cpp:
void printf(char* str) {
unsigned short* VideoMemory = (unsigned short*)0xb8000;
for(int i = 0; str[i] != '\0'; ++i) {
VideoMemory[i] = (VideoMemory[i] & 0xFF00) | str[i];
}
}
extern "C" void kernelMain(void* multiboot_structure, unsigned int magicnumber) {
printf("Hello World!");
while(1);
}
loader.s: (since C++ expects the stack pointer to be set before running)
.set MAGIC, 0x1badb002
.set FLAGS, (1<<0 | 1<<1)
.set CHECKSUM, -(MAGIC + FLAGS)
.section .multiboot
.long MAGIC
.long FLAGS
.long CHECKSUM
.section .text
.extern kernelMain
.global loader
loader:
mov $kernel_stack, %esp
push %eax
push %ebx
call kernelMain
_stop:
cli
hlt
jmp _stop
.section .bss
.space 2*1024*1024; # 2 MB
kernel_stack:
linker.ld:
ENTRY(loader)
OUTPUT_FORMAT(elf32-i386)
OUTPUT_ARCH(i386:i386)
SECTIONS {
. = 0x0100000;
.text : {
*(.multiboot)
*(.text*)
*(.rodata)
}
.data : {
start_ctors = .;
KEEP(*(.init_array));
KEEP(*(SORT_BY_INIT_PRIORITY( .init_array.* )))
end_ctors = .;
*(.data)
}
.bss : {
*(.bss)
}
/DISCARD/ : {
*(.fini_array*)
*(.comment)
}
}
Makefile:
GPPPARAMS = -m32 -fno-use-cxa-atexit -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore
ASPARAMS = --32
LDPARAMS = -melf_i386
objects = loader.o kernel.o
%.o: %.cpp
g++ $(GPPPARAMS) -o $@ -c $<
%.o: %.s
as $(ASPARAMS) -o $@ $<
mykernel.bin: linker.ld $(objects)
ld $(LDPARAMS) -T $< -o $@ $(objects)
install: mykernel.bin
sudo cp $< /boot/mykernel.bin