Page 1 of 2

Custom BootSector Booting Into Stage2 [Problems]

Posted: Tue Oct 06, 2009 2:28 pm
by XeonX369
My problem is as follows: my bootsector is not booting into the second stage. I have already theorized that it is the destination to which it copies Stage 2 into that was the problem, but when I changed it, it turned out to be not the case, now I believe that it is the fact that I am booting off of a USB drive. Here is my code:

Code: Select all

;XIX System 19 Bootsector - Version 1.00
;
;The purpose of this bootsector is simply to load
;the second stage of the XIX Bootloader, normally
;called the Bootloader.
;
;This is the case, in order to circumvent the now-
;restricting 512 (actually ~440) byte limit of the
;MBR, and to allow future implementations of error
;handling, error logging, hardware diagnostics,
;portability, and multi-boot support.
;
;For full documentation, read the source-enclosed
;bootsector.img.doc file.

[BITS 16]		;Assembler Directive denoting 16-bit Real-Mode
[ORG 0x7C00]		;Assembler Directive denoting residence at 0x7C00 in memory

begin:		;function that jumps over the data section and into the boot sequence
	jmp boot


;Section for Functions
prntstr:	;function that will print a string, loaded into SI, on screen
	mov ah, 0x0E	;place 0x0E (teletype function) into AH

	mov bh, 0x00	;set page number to page 1
	mov bl, 0x000E	;set attribute to Green Text, Black Background, non-Flashing

	.nxtchar	;label to jump to if AL is not equal to Null Char
	lodsb		;load the string residing in SI, into AL for printing
	or al, al	;check to see if AL = Null Character

	jz .ret		;if zero, jump to label to return to main program

	int 0x10	;call int 0x10 to print the string
	jmp .nxtchar

	.ret		;label to jump to if AL = Null Character
ret

