I'm programming my kernel (32 bits x86) , and I am cursed with a problem I can't see how to solve.
It's the first time I am confronted with such an issue , usually , I program in user space , so , here it is :
This is my kernel entry function :
void _start(){ const char* welcome = "HEYYY IT'S A MEEEE , MAAARIOOO! " ; init_video(); clear_screen() ; video_write((char*) welcome , 0x0E , false) ; init_idt(); while(1) ; }
And the result :
the thing works.
If I check the section .rodata :
Contents of section .rodata:2000 30313233 34353637 38394142 43444546 0123456789ABCDEF2010 08000000 48455959 59204954 27532041 ....HEYYY IT'S A2020 204d4545 4545202c 204d4141 4152494f MEEEE , MAAARIO2030 4f4f2120 0000000a 00202000 20202020 OO! ..... . 2040 20002000
You can see that our "welcome" variable has been stored in 0x2014.
But... If I do this :
int stuff(long long s , long long a , long long b);void _start(){ const char* welcome = "HEYYY IT'S A MEEEE , MAAARIOOO! " ; init_video(); clear_screen() ; video_write((char*) welcome , 0x0E , false) ; init_idt(); while(1) ; } int stuff (long long s , long long b , long long c) { return 0 ; }
Our Italian plumber disappeared :
Our "welcome" variable is now stored at 0x3014 , in the .rodata section :
3000 30313233 34353637 38394142 43444546 0123456789ABCDEF 3010 08000000 48455959 59204954 27532041 ....HEYYY IT'S A 3020 204d4545 4545202c 204d4141 4152494f MEEEE , MAAARIO 3030 4f4f2120 0000000a 00202000 20202020 OO! ..... . 3040 20002000 . .
Now , for the spooky part :
There's nothing at 0x3014 , when I run the program.If I run GDB , and print "welcome" , I get this :
(gdb) print /x welcome$1 = 0x3014(gdb) print welcome$2 = 0x3014 ""
This happens when I add a function with a certain number of arguments, even without using it.So , if I have to guess (correct me if I'm wrong) , either this is a stack issue, or this is a compilation/linking issue ?
Is it maybe due to the fact that I'm not using a cross-compiler ?
Here's the relevant part of the Makefile for the compilation and linking:
EXEC = SaharaOSCC = gccCFLAGS = -fno-PIC -mno-red-zone -fno-stack-protector -std=c11 -m32 -g -ffreestanding -pedantic -WallBOOTLOADER_DIR = ./bootloaderBOOTLOADER = $(BOOTLOADER_DIR)/bootloader.binASM_DIR = ./kernel/asmKERNEL_ENTRY = $(BOOTLOADER_DIR)/kernel_entry/kernel_entry.oKERNEL_ENTRY_FILE = $(BOOTLOADER_DIR)/kernel_entry/kernel_entry.asmKERNEL = ./kernel.binKDEBUG = ./symbol-debug-kernelKERNEL_DIR = ./kernelKERNEL_SRC_DIR = $(KERNEL_DIR)/srcKERNEL_INC_DIR = $(KERNEL_DIR)/includesKERNEL_OBJ_DIR = $(KERNEL_DIR)/objDRIVERS_DIR = ./driversDRIVERS_OBJ_DIR = $(DRIVERS_DIR)/objASM_SRC = $(wildcard $(ASM_DIR)/*.asm)BOOTLOADER_SRC = $(wildcard $(BOOTLOADER_DIR)/assembly/*.asm)KERNEL_OBJ = $(wildcard $(KERNEL_OBJ)/*.o)KERNEL_SRC = $(wildcard $(KERNEL_SRC_DIR)/*.c)KERNEL_INC = $(wildcard $(KERNEL_INC_DIR)/*.h)DRIVERS_SRC = $(wildcard $(DRIVERS_DIR)/*/src/*.c)DRIVERS_INC = $(wildcard $(DRIVERS_DIR)/*/includes/*.h)OBJ_K = $(KERNEL_SRC:.c=.o)OBJ_D = $(DRIVERS_SRC:.c=.o)OBJ_ASM_K = $(ASM_SRC:.asm=.o)all : run$(EXEC) : assembledebug : $(EXEC) $(KDEBUG) qemu-system-i386 -S -gdb tcp::9000 $<run : $(EXEC) qemu-system-i386 -d guest_errors $<disassemble : $(KERNEL) ndisasm -b 32 $? | catassemble : $(BOOTLOADER) $(KERNEL) cat $^ > $(EXEC) qemu-img resize $(EXEC) +100KOBJDUMP : $(KERNEL_ENTRY) $(OBJ_D) $(OBJ_K) $(OBJ_ASM_K) ld -melf_i386 -o $@ -Ttext 0x1000 $^ #Kernel build and drivers$(KERNEL) : $(KERNEL_ENTRY) $(OBJ_D) $(OBJ_K) $(OBJ_ASM_K) ld -melf_i386 -o $@ -Ttext 0x1000 $^ --oformat binary$(KDEBUG) : $(KERNEL_ENTRY) $(OBJ_D) $(OBJ_K) $(OBJ_ASM_K) ld -melf_i386 -o $@ -Ttext 0x1000 $^ %.o : %.c $(KERNEL_INC) $(DRIVERS_INC) $(CC) $(CFLAGS) -c $< -o $@%.o : %.asm nasm -f elf32 -F dwarf -g $< -o $@#Bootloader buildKERNEL_ENTRY : $(KERNEL_ENTRY)BOOTLOADER : $(BOOTLOADER)$(KERNEL_ENTRY): nasm -f elf32 -F dwarf -g $(KERNEL_ENTRY_FILE) -o $@ $(BOOTLOADER) : nasm $(BOOTLOADER_DIR)/assembly/boot.asm -i $(BOOTLOADER_DIR)/assembly -f bin -o $@