Page 1 of 1

Problem chainloading from 2nd stage of bootloader

Posted: Sat Jun 19, 2010 9:12 am
by jpshortstuff
A bootloader I'm writing provides a menu with the option:
"Boot from 1st hard disk"

Initially, I could fit my bootloader in 512 bytes. I had a small function (_load) to read (INT 13h, AH=02h) the boot-sector from the HD into 7C00h, and was relocating this function to 7E00h at runtime. This was working fine, no problems there.

Now, I am extending my bootloader, and this functionality needs to be in the second stage. I am loading this second stage into 7E00h from the second sector of a FAT12 floppy. Since the second stage is in 7E00h, there is no need to relocate the _load function, so I should be able to load the target boot-sector straight into 7C00h.

The second stage appears to be loading correctly, since the menu is displaying, and the other two options (install, shutdown; both in second stage as well) are also executing without problems. However, booting from the first HD is no longer working, and I can't for the life of me work out why.

Here's the function in question:

Code: Select all

_load:
  MOV AH, 02h     ; Read sectors from disk
  MOV AL, 1h      ; Read 1 sector
  MOV CH, 0h      ; First cylinder
  MOV CL, 1h      ; First sector
  MOV DH, 0h      ; First head
  MOV DL, 80h     ; First hard drive
  
  MOV BX, 07C0h   ; Target is 07C0h:0000h (ES:BX)
  MOV ES, BX
  MOV BX, 0h
  
  INT 13h         ; Execute read
  JC .read_err    ; Check for errors
  
  JMP 07C0h:0000h ; Transfer execution to boot sector

.read_err:
  MOV SI, .str_err_read
  CALL printstr
  JMP $
  
  ; Strings used by _load
.str_err_read db 'Error reading from first HD'
; _load end
This function hasn't changed from when it was in the first stage, the only difference is that it isn't being dynamically relocated (since it is already in the 07E0h segment). It's not firing the .read_err, but after it hits the JMP it just hangs.

Is there any reason why loading code from disk into memory would be any different than dynamically relocating it?

Any advice would be greatly appreciated.

Cheers.

Re: Problem chainloading from 2nd stage of bootloader

Posted: Sat Jun 19, 2010 12:49 pm
by b.zaar
First check that the whole of your 2nd stage bootloader is being loaded, maybe put some test code to print a message at the end of the 2nd stage loader and jump there to see it it works.

If the loader is all there then try verifying that the boot sector is being loaded by checking the boot signature (0xAA55) at 0x0000:7DFE before jumping to it. Also the loaded boot sector might be expecting the cs:ip values to be 0x0000:7C00 not 0x07C0:0000 which might affect some boot sectors.
jpshortstuff wrote:I am loading this second stage into 7E00h from the second sector of a FAT12 floppy.
I'm not sure what you're doing here either because I thought the 2nd sector of a FAT12 floppy was usually the first sector of the File Allocation Table? Are you adjusting the reserved sectors value in the BPB?

Re: Problem chainloading from 2nd stage of bootloader

Posted: Sun Jun 20, 2010 3:10 am
by jpshortstuff
Hi, thanks for the response.
b.zaar wrote:Also the loaded boot sector might be expecting the cs:ip values to be 0x0000:7C00 not 0x07C0:0000 which might affect some boot sectors.
I changed the JMP to use 0000h:7C00h and that fixed the problem. I'm not sure I quite understand why, since I was using JMP 07C0h:0000h when it was just a single stage loader and that was working fine. Also, the boot-sector I am loading from the HD is one that I have written, and doesn't make any assumptions about CS/IP.
jpshortstuff wrote:I am loading this second stage into 7E00h from the second sector of a FAT12 floppy.
I'm not sure what you're doing here either because I thought the 2nd sector of a FAT12 floppy was usually the first sector of the File Allocation Table? Are you adjusting the reserved sectors value in the BPB?
Hmm, good point, I need to sort that out.

Thanks very much for your help.