easy2mem 0 Newbie Poster

Hi. I have been working so hard to write this second stage loader but I cannot for the life of me figure out why it is not working. In my second stage loader it does not seem to load my kernel from disk. I have a view test points where some text should show on screen.

01: When it fails
02: When it finds the kernel
03: When it loads stage 2

I see the verbiage for when the stage 2 loader begins but not the fail or found kernel verbiage. It appears as if it starts to read my disk then stops and then halts for no reason. Here is my linker script where my goal is to load the kernel according to this script:

OUTPUT_FORMAT("binary")
ENTRY(start)
phys = 0x00100000;
SECTIONS
{
  .text phys : AT(phys) {
    code = .;
    *(.text)
    *(.rodata)
    . = ALIGN(4096);
  }
  .data : AT(phys + (data - code))
  {
    data = .;
    *(.data)
    . = ALIGN(4096);
  }
  .bss : AT(phys + (bss - code))
  {
    bss = .;
    *(.bss)
    . = ALIGN(4096);
  }
  end = .;_end = .; __end = .;
}

and here is the full code of my non-working stage 2:

;******
;Stage 2
;******
[BITS 16]

org 0x1000

; jump to the code
boot:   jmp start
      nop

bpbOEM          db  'WHITE OS'
bpbSectSize     dw  512
bpbClustSize    db  1
bpbReservedSec  dw  1
bpbFats         db  2
bpbRootSize     dw  224
bpbTotalSect    dw  2880
bpbMedia        db  240
bpbFatSize      dw  9
bpbTrackSect    dw  18
bpbHeads        dw  2
bpbHiddenSect   dd  0
bpbLargeSect    dd  0
bpbDriveNo      db  0
bpbReserved     db  0
bpbSignature    db  0

strings:
.mesg: db "Insert disk 02, then hit any key to continue . . .",0x0
.filename: db  "KERNEL     ",0x0
.failure: db  "Read error!",0x0
.found: db  "kernel found!",0x0

; here begins data
; static-build gdt
gdt:

; selector 0 is reserved and is the null selector
gdt_null:
   dd 0x00000000
   dd 0x00000000

; selector 8 is the big code selector
gdt_code:
   dw 0xFFFF
   dw 0x0000
   db 0x00
   db 10011010b
   db 11001111b
   db 0x00

; selector 10 is the big data selector
gdt_data:
   dw 0xFFFF
   dw 0x0000
   db 0x00
   db 10010010b
   db 11001111b
   db 0x00

; used to calculate the size of gdt
gdt_end:

; the gdt descriptor
gdt_desc:
   dw gdt_end - gdt - 1
   dd gdt

; the true start of the code
start:
   mov ax, 0x0000
   mov ds, ax
   mov si, strings.mesg
   mov ah, 0x0e

.loop:
   mov al, [ds:si]
   cmp al, 0x00
   jz load_kernel
   int 0x10
   inc si
   jmp .loop
      
load_kernel:
   mov ah, 0
    int 16h     ;Wait for keypress

   ;finish loading the kernel
   cli                  ;disable interrupts
   
   xor     ax, ax                              ; initialize all the necessary
   mov     ds, ax                              ; registers.
   mov     es, ax
   mov     ss, ax
   mov     sp, 0xFFFF                          ; Stack..

   mov     [bpbDriveNo], dl

   sti
   
   mov     di, 0x0050                          ; Load the root to
   mov     ax, 19                              ; 0x0000:0x0500 (0x500/0x10)
   mov     cx, 14
   call    read_sectors

   mov     di, 0x0210                          ; Load the fat to
   mov     ax, 1                               ; 0x0000:0x2100
   mov     cx, 9
   call    read_sectors
   
read_sectors:
   pusha
   mov     bl, byte [bpbTrackSect]             ; bl = number of sectors per track
   div     bl                                  ; al = ax / bl
   mov     cl, ah                              ; cl = real sector number
   add     cl, 1

   xor     ah, ah                              ; del the rest of the div before
   mov     bl, byte [bpbHeads]                 ; bl = number of heads
   div     bl                                  ; ah = rest of ( ax / bx ), al = ax / bx
   mov     ch, al                              ; ch = number of track
   mov     dh, ah                              ; dh = the head number

   mov     ax, cx                              ; save cx in ax
   mov     cx, 6                               ; try it 6 times
   .next_try:
   push    es
   push    cx
   mov     cx, ax                              ; restore cx
   push    cx

   xor     ax, ax
   mov     dl, [bpbDriveNo]                    ; reset drive
   push    dx
   int     0x13
   jc      .failed

   pop     dx
   pop     cx
   xor     bx, bx
   mov     es, di
   mov     ax, 0x0201                          ; function 2, 1 sector
   int     0x13
   jnc     .ok                                 ; if it was ok, check next..

   .failed:
   pop     dx
   pop     ax

   pop     cx
   pop     es
   loop    .next_try                           ; else try once again if there is an error
   jmp     error                               ; if cx = 0 and the read operation always failed, halt
   .ok:
   pop     cx                                  ; from the next_try loop
   pop     es
   popa
   add     di, 32                              ; add 32 (512/16) to segment
   inc     ax                                  ; add sector counter
   loop    read_sectors
   ret

