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.
I'm re-writing my boot loader to be two stages primarily to avoid the 512 byte limit on the regular sized boot loader. Before I get redirected, I have read this thread and it hasn't helped:
Stages one and two of the boot loader work exactly as expected right up until the very last nasm command at the end of stage two: the far jump. The error I get looks like this:
; declare a "main"
bl_s2_main:
; ensure interrupts are disabled
cli
; ensure the stack is setup correctly
xor ax,ax
mov ss,ax
mov sp,STAGE_TWO_OFFSET
; ensure data segments are correct
xor ax,ax
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
; load the kernel
call load_kernel
; load the GDT
lgdt [ BLOC_S2(gdt_descriptor) ]
; enter p_mode
mov eax,cr0
or eax,1
mov cr0,eax
; CODE WORKS PERFECTLY UP TO THIS POINT (NO BOCHS ERRORS AND DBG STATEMENTS WILL OUTPUT FINE HERE)
; jump to kernel
jmp DWORD 0x0008:KERNEL_OFFSET
I think the problem might be that I'm trying to read from too many disk sectors without increasing the track... How can I tell how many sectors there are in each track so that I know when to carry over X number of sectors and increase the track amount?
Are you sure to have enabled A20? If not, you might not be writing anything to an odd Megabyte (0x100000, 0x300000, etc.) and instead writing somewhere at the Megabyte just before.
You should press the SUSPEND button of Bochs and save the machine state in an empty folder (when asked if you want to save disk states answer YES) --- it may make Bochs to freeze, but then with a hex editor with good disassembly capabilities you can inspect the "memory.ram" file to see if your program is properly loaded in the memory areas intended.
You can also inspect the other files to see if everything makes sense. Some files, or maybe all of them, like the "cpu0" file are plaintext files containing the device state (register values).
But you must make sure to add a "jmp $" or some sort of infinite loop just before the crash so you can have an opportunity to SUSPEND to save state.
NOTE: also check carefuly the correctness of the GDT fields of each entry (what's that Gate Type 0 not supported???). You could use the previous method to find out if the GDT is really well-built in the memory.
brodeur235 wrote:I think the problem might be that I'm trying to read from too many disk sectors without increasing the track... How can I tell how many sectors there are in each track so that I know when to carry over X number of sectors and increase the track amount?
The CPU will let you JMP to a dodgy address (you'd crash after the JMP, not during the JMP). Your problem is that the GDT is dodgy (e.g. wrong address used for the "lgdt" instruction), or descriptor 0x0008 is wrong.
On a higher level, switching to protected mode in a 512-byte first stage is always a design failure - it leaves you no way for the second stage to load anything (e.g. the third stage or the kernel or the boot image or whatever). I guess what I'm saying is that it's a good idea to load everything your OS will need to get device drivers working (using the BIOS) and gather any information from the BIOS that your OS will need (memory map, VBE, etc); and only switch to protected mode after all this is done (and you don't need the BIOS anymore).
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.