Int13h AH=42h Boot From Hard Drive just fails [Solved]
Posted: Sun Jun 07, 2009 5:35 am
Hi!
I'm working an a project of an OS, but gotten stuck with the bootsector code.
Problem: Bootsector fails to load 2nd stage loader.
It's designed for NTFS partitions, it's supposed to load some number of sectors immediately following it on the partition. But Int13h AH=42h returns AH=1 with CF set. Couldn't figure out why so far.
Here's the code that fails:
How to reproduce: Compile with NASM -f bin and run in QEMU or even on real hardware, same thing. The output binary file is supposed to be pasted into an NTFS bootsector at offset 0x54.
Please give your perspective. Slap me if this has been answered somewhere before
I'm working an a project of an OS, but gotten stuck with the bootsector code.
Problem: Bootsector fails to load 2nd stage loader.
It's designed for NTFS partitions, it's supposed to load some number of sectors immediately following it on the partition. But Int13h AH=42h returns AH=1 with CF set. Couldn't figure out why so far.
Here's the code that fails:
Code: Select all
;/*
;* bootldr.asm *
;* NTFS-specific *
;* Bootsector is supposed to start with EB 52 *
;*/
org 7C54h
;NTFS Bootsector Structures
[section .bpb]
absolute 7C1Ch
BPB_HiddSec resd 1
absolute 7C28h
ExtBPB_TotalSectors resq 1
ExtBPB_$MFTCluster resq 1
ExtBPB_$MFTMirrCluster resq 1
ExtBPB_FileRecordSize resd 1
ExtBPB_IndexBlockSize resd 1
ExtBPB_SerialNumber resq 1
ExtBPP_Checksum resd 1
;My bootsector code
[section .code align=2]
start:
xor ax,ax
mov ds,ax
mov es,ax
cli
mov ss,ax
mov sp,7C00h
sti
push first_message
call print_string
push word (bootldr_end - sector1)/512 + 1 ;evaluates to 1
push word sector1 ;offset
push ds ;segment
push dword [BPB_HiddSec] ;LBA
call load_sectors
jmp sector1
;/*
;* Realmode Int13h AH=42h sector loading routine *
;*/
load_sectors:
push bp
mov bp,sp
%define lba (bp+4)
%define seg (bp+8)
%define ofs (bp+10)
%define nsect (bp+12)
push dword 0
push dword [lba] ;LBA
push word [seg] ;segment
push word [ofs] ;offset
push word [nsect] ;number of sectors
push word 10h ;10h, 0h.
mov ah,42h
mov si,sp
mov dl,80h
int 13h
jc os_failure
test ah,ah
jnz os_failure
leave
retn 10
os_failure:
push fail_message
call print_string
mov al,ah
call print_al
xor ax,ax
int 16h
int 19h
;Text messages
first_message db "Hi! I'm a boot sector! Let's start up...",13,10,0
fail_message db "Didn't even make it past the bootsector. Goodbye ;(",13,10
db 'INT13 Failed with AH=',0
;<here are some printing routines for debug>
;/*
;* Realmode printing routine *
;*/
print_string:
mov bp,sp
mov si,word [bp+2]
pusha
mov ah,0Eh
cld
.print_loop:
lodsb
test al,al
jz .end_print
int 10h
jmp short .print_loop
.end_print:
popa
retn 2
times 510-54h-($-$$) db 0
db 55h,0AAh
;======================================== The End of Sector 0
; The Start of Sector 1 ======================================
sector1:
push message2
call print_string
xor ax,ax
int 16h
int 19h
;/* TODO:
;* -) Parse the NTFS root dir for Kernel.exe
;* -) Load it up above 1 Mb using INT13h AH=42h
;* -) Set up basic PM
;* -) Jump to KernelEntry()
;*/
message2 db "Ok, let's load the Kernel.exe and set up PM",0
bootldr_end:
Please give your perspective. Slap me if this has been answered somewhere before