Page 1 of 2

[solved]Why can't I load the second sector to memory?

Posted: Sat Jan 08, 2011 9:55 am
by shedokan
Hi,
I'm just starting my own bootloader and I can't seem to be able to load the second sector of a floppy to memory.
This code worked and somehow it just stoped working after some change which I don't remember.

Can you please look at the code and tell me what I am doing wrong?
I have checked the code dozens of times and it looks like it should work fine.

I also have this at the top of the file:

Code: Select all

bits 16 ; set the mode to 16 bit
org 0x7C00 ; the bootloader is loaded into 0x7c00

jmp blStart ; jump over OEM block
I also have an OEM block after that and then I have the code with the problem:

Code: Select all

blStart:

; Reset floppy
blResetFloppy:
	xor ah, ah ; use function 0x0 to reset floppy
	xor dl, dl ; drive 0 is floppy drive

	int 13h ; call BIOS
	jc blResetFloppy ; If Carry Flag (CF) is set, there was an error. Try resetting again

	; Done Reset

	; Read second sector from floppy to 0x7E00:0
	mov ax, 0x7E00 ; put 0x7E00 temporarily in ax
	mov es, ax ; set es to 0x7E00
	xor bx, bx ; set bx to 0

blReadSecondSector:
	mov ah, 02h ; use function 0x02
	mov al, 1 ; read 1 sector

	mov ch, 1 ; its still on track 1(cylinder 1)
	mov cl, 2 ; read the second sector

	xor dx, dx ; use head 0 to read and read from drive 0(floppy drive)

	int 13h ; read sectors
	jc blReadSecondSector ; If Carry Flag (CF) is set, there was an error. Try reading again

	; jump to the loaded sector
	jmp 0x7E00:0x0

; Fill the file with zeros to fit into a whole section(512 bytes)
times 510-($-$$) db 0

dw 0xAA55 ; Boot sector identifyer

; sector 2 - second bootloader part ----------------------------------------------------------------------------------------------

mov ax, 0
int 10h

cli
hlt

times 1024-($-$$) db 0
I use : PARTCOPY boot.bin 0 400 -f0

While debugging with functions that print out messages using bios it resets and reads fine ut I don't know if it's reading what it's supposed to.

Thanks

Re: Why can't I load the second sector to memory?

Posted: Sat Jan 08, 2011 10:42 am
by M2004
After a quick look: You are loading to linear address of 0x7E000 instead of linear address of 0x7e00.

Putting 0x7E00 to a segment register corresponds to linear value 0x7E000
; Read second sector from floppy to 0x7C00:0x0200
mov ax, 0x7E00 ; put 0x7C00 temporarily in bx
mov es, ax ; set es to 0x7C00
xor bx, bx ; set bx to 0
Fix:

Code: Select all

   mov ax, 0x7E0  ;This will correspond to the linear adress of 0x7e00
   mov es, ax 
   xor bx, bx 
regards
Mac2004

Re: Why can't I load the second sector to memory?

Posted: Sat Jan 08, 2011 12:11 pm
by shedokan
Thanks for your reply, I tried your fix but it doesn't look like it changes anything.
From looking at other assembly code your fix is good but there's probably something else wrong with it.

Re: Why can't I load the second sector to memory?

Posted: Sat Jan 08, 2011 12:59 pm
by Combuster

Code: Select all

   jmp 0x7E00:0x0
Many instances of the same mistake?

Re: Why can't I load the second sector to memory?

Posted: Sat Jan 08, 2011 3:11 pm
by shedokan
Combuster wrote:

Code: Select all

   jmp 0x7E00:0x0
Many instances of the same mistake?
If I have many instances of the same mistake with the same 0xCE00 address everywhere doesn't it mean that I don't have a mistake?
If I understand correctly I need to use:

Code: Select all

mov ax, 0x7E0
and
jmp 0x7E0:0x0
which means it doesn't matter if I use 0x7E0 or 0x7E00 right?

Thanks

Re: Why can't I load the second sector to memory?

Posted: Sat Jan 08, 2011 10:25 pm
by thepowersgang
You appear to no understand the idea of real-mode segmentation

I suggest reading the wiki and other sites to get a proper understanding, but here's a quick introduction.

In real mode, memory access is performed via a segment (usually using the value in DS) and an offset (usually encoded in the instruction) and represented as Segment:Offset

The linear (actual) address is equal to Segment*16+Offset

Re: Why can't I load the second sector to memory?

Posted: Sun Jan 09, 2011 12:59 am
by prasadjvv
If I am not wrong, you are intended to read second sector in first track (cylinder) on "head 0".

The following line tells that, you are trying to read from second cylinder rather than first one.
mov ch, 1 ; its still on track 1(cylinder 1)