error:
   mov ax, 0x0000
   mov ds, ax
   mov si, strings.failure
   mov ah, 0x0e

.loop:
   mov al, [ds:si]
   cmp al, 0x00
   jz waitn
   int 0x10
   inc si
   jmp .loop
   
waitn:
   mov     ah, 0
   int     0x16
   int     0x19

;------------------------;
;  search for the file   ;
;------------------------;
   mov     dx, [bpbRootSize]
   mov     bx, 0x0500
   filesearch:
   cld
   mov     si, strings.filename
   mov     cx, 11
   mov     di, bx
   repe    cmpsb
   je      found
   add     bx, 32
   dec     dx
   jz      error
   jmp     filesearch

;-----------------------------------;
;   the file is found, load it.     ;
;-----------------------------------;
found:
   mov ax, 0x0000
   mov ds, ax
   mov si, strings.found
   mov ah, 0x0e

.loop:
   mov al, [ds:si]
   cmp al, 0x00
   jz donext
   int 0x10
   inc si
   jmp .loop
   mov     bp, [bx+26]                         ; bp=cluster number from directory entry
   mov     di, 0x1000                          ; 1000 (segment)
donext:
   .next_block:
   xor     cx, cx
   mov     cl, [bpbClustSize]                  ; reset sector count to 1 cluster
   mov     si, bp                              ; si=next should-be cluster for
                                   ; contiguous reads
   .next_contiguous:
   mov     ax, 3                               ; 3
   mul     si                                  ; multiply cluster number by 3
                                   ; dx assumed to be 0, it's a floppy!
   shr     ax, 1                               ; divide by two
   push    bp
   xchg    bp, ax                              ; bp=ax
   mov     ax, word [0x2100+bp]                ; ax=FAT element with junk
                                   ; (addressing with bp)
   pop     bp
   jc     .odd_cluster                   ; jump if the value was odd

   .even_cluster:
   and     ax, 0x0FFF                          ; leave only lower 12 bits
   jmp     .got_cluster                        ; got it

   .odd_cluster:
   push    cx                                  ; preserve sector count
   mov     cl, 4                               ; shift four bits right
   shr     ax, cl                              ; (leave only bits 4-15)
   pop     cx                                  ; restore sector count

   .got_cluster:
   inc     si                                  ; si=current cluster+1
   cmp     ax, si                              ; next cluster=current cluster+1?
   jne    .force_read                    ; is it still contiguous?

   add     cl, [bpbClustSize]                  ; increase sector count by 1 cluster
   adc     ch, 0
   jmp     .next_contiguous

   .force_read:
   xchg    bp, ax                              ; ax=bp (base cluster), bp=new cluster
   dec     ax                                  ; decrease by 2 to get the actual... (1)
   dec     ax                                  ; ...cluster number (2)

   xor     dx, dx
   mov     dl, [bpbClustSize]
   mul     dx                                  ; multiply by sectors per cluster
                                   ; (dx ignored)
   add     ax, 33                              ; assume data-area start at sector 33
   call    read_sectors                        ; read cx sectors at ax to es:0 :)

   cmp     bp, 0x0FF8                          ; the new cluster is EOF (FF8-FFF)?
   jb      .next_block                    ; if not in this range, read next block
   
   ;load a20
   xor cx, cx            ;clear the CX register
   clear_buf:
   in al, 64h              ; Get input from keyboard status port
   test al, 02h            ; Test the buffer full flag
   loopnz clear_buf        ; Loop until buffer is empty
   mov al, 0D1h            ; Keyboard: write to output port
   out 64h, al             ; Output command to keyboard
   clear_buf2:
   in al, 64h              ; Wait 'till buffer is empty again
   test al, 02h
   loopnz clear_buf2
   mov al, 0dfh            ; Keyboard: set A20
   out 60h, al             ; Send it to the keyboard controller
   mov cx, 14h
   wait_kbc:                       ; This is approx. a 25uS delay to wait
   out 0edh, ax            ; for the kb controler to execute our
   loop wait_kbc           ; Command.

   xor ax, ax
   mov ds, ax              ; Set DS-register to 0 - used by lgdt
   lgdt [gdt_desc]         ; Load the GDT descriptor

; set cr0.1 to 1 to switch to protected mode
   mov eax, cr0
   or eax, 1
   mov cr0, eax

; jump to new code zone to really switch to protected mode
   jmp 0x08: pmode

; here we are in 32-bit protected mode
[BITS 32]
pmode:
   ; cs is already set. we set ds to data zone and es to vdeo zone. we also setup
   ; ss for c layer
   mov ax, 10h             ; Save data segment identifyer
   mov ds, ax              ; Move a valid data segment into the data segment register
   mov ss, ax              ; Move a valid data segment into the stack segment register
   mov esp, 0xfffc        ; Move the stack pointer
   
   ;jmp $
   
   jmp 0x08:0x100000         ; Jump to section 08h (code)

times ( 1024 - ( $ - $$ ) ) db 0x00

please any help is greatly appreciated.