Removing infinite loop in driver breaks code at jmp to protected mode
Posted: Fri Apr 04, 2025 12:39 pm
Hey guys, I hope everyone is doing well! Like many others here, I'm working on my own OS, and I've encountered a problem that I'm having a hard time diagnosing/solving, and so I'm looking for help.
In the current commit (ce5961e) you can see that my OS is triple faulting, however in a previous commit (22b13c5) you see the expected messages being printed correctly to the screen. The difference between these commits is that I removed the infinite while loop from the beginning of FdcInit, a init function of a C driver for the floppy disk that I call to load the kernel into RAM. (The attached image is of the "working" commit)
Here is my GitHub repo: https://github.com/viniciius14/os
Now there are multiple possible error sources, I imagine, and these are some of the ones that I think aren't because I've been messing around with these already after reading some posts from this forum:
I imagine most of you don't want to run a random guy's code on your pc so I've temporarily included a debug folder in the repo with some debug info files and some binaries. (By the way, QEMU.log is 80-something MB in size, so it'll take a little to load).
In case you do want to run this code for yourself, head on to misc/config.mk and edit the first line, which has the absolute path hardcoded there (this project is meant to be run in a docker container, but that's not working on my machine atm due to a different issue), and you can also see in that file the tools used for compilation.
To do my test runs, I usually do a
I appreciate any help I can get, and if you spot something dumb/inefficient or otherwise not very clever, feel free to leave a remark about it as I'm doing this project for the sake of learning.
In the current commit (ce5961e) you can see that my OS is triple faulting, however in a previous commit (22b13c5) you see the expected messages being printed correctly to the screen. The difference between these commits is that I removed the infinite while loop from the beginning of FdcInit, a init function of a C driver for the floppy disk that I call to load the kernel into RAM. (The attached image is of the "working" commit)
Here is my GitHub repo: https://github.com/viniciius14/os
Now there are multiple possible error sources, I imagine, and these are some of the ones that I think aren't because I've been messing around with these already after reading some posts from this forum:
- Not enough sectors are being loaded - the FAT12 version of this bootloader "dynamically" reads sectors from the data section of the floppy disk depending on the size of the stage2, meaning that this shouldn't be an issue.
- Setting up the stack so that C code doesn't return into oblivion - can be seen in stage2_32.S
- Ensuring stage2_16 gets placed at 0x7E00 by the linker - added stage2_16.text section to the code and linker.
- stage2_16 is being compiled with 32 bit instructions - now this one is a bit trickier to verify, but seeing the disassembly of stage2_16, the instructions being used had EAX and other 32 bit registers in the disassembly. Even though the file has [bits 16] at the beginning, it is being compiled with the -f elf32 flag due to the way the Makefile is set up. So I created a branch and you can see that I compile directly to a binary file and attach it later into the code. This didn't give many fruitful results, and I prefer the way my build system is right now without the exception (stage2_16.S) and the workarounds in the Makefile. Additionally, some new bugs showed up, like the beginning of messages was not being printed for some reason, so I dropped it for now. Here's that branch: https://github.com/viniciius14/os/tree/stage2_16_bin
I imagine most of you don't want to run a random guy's code on your pc so I've temporarily included a debug folder in the repo with some debug info files and some binaries. (By the way, QEMU.log is 80-something MB in size, so it'll take a little to load).
In case you do want to run this code for yourself, head on to misc/config.mk and edit the first line, which has the absolute path hardcoded there (this project is meant to be run in a docker container, but that's not working on my machine atm due to a different issue), and you can also see in that file the tools used for compilation.
To do my test runs, I usually do a
Code: Select all
make clean && make debug && make run