Custom BootSector Booting Into Stage2 [Problems]

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.
XeonX369
Member
Member
Posts: 29
Joined: Mon Sep 28, 2009 1:12 pm

Custom BootSector Booting Into Stage2 [Problems]

Post 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.
User avatar
qw
Member
Member
Posts: 792
Joined: Mon Jan 26, 2009 2:48 am

Re: Bootsector not Booting into Stage 2

Post 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
    ...
User avatar
gravaera
Member
Member
Posts: 737
Joined: Tue Jun 02, 2009 4:35 pm
Location: Supporting the cause: Use \tabs to indent code. NOT \x20 spaces.

Re: Bootsector not Booting into Stage 2

Post 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.
17:56 < sortie> Paging is called paging because you need to draw it on pages in your notebook to succeed at it.
User avatar
Masterkiller
Member
Member
Posts: 153
Joined: Sat May 05, 2007 6:20 pm

Re: Bootsector not Booting into Stage 2

Post 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;
ALCA OS: Project temporarity suspended!
Current state: real-mode kernel-FS reader...
XeonX369
Member
Member
Posts: 29
Joined: Mon Sep 28, 2009 1:12 pm

Re: Bootsector not Booting into Stage 2

Post 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<
neonek
Member
Member
Posts: 38
Joined: Thu Aug 28, 2008 1:53 pm
Location: Białystok - Podlasie, Poland

Re: Bootsector not Booting into Stage 2

Post 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 :)
Please correct my English. If you'll find mistake please tell me about it so I can improve my English.
User avatar
NickJohnson
Member
Member
Posts: 1249
Joined: Tue Mar 24, 2009 8:11 pm
Location: Sunnyvale, California

Re: Custom BootSector Booting Into Stage2 [Problems]

Post 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.
XeonX369
Member
Member
Posts: 29
Joined: Mon Sep 28, 2009 1:12 pm

Re: Custom BootSector Booting Into Stage2 [Problems]

Post 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!
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Custom BootSector Booting Into Stage2 [Problems]

Post by Combuster »

Once again, where are your segment registers?
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
XeonX369
Member
Member
Posts: 29
Joined: Mon Sep 28, 2009 1:12 pm

Re: Custom BootSector Booting Into Stage2 [Problems]

Post 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.
Attachments
bootsector.asm
(3.31 KiB) Downloaded 101 times
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Custom BootSector Booting Into Stage2 [Problems]

Post by Combuster »

/facepalm.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
neonek
Member
Member
Posts: 38
Joined: Thu Aug 28, 2008 1:53 pm
Location: Białystok - Podlasie, Poland

Re: Custom BootSector Booting Into Stage2 [Problems]

Post by neonek »

RBIL int 0x13 function 0x02. Read carefully, you've incorrectly set registers.
Please correct my English. If you'll find mistake please tell me about it so I can improve my English.
XeonX369
Member
Member
Posts: 29
Joined: Mon Sep 28, 2009 1:12 pm

Re: Custom BootSector Booting Into Stage2 [Problems]

Post 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.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Custom BootSector Booting Into Stage2 [Problems]

Post by Combuster »

briandknopp wrote:Any further assistance.
Well, it may be an idea to try something easier than OS development for practice...
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Custom BootSector Booting Into Stage2 [Problems]

Post 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 ;)
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Post Reply