Page 1 of 1

bootloader freezing problem

Posted: Sat Apr 24, 2010 11:45 pm
by assainator
after having fun in the 32-bit world I came back to the bootloader stage since I really wanted to have my own bootloader with my own filesystem instead of using GRUB.

but for some reason, at one punt my bootloader just freezes. And i can't find the problem.

i'm using bochs and nasm

my code

Code: Select all

org 0

mov [drive], dl

start:
  cli
  ;setup segments
  mov ax, 0x07c0
  mov ds, ax
  mov es, ax
  mov fs, ax
  mov gs, ax
  mov ss, ax
  
  
  ;setup stack
  mov sp, [stack_end]
  sti

; now read the lafs table
read_lafs_tbl:
  mov ah, 0x02 ; we should read
  mov al, 0x01 ; read one sector
  mov ch, 0x00 ; read from cilinder 0x0
  mov cl, 0x02 ; we want to start reading at sector 0x01
  mov dh, 0x00 ; we want to read from the first head (0x0)
  mov dl, [drive] ; we want to read from drive 0x0
  
  
  mov bx, 0x0
  mov es, bx
  mov bx, 0x02000

int 0x013
;jc read_lafs_tbl


;;;;; ==>> now we need to find the stage2 name <<== ;;;;;;;;;
mov     cx, WORD [LAFS_fileCount]             ; load loop counter
mov     di, 0x02000                            ; locate first entry
.loop:
  push    cx
  mov     cx, 0x0008                          ; eigth character name
  mov     si, stage2_name                     ; image name to find
  push    di
  rep  cmpsb                                  ; test for entry match
  pop     di
  je      load_stage2
  pop     cx
  add     di, 17                          ; queue next entry
loop    .loop
mov     si, stage2_no_find
jmp     error


  
load_stage2:
  mov si, di
  
  ;get the start sector
  mov ax, [si+15]
  mov [good_location] ,ax
  
  ;convert the start sector to CHS
  call LBA2CHS
  
  ;now calculate the size of stage2 (it is assembled with 512 alignment)
  mov di, [good_location]
  mov ax, [di-2]
  mov bx, 512
  div bx
  mov [stage2_sector_count], ax
  
  
  ;now print everything
  
  ;the start sector
  mov si, sector_str
  call print_string
  
  xor ax, ax
  mov al, [stage2_start_sector]
  call print_ax_bin
  
  
  
  ;the sector count
  mov si, sector_count_str
  call print_string

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; It freezes here! ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  
  mov ah, 0x0
  mov al, [stage2_sector_count]
  call print_ax_bin
  
  
  
  ;the track number
  mov si, track_str
  call print_string
  
  mov ah, 0x0
  mov al, [stage2_cilinder]
  call print_ax_bin
  
  
  
  ;the head number
  mov si, head_str
  call print_string
  
  mov ah, 0x0
  mov al, [stage2_head]
  call print_ax_bin
  
  
  ;pause
  jmp $

  


;;;;; =>> Functions <== ;;;;;;;
LBA2CHS:
  pusha
  
  mov ax, [good_location]
  mov dl, 18
  div dl
  add bx, 1
  mov [stage2_start_sector], bl
  
  mov ax, [good_location]
  mov bl, 18
  div bl
  mov [stage2_cilinder], bl
  
  mov [stage2_head], al
  
  popa
  ret
  
  
;Sector = (LBA/SectorsPerTrack) Remainder value + 1
;Cylinder = (LBA/SectorsPerTrack)/NumHeads (Take Remainder value)
;Head = (LBA/SectorsPerTrack)/NumHeads (Take quotient value)
    

error:
  mov si, kernel_error
  call print_string
  
  call print_ax_bin
  
  jmp $


print_string:
  pusha
  lodsb
  cmp al, 0
  jz .done
  
  mov ah, 0x0e
  int 0x10
  
  jmp print_string

  .done:
    popa
    ret


print_ax_bin: 
  pusha
  ; print result value in binary:
  mov cx, 16
  mov bx, ax
  .print:
    mov ah, 0x0e   ; print function.
    mov al, '0'
    test bx, 1000000000000000b  ; test first bit.
    jz .zero
    mov al, '1'
    
  .zero:
    int 0x10
    shl bx, 1
  loop .print      
  ; print binary suffix:
  mov al, 'b'
  int 0x10  
  popa  
  ret


kernel_error db 13, 10, "Read err",13, 10,0
stage2_name db "stage2  "
found_stage2 db "Found stage2", 0
stage2_no_find db 13, 10, "Couldn't find stage2",13, 10,0
loc_kern db 13, 10, "Looking for kernel",0
newline db 13, 10, 0
sector_str db 13, 10, "sector: ",0
sector_count_str db 13, 10, " ->count: ",0
head_str db 13, 10, "head: ",0
track_str db 13, 10, "track: ",0


; fill the rest with zero's
times 497 - ($-$$) db 0

; LaFS superblock
LAFS_magic db "LAFS"
LAFS_version db 0x02
LAFS_bytesPerBlock dw 512
LAFS_SizeOfTable db 0x01
LAFS_hiddenBlocks db 0x01
LAFS_fileCount dw 0x04
LAFS_volumeSize dw 2880

dw 0xaa55

section .bss

stack_begin:
    resb 4096  ; Reserve 4 KiB stack space
stack_end:

drive:
  resb 1

good_location:
  resb 2

stage2_start_sector:
  resb 1

stage2_cilinder:
  resb 1

stage2_head:
  resb 1

stage2_sector_count:
  resb 1

Re: bootloader freezing problem

Posted: Sat Apr 24, 2010 11:59 pm
by HitmanYesman
I think the stack is corrupted at some point in the code. Just an educated guess.

Re: bootloader freezing problem

Posted: Sun Apr 25, 2010 1:21 am
by xenos
Indeed, it's a stack corruption problem in print_string. At the beginning of this function, you do a pusha, then output a character, jump back to the beginning of the function, pusha again... I guess you get the point.

Re: bootloader freezing problem

Posted: Sun Apr 25, 2010 1:31 am
by assainator
Thanks, that solved it!

assainator