Blind-sided by multi-boot/PE problems...
Posted: Mon Feb 01, 2010 11:55 pm
Perhaps I celebrated too soon about my PE kernel and being "multiboot compliant".
I thought everything was ok, and as far as I could originally tell it was. Grub booted the kernel with ease, and my kernel obviously had control of the system. So, I played around a bit and got it to clear the screen, change colors, print a couple chars to the screen, etc, and figured it was time to move on to some real implementations of the groundwork. Wrong. I soon discovered my basic I/O implementation was giving horrible results. If, let's say, I tried to print char* teststring = "Hello from the kernel!"; I would get some random junk like:
sdf9087=!@^y654%$P .... (there was a LOT more, covering several lines, lol)
So I wonder what the heck is wrong. I check and recheck the implementations, and can find no problems with the code. I even copy and paste them into a Win32 console application to try out, and it worked fine; as if I was using a regular standard library. THEN I become aware that only local variables actually exist at runtime. If I have a global variable and try to print it via VGA, Virtual PC again prints random junk. Mind you, at the local level inside a function printing a single character at a time works perfectly somehow. On Sun's Virtual Box, nothing is printed at all if I try to print a global char*/string. It's like they disappear into an unknown (void *).
Then I got to thinking that maybe the way I've implemented the multi-boot code was bad, and causing data/resources to get chopped off during loading. So, I went to the only two online tutorials for this that I know exist:
http://ksrenevasan.blogspot.com/
http://forum.osdev.org/viewtopic.php?f=1&t=21260
Following those and all their settings to the letter, I'm still plagued with the same problem. Random junk is written to the video buffer when you try to print a string, and global variables (anything outside the functions) doesn't exist at all -- and may result in more random junk. For ksrenevasan's PE/multi-boot tutorial, I discovered that changing:
...Eliminates the issue with being totally unable to print an uncorrupted string. However, the same problem is still there in respect to only local variables working.
I'm using Grub 0.97 and the stage2_eltorito loader, if it is of any significance. I'm going to be trying to solve this, and thoroughly (re-)reading all of the information available for both the PE format and multi-boot specifications. But I'm hoping someone at least knows what could be the issue with this or slap a bit of sense into me. My guess is that there is just something obviously wrong with how my kernel gets loaded, and it's likely within that multiboot header somehow (it suggests to me that data/resources are getting chopped?). Alternatively, the way I've rigged VS to output the kernel could be flawed, but I really doubt this. The weird thing is the tutorial writers who I copied for validation suggest it works fine, and I doubt they would have posted it if it didn't. And yes, I've more than tripled check during my tests to be sure I set everything up like them (to validate whether or not their code would work). I'm just a bit baffled at this point.
Sorry for long question, but I wanted to be as clear as possible about my problem. Also, I kindly request that any suggestions to switch toolsets/formats/etc be withheld. The project is 100% 'academic' at this time, and the whole point (and requirement) is to use PE format and work in VS.
I thought everything was ok, and as far as I could originally tell it was. Grub booted the kernel with ease, and my kernel obviously had control of the system. So, I played around a bit and got it to clear the screen, change colors, print a couple chars to the screen, etc, and figured it was time to move on to some real implementations of the groundwork. Wrong. I soon discovered my basic I/O implementation was giving horrible results. If, let's say, I tried to print char* teststring = "Hello from the kernel!"; I would get some random junk like:
sdf9087=!@^y654%$P .... (there was a LOT more, covering several lines, lol)
So I wonder what the heck is wrong. I check and recheck the implementations, and can find no problems with the code. I even copy and paste them into a Win32 console application to try out, and it worked fine; as if I was using a regular standard library. THEN I become aware that only local variables actually exist at runtime. If I have a global variable and try to print it via VGA, Virtual PC again prints random junk. Mind you, at the local level inside a function printing a single character at a time works perfectly somehow. On Sun's Virtual Box, nothing is printed at all if I try to print a global char*/string. It's like they disappear into an unknown (void *).
Then I got to thinking that maybe the way I've implemented the multi-boot code was bad, and causing data/resources to get chopped off during loading. So, I went to the only two online tutorials for this that I know exist:
http://ksrenevasan.blogspot.com/
http://forum.osdev.org/viewtopic.php?f=1&t=21260
Following those and all their settings to the letter, I'm still plagued with the same problem. Random junk is written to the video buffer when you try to print a string, and global variables (anything outside the functions) doesn't exist at all -- and may result in more random junk. For ksrenevasan's PE/multi-boot tutorial, I discovered that changing:
Code: Select all
...
dd(0x0010200F) ; load_end_addr
dd(0x0010200F) ; bss_end_addr
...
to:
dd(0x001020FF) ; load_end_addr
dd(0x001020FF) ; bss_end_addr
I'm using Grub 0.97 and the stage2_eltorito loader, if it is of any significance. I'm going to be trying to solve this, and thoroughly (re-)reading all of the information available for both the PE format and multi-boot specifications. But I'm hoping someone at least knows what could be the issue with this or slap a bit of sense into me. My guess is that there is just something obviously wrong with how my kernel gets loaded, and it's likely within that multiboot header somehow (it suggests to me that data/resources are getting chopped?). Alternatively, the way I've rigged VS to output the kernel could be flawed, but I really doubt this. The weird thing is the tutorial writers who I copied for validation suggest it works fine, and I doubt they would have posted it if it didn't. And yes, I've more than tripled check during my tests to be sure I set everything up like them (to validate whether or not their code would work). I'm just a bit baffled at this point.
Sorry for long question, but I wanted to be as clear as possible about my problem. Also, I kindly request that any suggestions to switch toolsets/formats/etc be withheld. The project is 100% 'academic' at this time, and the whole point (and requirement) is to use PE format and work in VS.