My FAT12 Bootsector FINALLY works :D
My FAT12 Bootsector FINALLY works :D
After two weeks of hair-tearing frusteration, Ive finally got my FAT12 Bootsector working precisely how I want it!
And the best part is, I finally understand the Assembler Im writing and learnt a great deal about Debugging under Bochs!
Its so... like, good feeling to be able to fix a problem after weeks of it making you want to scream!
Its just a standard FAT12 bootloader, but... Ive rewritten old Bootloader code so many times now, that most of this was written by me! Although, Ive referenced hundreds of other peoples bootloaders and articles in order to try and fix some bugs. But most of it I didnt have to change, YAY!.
The bootloader loads a file called K.BIN from the floppydrive, and will load it in all its entirity.
K.bin is the Second stage bootloader and Kernel all in one file.
Stage2 so far, has room for about 1kb of code.
at the 1kb point (offset 0x400) in the file, the Kernel code begins.
And, my sector loads the file to 0x0000F000.
so, F000 - F400 is Stage 2 code.
F400 - ???? is Kernel code.
What I should do, is make the Stage2 copy the Kernel code to 0x10000, then execute it there. 0x10000 just feels tidy .
So, for the rest of the night - Im going to be working on the Stage 2 Bootloader Code.
To setup Protected Mode, Video mode I want the Kernel to start in, Stack for the Kernel. GDT (Ring0 Data/Code, Ring3 Data/Code, Null...)
THEN! Finally, ATLAST! Ill be in C World! YAYYYYYYY
Ive included the sourcecode to the Stage1 FAT12 Bootloader, should anyone be interested.
Its hardly commented, so I appologize in advance.
~Zeii.
And the best part is, I finally understand the Assembler Im writing and learnt a great deal about Debugging under Bochs!
Its so... like, good feeling to be able to fix a problem after weeks of it making you want to scream!
Its just a standard FAT12 bootloader, but... Ive rewritten old Bootloader code so many times now, that most of this was written by me! Although, Ive referenced hundreds of other peoples bootloaders and articles in order to try and fix some bugs. But most of it I didnt have to change, YAY!.
The bootloader loads a file called K.BIN from the floppydrive, and will load it in all its entirity.
K.bin is the Second stage bootloader and Kernel all in one file.
Stage2 so far, has room for about 1kb of code.
at the 1kb point (offset 0x400) in the file, the Kernel code begins.
And, my sector loads the file to 0x0000F000.
so, F000 - F400 is Stage 2 code.
F400 - ???? is Kernel code.
What I should do, is make the Stage2 copy the Kernel code to 0x10000, then execute it there. 0x10000 just feels tidy .
So, for the rest of the night - Im going to be working on the Stage 2 Bootloader Code.
To setup Protected Mode, Video mode I want the Kernel to start in, Stack for the Kernel. GDT (Ring0 Data/Code, Ring3 Data/Code, Null...)
THEN! Finally, ATLAST! Ill be in C World! YAYYYYYYY
Ive included the sourcecode to the Stage1 FAT12 Bootloader, should anyone be interested.
Its hardly commented, so I appologize in advance.
~Zeii.
Re:My FAT12 Bootsector FINALLY works :D
Congratulations! It looks good. I know the feeling of hair-tearing frustration; multitasking is still not working and allas, I am out of ideas to get it working, so it looks like i'll be re-writing multitasking again ???
Re:My FAT12 Bootsector FINALLY works :D
Ok, it DOESNT work, false alarm guys.
*sigh*
It goes nuts trying to load about 4kb +
It starts giving errors in Bochs about new FDD commands being sent.
Ive made some minor modifications, so the Address for the read-to location in RAM is updated by incremented ES by 0x20.
But, it still screws up.
Im out of ideas, so... if someone could have a peek at my code and try and figure it out, id be very greatful.
Ill be working on it too, to try and solve it, any help would be MASSIVELY appreciated.
~Zeii
*sigh*
It goes nuts trying to load about 4kb +
It starts giving errors in Bochs about new FDD commands being sent.
Ive made some minor modifications, so the Address for the read-to location in RAM is updated by incremented ES by 0x20.
But, it still screws up.
Im out of ideas, so... if someone could have a peek at my code and try and figure it out, id be very greatful.
Ill be working on it too, to try and solve it, any help would be MASSIVELY appreciated.
~Zeii
Re:My FAT12 Bootsector FINALLY works :D
Here is a dump, to help anyone who is trying to help me debug:
[FDD ] write 0x03f5: receiving new command 0x07, old one (0xe6) pending
=================================================
00001592229i[CPU ] real mode
00001592229i[CPU ] CS.d_b = 16 bit
00001592229i[CPU ] SS.d_b = 16 bit
00001592229i[CPU ] | EAX=0b1e0307 EBX=00000000 ECX=000a001a EDX=5d9a03f5
00001592229i[CPU ] | ESP=0000ff3d EBP=0000ff41 ESI=00007c5a EDI=0000f733
00001592229i[CPU ] | IOPL=0 id vip vif ac vm rf nt of df IF tf sf ZF af PF cf
00001592229i[CPU ] | SEG selector base limit G D
00001592229i[CPU ] | SEG sltr(index|ti|rpl) base limit G D
00001592229i[CPU ] | CS:f000( 0000| 0| 0) 000f0000 0000ffff 0 0
00001592229i[CPU ] | DS:eb02( 0000| 0| 0) 000eb020 0000ffff 0 0
00001592229i[CPU ] | SS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00001592229i[CPU ] | ES:0fe0( 0000| 0| 0) 0000fe00 0000ffff 0 0
00001592229i[CPU ] | FS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00001592229i[CPU ] | GS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00001592229i[CPU ] | EIP=00000500 (000004ff)
00001592229i[CPU ] | CR0=0x00000010 CR1=0 CR2=0x00000000
00001592229i[CPU ] | CR3=0x00000000 CR4=0x00000000
00001592229i[CPU ] >> ee
00001592229i[CPU ] >> : out dx, al
00001592229i[CTRL ] quit_sim called with exit code 1
~Zeii
[FDD ] write 0x03f5: receiving new command 0x07, old one (0xe6) pending
=================================================
00001592229i[CPU ] real mode
00001592229i[CPU ] CS.d_b = 16 bit
00001592229i[CPU ] SS.d_b = 16 bit
00001592229i[CPU ] | EAX=0b1e0307 EBX=00000000 ECX=000a001a EDX=5d9a03f5
00001592229i[CPU ] | ESP=0000ff3d EBP=0000ff41 ESI=00007c5a EDI=0000f733
00001592229i[CPU ] | IOPL=0 id vip vif ac vm rf nt of df IF tf sf ZF af PF cf
00001592229i[CPU ] | SEG selector base limit G D
00001592229i[CPU ] | SEG sltr(index|ti|rpl) base limit G D
00001592229i[CPU ] | CS:f000( 0000| 0| 0) 000f0000 0000ffff 0 0
00001592229i[CPU ] | DS:eb02( 0000| 0| 0) 000eb020 0000ffff 0 0
00001592229i[CPU ] | SS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00001592229i[CPU ] | ES:0fe0( 0000| 0| 0) 0000fe00 0000ffff 0 0
00001592229i[CPU ] | FS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00001592229i[CPU ] | GS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00001592229i[CPU ] | EIP=00000500 (000004ff)
00001592229i[CPU ] | CR0=0x00000010 CR1=0 CR2=0x00000000
00001592229i[CPU ] | CR3=0x00000000 CR4=0x00000000
00001592229i[CPU ] >> ee
00001592229i[CPU ] >> : out dx, al
00001592229i[CTRL ] quit_sim called with exit code 1
~Zeii
Re:My FAT12 Bootsector FINALLY works :D
You've got a recalibrate command being issued before the previous read completes. You need to add a delay in between reads. Set up an empty loop and adjust cx until you're clear. You also need to repeat your drive reset until cf=0.
Re:My FAT12 Bootsector FINALLY works :D
You need somewhere around 50ms between commands, according to the docs I have read.
Re:My FAT12 Bootsector FINALLY works :D
I thought the Recalibrate call was ONLY called when the Read failed?
Otherwise, it jumped out to cbrs_Success?
The recalibrate is :
xor ax, ax
int 0x13
right?
Thanks for your help, Ill test it shortly.
~Zeii
Otherwise, it jumped out to cbrs_Success?
The recalibrate is :
xor ax, ax
int 0x13
right?
Thanks for your help, Ill test it shortly.
~Zeii
Re:My FAT12 Bootsector FINALLY works :D
It reads data correctly up to the point where it hits 0x10000
If I tell it to LOAD the data to Memory location 0x10000 I get problems too.
This may sound like a REALLY bad way to get around this problem,
But... Is it possible to write a Minikernel, that has a Simple FDD driver in it, in C, and use that to load the rest of the Kernel?
If I load at 0x10000 I get a FDD I/O out of range error.
~Zeii.
If I tell it to LOAD the data to Memory location 0x10000 I get problems too.
This may sound like a REALLY bad way to get around this problem,
But... Is it possible to write a Minikernel, that has a Simple FDD driver in it, in C, and use that to load the rest of the Kernel?
If I load at 0x10000 I get a FDD I/O out of range error.
~Zeii.
Re:My FAT12 Bootsector FINALLY works :D
Alrighty .
Ive changed some things in the Bootloader.
I still cant load to 0x0000F000, because itll breach the 64kb boundary.
BUTTTT... On the bright side, with a little bit of messing around,
Ive got the old Kernel booting .
The Stage2 file, is being loaded to 0x7E00, and the Kernel at 0x8000
Everything is functioning so far
Ive tested Exception handling, Interrupts (with PIT), Text output, All of 'old' Citadel's functions and calls are working just as they did then.
YAY! I have a bootloader that works!.
Since I cant solve the bug to do with the boundary (I even corrected the Segment for ES, and I have no luck), Ive worked 'around' the bug.
Heh, only a Geek would do that . lol.
Anywho, Im pondering with ideas now.
I do want the Kernel at 0x10000, rather than 0x8000, something about 0x8000 just doesnt seem .... right.
But then again, The Kernels purpose (since Im trying to make a Microkernel) is simply to manage memory, multitasking stuff (like Processes / threads), and Interprocess communication. I can probably fit all of that under the boundary.
OR...
I could do something slightly strange and different.
Right, Bootloader Stage1 executes, loads Bootloader S2 to 0x7E00, the 'Kernel' is located at 0x8000. Bootloader S2 sets up Protected Mode and the GDT, then jumps to the Kernel stub at 0x8000, which then directly calls the Kernels Main function.
What if, the 'kernel', isnt a kernel. Its just... like, a Minikernel. A protected mode program, with enough to tell you when theres an exception, and to use interrupts and print some text on screen. This Minikernel could bootstrap the 'real' kernel, since its in Protected Mode, the boundary issues no longer seem to matter.
The Minikernel, with its FAT12 Driver and FDC Driver, could load the 'real' kernel to 0x10000, once thats done, the Minikernel C code would finnish, returning control to the Minikernel Assembly stub, which would then jump to 0x10000 and begin execution of the 'real' kernel.
Or I could just stop thinking 0x10000 is a magickal place of serenity, and make the Kernel reside at 0x8000.
Any ideas / suggestions?
What do you think of my Zany plan? Do you think its necessary?
Oh, and anyone with MSN, Yahoo or ICQ.
Feel free to add me, my details are in my Profile.
Itd be cool to talk to OS Devers in real time
~Zeii.
Ive changed some things in the Bootloader.
I still cant load to 0x0000F000, because itll breach the 64kb boundary.
BUTTTT... On the bright side, with a little bit of messing around,
Ive got the old Kernel booting .
The Stage2 file, is being loaded to 0x7E00, and the Kernel at 0x8000
Everything is functioning so far
Ive tested Exception handling, Interrupts (with PIT), Text output, All of 'old' Citadel's functions and calls are working just as they did then.
YAY! I have a bootloader that works!.
Since I cant solve the bug to do with the boundary (I even corrected the Segment for ES, and I have no luck), Ive worked 'around' the bug.
Heh, only a Geek would do that . lol.
Anywho, Im pondering with ideas now.
I do want the Kernel at 0x10000, rather than 0x8000, something about 0x8000 just doesnt seem .... right.
But then again, The Kernels purpose (since Im trying to make a Microkernel) is simply to manage memory, multitasking stuff (like Processes / threads), and Interprocess communication. I can probably fit all of that under the boundary.
OR...
I could do something slightly strange and different.
Right, Bootloader Stage1 executes, loads Bootloader S2 to 0x7E00, the 'Kernel' is located at 0x8000. Bootloader S2 sets up Protected Mode and the GDT, then jumps to the Kernel stub at 0x8000, which then directly calls the Kernels Main function.
What if, the 'kernel', isnt a kernel. Its just... like, a Minikernel. A protected mode program, with enough to tell you when theres an exception, and to use interrupts and print some text on screen. This Minikernel could bootstrap the 'real' kernel, since its in Protected Mode, the boundary issues no longer seem to matter.
The Minikernel, with its FAT12 Driver and FDC Driver, could load the 'real' kernel to 0x10000, once thats done, the Minikernel C code would finnish, returning control to the Minikernel Assembly stub, which would then jump to 0x10000 and begin execution of the 'real' kernel.
Or I could just stop thinking 0x10000 is a magickal place of serenity, and make the Kernel reside at 0x8000.
Any ideas / suggestions?
What do you think of my Zany plan? Do you think its necessary?
Oh, and anyone with MSN, Yahoo or ICQ.
Feel free to add me, my details are in my Profile.
Itd be cool to talk to OS Devers in real time
~Zeii.
Re:My FAT12 Bootsector FINALLY works :D
After viewing the Memory Map provided by Bubachs,
I think I know the bug...
The Bootloader Stack is set to start at 0x0 and move up.
See the problem?
The problem is after loading so many sectors, that it starts issuing crazy commands to the Floppy disk, like Write and such.
According to Bubachs map, 0x0000ish area is the BIOS IVT.
Im overwriting it. And thats why im having such serious trouble there!
Yeah? Suggestions, opinions?
~Zeii
I think I know the bug...
The Bootloader Stack is set to start at 0x0 and move up.
See the problem?
The problem is after loading so many sectors, that it starts issuing crazy commands to the Floppy disk, like Write and such.
According to Bubachs map, 0x0000ish area is the BIOS IVT.
Im overwriting it. And thats why im having such serious trouble there!
Yeah? Suggestions, opinions?
~Zeii
Re:My FAT12 Bootsector FINALLY works :D
Debugged!
Stack was at 0000:FFFF, going down.
See the problem?
If I was reading into 0xF000, 0xF000 - 0xF200 is S2 Bootloader, 0xF200 - ???? Was the Kernel.
FFFF was being overwritten, the Stack was being raped!
Meaning all commands I was sending to the BIOS Was being bjorked big time, and then the Kernel code was being overwritten with the next readSector loop.
Well, thats my take of the bug. Im yet to fix it, and to be honest - I dont really need to fix it at this point.
But, thats my take of the bug.
Advice / Suggestion / Opinion?
~Zeii.
Stack was at 0000:FFFF, going down.
See the problem?
If I was reading into 0xF000, 0xF000 - 0xF200 is S2 Bootloader, 0xF200 - ???? Was the Kernel.
FFFF was being overwritten, the Stack was being raped!
Meaning all commands I was sending to the BIOS Was being bjorked big time, and then the Kernel code was being overwritten with the next readSector loop.
Well, thats my take of the bug. Im yet to fix it, and to be honest - I dont really need to fix it at this point.
But, thats my take of the bug.
Advice / Suggestion / Opinion?
~Zeii.
Re:My FAT12 Bootsector FINALLY works :D
Thats the direction stacks are ment to go. :-\zeii wrote: Debugged!
Stack was at 0000:FFFF, going down.
See the problem?
I also see a misaligned stack (extra clock per push/pop/call/stack mov's such as parameters) and a stack that can potentially overwrite the BIOS data area and IVT. Although 64KB is quite an insane amount to use to load a kernel, its still bad practice to define a stack such as that.
Re:My FAT12 Bootsector FINALLY works :D
I agree Ryu!
So, Where do you imagine would be a good healthy place to plop the Stack?
Also, if possible, could you give me the line number of the Extra Push/Pop?
Thank you!
~Zeii
So, Where do you imagine would be a good healthy place to plop the Stack?
Also, if possible, could you give me the line number of the Extra Push/Pop?
Thank you!
~Zeii
Re:My FAT12 Bootsector FINALLY works :D
A healthy place for a bootstrap stack is above 800h and below 7C00h in linear addresses (29KB). The reason why because your garenteed that theres available RAM if the bootsector was loaded and managed to start executing in a x86 compatible system. 4KB should be plenty so I would say 80:1000h, that is.. SS=80h SP=1000h starting pointer or top of the stack.zeii wrote:So, Where do you imagine would be a good healthy place to plop the Stack?
I didn't went through your code what I ment was, if you set SP=FFFFh, every push/pop/call/ret/stack mov's will have a extra clock penalty because its not aligned in words in 16bit mode.zeii wrote:Also, if possible, could you give me the line number of the Extra Push/Pop??
Re:My FAT12 Bootsector FINALLY works :D
Thanks Ryu!
0x00080 : 0x01000h
0x00801000 Would be the stack location?
~Z
0x00080 : 0x01000h
0x00801000 Would be the stack location?
~Z