Page 1 of 1

Concerns with Second Stage of Bootloader

Posted: Thu Nov 10, 2011 11:52 am
by theseankelly
Hey, continuing on with writing my own bootloader for the educational value.

What I currently have:
cdboot.S first stage that knows how to parse ISO 9660 and does successfully find and load the second stage to 0x0600 (verified in bochs mem dumps).

I'm attempting to write a second stage that is agnostic to filesystem or device type. To do this, I reserve a couple dwords at the top of my stage2 where it'll expect to find the kernel LBA offset and # of LBAs to load (I'm assuming int 13 extensions are available, for now -- first stage gives up if they aren't). Basically it's either up to stage1 which knows how to read a FS to find the kernel file and populate these dwords after stage2 is loaded (which is what my cdboot does -- and correctly, based on bochs memory dumps), or else up to an install utility to set them on disk.

So, my concerns.
The first few lines of code of my stage2:

Code: Select all

[bits 16]                 ; using 16 bit assembly
[org 0x0600]    

start: 
			jmp		real_start
			times 8-($-$$) db 0
kernloc		dd	0
kernsize	  dd	0	

real_start:				
   ; let's see if we have kernel info 
			cmp		dword [kernloc], 0
			jz		.end
			cmp		dword [kernsize], 0		
			jz		.end
Basically I arbitrarily decided that the kernel location info would be 8 bytes into the file to leave some room for code to jump over it. The code does seem to function correctly (even when I do something else like enable a20 instead of that comparison) but bochs doesn't disassemble correctly. Stepping through the function, the first jump seems to happen twice, and it only picks up the second "cmp" in the disassembled window. Also, if I put breakpoint (xchg bx,bx) as the first instruction at "real_start", bochs doesn't hit it.

Is this possibly a bochs error, or are my db commands messing something up? I'm not sure whether or not to be concerned, because I haven't experienced any runtime errors yet.

Some other minor concerns I'm not sure about:
My stage1 sets the segment registers to zero, and SP to 0x600.
1) It's not necessary for my stage2 to re-set all these values since the stack isn't overwritten, and I'm still in 16bit mode, right?
2) Is a 256byte stack big enough? I don't make any deeply nested function calls other than whatever interrupts do.

Thanks
Sean

Re: Concerns with Second Stage of Bootloader

Posted: Thu Nov 10, 2011 12:03 pm
by CWood
I think I know what is happening here. I had the same issue. The bochs debugger is simply becoming mis-aligned. Nothing to really worry about, so long as your code works, I managed to debug "around" this limitation, which wasn't particularly easy, but certainly, it is possible. Just don't worry about it too much, and use a different disassembler as well, for cross-references (I get my make file to automatically ndisasm everything)

Re: Concerns with Second Stage of Bootloader

Posted: Thu Nov 10, 2011 12:29 pm
by bluemoon
theseankelly wrote:1) It's not necessary for my stage2 to re-set all these values since the stack isn't overwritten, and I'm still in 16bit mode, right?
Yes.
theseankelly wrote:2) Is a 256byte stack big enough? I don't make any deeply nested function calls other than whatever interrupts do.
To rule out the assumption of interrupts won't do deeply nested function itself, I disable it (by PUSH/POPF to init EFLAG) until I enter my kernel.

Re: Concerns with Second Stage of Bootloader

Posted: Thu Nov 10, 2011 12:38 pm
by gerryg400
Is this possibly a bochs error, or are my db commands messing something up?
I'm not sure about this exact situation but DB commands can in general confuse disassemblers/debuggers. The dissembler can lose synch trying to understand what the data in the 8 bytes is and take a few instructions to get back on track. Perhaps that's what happening.