readdsk:	;function that will reset the disk, then read it into 0x8000
	.rstdsk
	mov ah, 0x00		;place 0x00 (reset function) into AH
	mov dl, [bootdrv]	;reset drive

	int 0x13		;call int 0x13 to reset drive
	jc .rstdsk		;jmp to .rstdsk if carry flag is set (reset failed)

	mov ax, 0x8000		;load 0x8000 into AX register (can't directly manipulate ES
	mov es, ax		;set ES to contents of AX (location of memory to read to)
	xor bx, bx		;set offset to 0x0000

	.rddsk
	mov ah, 0x02		;place 0x02 (read function) into AH
	mov al, 0x01		;read 1 sectors
	mov ch, 0x01		;read 1 track
	mov cl, 0x02		;read 2 sectors ahead of track 1
	mov dh, 0x00		;read from head 0
	mov dl, [bootdrv]	;read from drive

	int 0x13	;call int 0x13 to read from disk
	jc .rddsk	;if carry flag is set (read unsuccessfull) try again
ret


;Section for Strings
sysmess db 'XIX System 19 Bootsector - Version 1.00',13,10,10,0	;string to print system information
								;13 = character return
								;10 = new line
								;0 = null character (end string)

dsksucc db 'Disk Reading Successfull, Will now Load Stage 2',13,10,0


;Section for Variables
bootdrv db 0	;variable to store drive number


;Main Program
boot:
	mov [bootdrv], dl	;load the boot-drive number into the bootdrv variable

	lea si, [sysmess]	;load effective address of string sysmess into SI
	call prntstr		;call the function to print the string

	call readdsk		;call the function to load from disk into memory
	lea si, [dsksucc]	;dsksucc into SI
	call prntstr		;call the function to print the string

	jmp 0x8000:0x0000	;jump to instruction residing in 0x7E00 (stage 2 bootloader)

	hlt			;halt the processor from executing this instruction


;Necessities for the Bootsector
times 510-($-$$) db 0		;fill unused space upto 510 bytes (0x1FE)
signature dw 0xAA55		;append the bootloader signature to last 2 bytes (0x1FE-0x200) 
Also, what is the best place to put a Stage 2 bootloader in memory. As you can see, I have it set to 0x8000. Would 0xFFFF be any different.

Re: Bootsector not Booting into Stage 2

Posted: Tue Oct 06, 2009 3:17 pm
by qw
Set up your segment registers and stack first. The BIOS does not do that for you. Enable interrupts. And since you're using string instructions, clear the Directory Flag as well.

Code: Select all

;Main Program
boot:
    xor ax, ax
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov sp, some_stack_top
    sti
    cld
    ...

Re: Bootsector not Booting into Stage 2

Posted: Tue Oct 06, 2009 4:29 pm
by gravaera
I'm not actually proposing this as the solution, mind you, just mentioning something. As a supplementary note to what hobbes said, it is advisable to actually clear all flags as soon as you're booted up: No reason why any of them should be set, or left in an undefined state. Just go:

Code: Select all

clearFlags:
   push dword 0
   popf
Right after you've set up your stack.

Re: Bootsector not Booting into Stage 2

Posted: Wed Oct 07, 2009 4:06 am
by Masterkiller
briandknopp wrote:now I believe that it is the fact that I am booting off of a USB drive.
First: Are you sure that you write that code into MBR? It is possible while in OS, to write the code to Volume Boot Sector, and the MBR to write it transparently. Ensure that the layout of MBR is MBRless.
Second: Second sector is on Cylinder(0) Head(0) Sector(2); not in Cylinder(1) Head(0) Sector(2);
Third: 0x8000:0x0000 = Physical Address: 0x80000; The calculation of physical address is Segment*0x10+offset; That is not a problem since you use the same values with load sector;

Re: Bootsector not Booting into Stage 2

Posted: Wed Oct 07, 2009 8:55 am
by XeonX369
Thank you Masterkiller for your reply about the Cylinders, I suppose that I changed that to see what it does, but in the end, it did nothing.

I tried everyone's solutions, with none actually solving it. Am I still doing something incorrect, I have this as the portion of code (within boot: function) that will reset registers and set up the stack.

Code: Select all

xor ax, ax		;refresh all segment registers
    	mov ds, ax
    	mov es, ax
    	mov ss, ax
    	mov sp, 0x200		;stack size is 0x200 bytes (512) 
    	sti			;enable interupts
    	cld			;clear the direction flag
Is this appropriate, I am having many grievances with this particular portion of OSDev. I realize that I could use GRUB, but I really would like to have my own bootsector/bootloader.

So, any more advice? [-o<

Re: Bootsector not Booting into Stage 2

Posted: Wed Oct 07, 2009 9:41 am
by neonek
I think sp register should point to the top of the stack. Address 0x7C00 is the load address, 0x200 is the bootsector size and if you want a 0x200 bytes stack so sp value should be 0x7C00+0x400 = 0x8000. Some BIOSes loads bootsector at 0x07C0:0x0000, some at 0x0000:0x7C00 and you should jump to boot label as cs:ip pair, for example:
cs = 0x0000

Code: Select all

jmp 0x0000:boot
cs = 0x07C0

Code: Select all

jmp 0x07C0:boot
This are my observations about code.
I'm coding bootloader too :)

Re: Custom BootSector Booting Into Stage2 [Problems]

Posted: Wed Oct 07, 2009 11:07 am
by NickJohnson
@neonk: I think the sp register is still pointing to the top of the stack... it doesn't have to be directly above the code (and is probably safer elsewhere).

However, you really don't want to overwrite 0x000-0x500: it contains the IVT and BDA, which are important for BIOS functions. That would definitely cause random problems. I would move the stack pointer to 0x7C00, so it grows down into the plentiful free memory from 0x0500 to 0x7BFF. As long as it doesn't hit 0x7C00-0x8000, 0x0000-0x0500, or anything above 0x80000 you should be okay.

Re: Custom BootSector Booting Into Stage2 [Problems]

Posted: Wed Oct 07, 2009 12:51 pm
by XeonX369
I tried setting SP to 0x7C00, and the result was the same non-functioning.

It acts as if it jumps to where the stage 2 is supposed to be loaded to (0x8000) but it either doesn't go to the program, or the stage 2 just doesn't work. To help, I have attached the (small) Stage 2 code

Code: Select all

;XIX System 19 Bootloader - Version pre-Alpha
;
;This version of the XIX System 19 Bootloader is used
;only to test the capabilities of the new and improved 
;bootsector.
;
;It will merely display a system information string

[BITS 16]	;Assembler Directive denoting this as 16-bet Real Mode
[ORG 0x0000]	;Assembler Directive denoting this as existing at offset 0x0000

begin:		;function to jump over the data section and into the main boot sequence
	jmp boot


;Section for Functions
prntstr:	;function to print a string loaded into AL
	mov ah, 0x0E	;load 0x0E (teletype) into AH

	mov bh, 0x00	;set page number to 0 (page 1)
	mov bl, 0x000E	;set attribute to Green Text, Black Background, non-flashing

	.nxtchar	;label to repeat int 0x10
	lodsb		;load string in SI, into AL
	or al, al	;check to see if AL = null char (set zero if true)

	jz .ret		;jump over int 0x10 and exit function

	int 0x10	;call int 0x10 to print the string
	jmp .nxtchar	;repeat the routine if null character is not yet present

	.ret		;label to jump to, to get out of the loop
ret


;Section for Strings
sysmess db 'XIX System 19 Bootloader - Version pre-Alpha',13,10,10,0	;System Information String
									;13 = char return
									;10 = new line
									;0 = null character (terminate)


;Main Program
boot:
	lea si, [sysmess]	;load effective address of sting sysmess into SI
	call prntstr		;call function to print the string

	cli			;REMOVE AFTER TEST
	hlt			;REMOVE AFTER TEST
once again, Please Help, I am so grateful for all effort to this point!

Re: Custom BootSector Booting Into Stage2 [Problems]

Posted: Wed Oct 07, 2009 12:54 pm
by Combuster
Once again, where are your segment registers?

Re: Custom BootSector Booting Into Stage2 [Problems]

Posted: Wed Oct 07, 2009 1:00 pm
by XeonX369
Combuster wrote:Once again, where are your segment registers?
Segment Registers in the bootsector, or in the Stage 2 bootloader?

The attached file is the current bootsector.

Re: Custom BootSector Booting Into Stage2 [Problems]

Posted: Wed Oct 07, 2009 1:13 pm
by Combuster
/facepalm.

Re: Custom BootSector Booting Into Stage2 [Problems]

Posted: Wed Oct 07, 2009 1:27 pm
by neonek
RBIL int 0x13 function 0x02. Read carefully, you've incorrectly set registers.

Re: Custom BootSector Booting Into Stage2 [Problems]

Posted: Wed Oct 07, 2009 1:37 pm
by XeonX369
neonek wrote:RBIL int 0x13 function 0x02. Read carefully, you've incorrectly set registers.
Should I set the registers to the following values:

Code: Select all

mov al, 0x10		;total sectors to read (16)
	mov ch, 0x00		;read track 1
	mov cl, 0x02		;read from sector 2
	mov dh, 0x00		;read from head 0
Is this correct. All of the different tutorials I see have all sorts of different explainations for what is to go here.

EDIT: Oops, i tried these values, with no success. Any further assistance.

Re: Custom BootSector Booting Into Stage2 [Problems]

Posted: Wed Oct 07, 2009 1:46 pm
by Combuster
briandknopp wrote:Any further assistance.
Well, it may be an idea to try something easier than OS development for practice...

Re: Custom BootSector Booting Into Stage2 [Problems]

Posted: Wed Oct 07, 2009 2:00 pm
by neon
Hello,

Your "second stage bootloader" has and ORG of 0, meaning a displacement will not be added to any memory reference. This is fine, and is recommended in most cases, but this also means that you have to set up your segment registers correctly as well.

I do not see at all where you set your segment registers too. You should set your registers to 0x8000 in your "2nd stage" boot code.

Also, loading your "2nd stage" to 0x80000 is fine. I personally load my boot manager to 0x500 but it does not really matter. There is no "best" location besides one that is almost always guaranteed to be available and physical RAM.

*edit: Also, I highly recommend using a file system [unless you have plans for your own implementation.] rather then reading raw sectors the way you are currently doing. Just a suggestion ;)