Home > Software design >  FASM bootloader in bochs hlp
FASM bootloader in bochs hlp

Time:10-02

I was trying to write my own bootloader on fasm assembly, but unsucces.

Result: Prefetch: EIP 00010000 > CS.limit 0000ffff

Code:

org 0x7C00

mov ax, 0x02

int 0x10

mov si, boot_msg

call printf

mov al, 0x01 ; secror to read
mov bx, 0x7E00 ; dest
mov cx, 0x0002 ; cylinder:sector
mov dl, 0x01 ; floppy
call disk_read

mov ax, 0x7E00
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp 0x7E00:0x0000

include 'disk.asm'
include 'printh.asm'

boot_msg db 'R-OS BOOTLOADER       
              ',\
'KERNEL CHS 0 0 1', 0x00

times 510-$ $$ db 0x00
dw 0xAA55
;;;;;;;;; kernel! ;;;;;;;;;;
org 0x7E00

mov ah, 0x0E
mov al, 'X'
int 0x10
cli hlt

times 4096-512-$ $$ db 0x00

disk.asm:

disk_read:
  pusha
  mov si, 0x02
.top:
  mov ah, 0x02
  int 0x13
  jnc .end
  xor ah, ah
  int 0x13
  jnc .top
  jc .err
.end:
  popa
  ret
.msg db 'disk rw err', 0x00
.err:
  popa
  pusha
  mov ah, 0x0E
  mov si, .msg
  jmp .l
.l:
  lodsb
  cmp al, 0x00
  je .end
  int 0x10

printh.asm just have print functions.

I cant understand, why it is doesn't work. I was trying a lot of variants of solve, but not one working in this list.

please, help

CodePudding user response:

To successfully use the BIOS.ReadSectors function 02h, you need to setup all its parameters! You didn't initialize the ES segment register, nor did you specify the head number in the DH register. Presumably you think that all registers start out with zero, but this is not the case! The only register that your bootloader receives is the DL register that holds the number for the boot drive. That will be the number that you need to provide to this function.

You are loading the additional sector at offset address 0x7E00. Because ES=0 (assuming), this is segmented address 0x0000:0x7E00. You can jmp to this address in a number of ways, but if you want to do it with a zero offset, then the segment part will have to be 0x07E0. That's how segmentation works.

You can read more about bootloaders in my answer at (https://stackoverflow.com/questions/34216893/disk-read-error-while-loading-sectors-into-memory/34382681?r=SearchResults&s=21|9.2814#34382681) and in Michael Petch's answer at (https://stackoverflow.com/questions/32701854/boot-loader-doesnt-jump-to-kernel-code/32705076?r=SearchResults&s=46|10.4269#32705076).

This is an improved version:

ORG  0x7C00

xor  ax, ax     ; Setup segment registers in accordance with the `ORG 0x7C00`
mov  ds, ax
mov  es, ax
mov  ss, ax
mov  sp, 0x7C00
cld             ; Once at the top of every program

mov  ax, 0x0003
int  0x10

mov  si, boot_msg
call printf

mov  al, 1      ; Number of sectors to read
mov  bx, 0x7E00 ; ES:BX
mov  cx, 0x0002 ; Cylinder, Sector
mov  dh, 0      ; Head, DL is bootdrive
call disk_read

mov  ax, 0x07E0 ; How segmentation works!
mov  ds, ax
mov  es, ax
jmp  0x07E0:0x0000

include 'disk.asm'
include 'printh.asm'

boot_msg db 'R-OS BOOTLOADER       
              ',\
'KERNEL CHS 0 0 1', 0

times 510-($-$$) db 0
dw 0xAA55
;;;;;;;;; kernel! ;;;;;;;;;;
ORG  0x7E00

mov  bh, 0        ; Don't forget to mention the DisplayPage
mov  ah, 0x0E
mov  al, 'X'
int  0x10

cli
hlt
jmp  $-2

times 4096-512-($-$$) db 0

In the disk.asm file, you are trying to implement a retry count, but you forget to actually decrement the counter if an error occured.
Also if you display an error message here, it's kinda fatal, so make the code halt.

Again an improved version:

disk_read:
  pusha
  mov  si, 5     ; Retry count
.top:
  mov  ah, 0x02
  int  0x13
  jnc  .OK
  mov  ah, 0x00
  int  0x13
  dec  si
  jnz  .top      ; More tries
  jmp  .fatal
.OK:
  popa
  ret

.msg db 'disk rw err', 0

.fatal:
  mov  bh, 0        ; Don't forget to mention the DisplayPage
  mov  ah, 0x0E
  mov  si, .msg
  lodsb
.next:
  int  0x10
  lodsb
  cmp  al, 0
  jne  .next

  cli
  hlt
  jmp  $-2

printh.asm just have print functions.

It is important to include as much information as possible! In my above improved code I assumed that printf does not destroy the DL register. Please make sure it preserves at least DX.
If you would have included the code in the printh.asm file, I would have verified this already for you...

  • Related