Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
qemu-system-i386: Trying to execute code outside RAM or ROM at 0x6a006afa
This usually means one of the following happened:
(1) You told QEMU to execute a kernel for the wrong machine type, and it crashed on startup (eg trying to run a raspberry pi kernel on a versatilepb QEMU machine)
(2) You didn't give QEMU a kernel or BIOS filename at all, and QEMU executed a ROM full of no-op instructions until it fell off the end
(3) Your guest kernel has a bug and crashed by jumping off into nowhere
This is almost always one of the first two, so check your command line and that you are using the right type of kernel for this machine.
If you think option (3) is likely then you can try debugging your guest with the -d debug options; in particular -d guest_errors will cause the log to include a dump of the guest register state at this point.
Execution cannot continue; stopping here.
make: *** [makefile:26: run] Error 1
The main problem is that you are not using a cross compiler and your native compiler is producing position independent code that is relying on a global offset table. You tell the linker to ignore the problems, but that just hides the problem. Your IDT will not be referenced properly in memory as a result and things will die a horrible death when STI is issued. I am assuming before you call STI that you also call isr_install(). I highly recommend you use a cross compiler, but if you are intent on using your native compiler get rid of hiding the errors with the linker and compile with -fno-PIE and link (with ld) using -no-pie. This will compile and link as a position independent executable. Your makefile could look like this:
C_SOURCES = $(wildcard kernel.c lib/*.c lib/Drivers/*.c lib/CPU/*.c)
HEADERS = $(wildcard lib/*.h lib/Drivers/*.h lib/CPU/*.h)
# Nice syntax for file extension replacement
OBJ = ${C_SOURCES:.c=.o lib/CPU/interrupt.o}
# Change this if your cross-compiler is somewhere else
CC = /usr/bin/gcc
GDB = /usr/bin/gdb
# -g: Use debugging symbols in gcc
CFLAGS = -g -m32 -Ilib/ -fno-PIE
# First rule is run by default
Ranedeer.bin: boot/bootsect.bin kernel.bin
cat $^ > Ranedeer.bin
# '--oformat binary' deletes all symbols as a collateral, so we don't need
# to 'strip' them manually on this case
kernel.bin: boot/kernel_entry.o ${OBJ}
ld -no-pie -melf_i386 -o $@ -Ttext 0x1000 $^ --oformat binary
# Used for debugging purposes
kernel.elf: boot/kernel_entry.o ${OBJ}
ld -no-pie -melf_i386 -o $@ -Ttext 0x1000 $^
run: Ranedeer.bin
qemu-system-i386 -fda Ranedeer.bin
# Open the connection to qemu and load our kernel-object file with symbols
debug: Ranedeer.bin kernel.elf
qemu-system-i386 -s -fda Ranedeer.bin &
${GDB} -ex "target remote localhost:1234" -ex "symbol-file kernel.elf"
# Generic rules for wildcards
# To make an object, always compile from its .c
%.o: %.c ${HEADERS}
${CC} ${CFLAGS} -ffreestanding -c $< -o $@
%.o: %.asm
nasm $< -f elf -o $@
%.bin: %.asm
nasm $< -f bin -o $@
clean:
rm -rf *.bin *.dis *.o Ranedeer.bin *.elf
rm -rf *.o lib/*.o lib/Drivers/*.o Boot/*.o Boot/*.bin lib/CPU/*.o
It should be noted that when running QEMU for debugging you did: qemu-system-i386 -s -fda Ranedeer &.I think it should be qemu-system-i386 -s -fda Ranedeer.bin & given that Ranedeer doesn't include the bootloader. I made that change to your makefile above as well.