Please observe that cylinder number starts from index 0 (not from 1) for int 13h.
Note 2: don't confuse with sector no's as sector no's start from 1.
(This is a common mistake I might have done (have done, don't remember), when I
started to use INT 13h).

Re: Why can't I load the second sector to memory?

Posted: Sun Jan 09, 2011 2:48 am
by M2004
shedokan: LBA /CHS conversion information can be found here.
http://en.wikipedia.org/wiki/Logical_block_addressing

Secondly: Setting a up proper stack would be a good idea.

Here's my boot loader example.
http://board.flatassembler.net/topic.php?t=6529

regards
Mac2004

Re: Why can't I load the second sector to memory?

Posted: Sun Jan 09, 2011 6:18 am
by Chandra
mac2004 wrote:After a quick look: You are loading to linear address of 0x7E000 instead of linear address of 0x7e00.

Putting 0x7E00 to a segment register corresponds to linear value 0x7E000
; Read second sector from floppy to 0x7C00:0x0200
mov ax, 0x7E00 ; put 0x7C00 temporarily in bx
mov es, ax ; set es to 0x7C00
xor bx, bx ; set bx to 0
Fix:

Code: Select all

   mov ax, 0x7E0  ;This will correspond to the linear adress of 0x7e00
   mov es, ax 
   xor bx, bx 
regards
Mac2004
Good Suggestion, but not a solution though. No matter where he loads the 2nd sector, he is jumping to right linear address and hence this is not the actual problem. But yes, you need to be careful not to load the kernel (or possibly 2nd stage loader) to the reserved area such as Bios Data Area.
prasadjvv wrote:If I am not wrong, you are intended to read second sector in first track (cylinder) on "head 0".

The following line tells that, you are trying to read from second cylinder rather than first one.
mov ch, 1 ; its still on track 1(cylinder 1)

Please observe that cylinder number starts from index 0 (not from 1) for int 13h.
Note 2: don't confuse with sector no's as sector no's start from 1.
(This is a common mistake I might have done (have done, don't remember), when I
started to use INT 13h).
Now, that's the fix. Exactly, cylinder number starts from 0 and not 1.

Re: Why can't I load the second sector to memory?

Posted: Sun Jan 09, 2011 11:46 am
by shedokan
prasadjvv wrote:If I am not wrong, you are intended to read second sector in first track (cylinder) on "head 0".

The following line tells that, you are trying to read from second cylinder rather than first one.
mov ch, 1 ; its still on track 1(cylinder 1)

Please observe that cylinder number starts from index 0 (not from 1) for int 13h.
Note 2: don't confuse with sector no's as sector no's start from 1.
(This is a common mistake I might have done (have done, don't remember), when I
started to use INT 13h).
Thanks! your solution worked, I was using the brokenthorn tutorial, so I don't know why this problem was there.

Anyways thanks, and I'll be sure to read up about LBA.

I added the following after looking at GRUB's bootloader:

Code: Select all

blStart:
	; setup registers to point to our segment
	; set up ds and ss as offset from 0
	xor ax, ax
	mov ds, ax
	mov ss, ax
	mov es, ax

	; set the stack pointer
	mov sp, 0x2000
is that enough to initialize the stack?

Thanks

Re: Why can't I load the second sector to memory?

Posted: Sun Jan 09, 2011 1:53 pm
by M2004
shedokan wrote:is that enough to initialize the stack?
It would be wise to disallow interrupt's while doing the stack setup.
Otherwise it seems to be ok. Setting up the stack is not difficult. :)

Regards
Mac2004

Re: Why can't I load the second sector to memory?

Posted: Sun Jan 09, 2011 3:14 pm
by shedokan
Actually I have done that also in my new code.
Why do I have to clear interrupts before I set the new stack?
Is it so that interrupts won't interfere while only half of the registers are set correctly?

Thanks

Re: Why can't I load the second sector to memory?

Posted: Sun Jan 09, 2011 3:56 pm
by M2004
mac2004 wrote:Why do I have to clear interrupts before I set the new stack?
Is it so that interrupts won't interfere while only half of the registers are set correctly?
Interrupts use stack and having an interrupt while changing the stack would
cause unexpected results to occur.

regards
Mac2004

Re: Why can't I load the second sector to memory?

Posted: Sun Jan 09, 2011 9:55 pm
by quok
When you change the SS segment, interrupts are automatically disabled until after the next instruction. So it would be wise to immediately load SP/ESP next and not ES. :)

Re: Why can't I load the second sector to memory?

Posted: Tue Jan 11, 2011 12:39 pm
by shedokan
mac2004 wrote:
mac2004 wrote:Why do I have to clear interrupts before I set the new stack?
Is it so that interrupts won't interfere while only half of the registers are set correctly?
Interrupts use stack and having an interrupt while changing the stack would
cause unexpected results to occur.

regards
Mac2004
thnanks for the info.
quok wrote:When you change the SS segment, interrupts are automatically disabled until after the next instruction. So it would be wise to immediately load SP/ESP next and not ES. :)
so why grub does it?