admin管理员组

文章数量:1134247

I am trying to write bootloader for hobby OS. I use FASM, genisoimage (via WSL) and VirtualBox. VBox shows "Guru Meditation" error and it`s only 'M' letter on display. Here is a screenshot:

I tried to add delay between showing letters, but it only add "Guru meditation" error (there was no error before that). I`m expected this: it prints 'Maks bootloader', loads kernel and jump to it, and kernel prints 'Hello, world' and go to infinite loop.

Source code of bootloader:

org 0x7c00
use16

start:
    mov ah, 0x0e
    mov al, 'M'
    int 0x10
    call delay
    mov al, 'a'
    int 0x10
    call delay
    mov al, 'k'
    int 0x10
    call delay
    mov al, 's'
    int 0x10
    call delay
    mov al, ' '
    int 0x10
    call delay
    mov al, 'b'
    int 0x10
    call delay
    mov al, 'o'
    int 0x10
    call delay
    mov al, 'o'
    int 0x10
    call delay
    mov al, 't'
    int 0x10
    call delay
    mov al, 'l'
    int 0x10
    call delay
    mov al, 'o'
    int 0x10
    call delay
    mov al, 'a'
    int 0x10
    call delay
    mov al, 'd'
    int 0x10
    call delay
    mov al, 'e'
    int 0x10
    call delay
    mov al, 'r'
    int 0x10
    call delay

    mov ah, 2
    mov al, 1
    mov ch, 1
    mov cl, 2
    mov dh, 0
    mov dl, 0x80
    mov bx, 0x0600
    mov es, bx
    int 0x13
    
    jmp 0x0000:0x0600

times 510-($-$$) db 0
dw 0xAA55

delay:
    mov cx, 0xFFFF
    ret

Here is all info:

I am trying to write bootloader for hobby OS. I use FASM, genisoimage (via WSL) and VirtualBox. VBox shows "Guru Meditation" error and it`s only 'M' letter on display. Here is a screenshot:

I tried to add delay between showing letters, but it only add "Guru meditation" error (there was no error before that). I`m expected this: it prints 'Maks bootloader', loads kernel and jump to it, and kernel prints 'Hello, world' and go to infinite loop.

Source code of bootloader:

org 0x7c00
use16

start:
    mov ah, 0x0e
    mov al, 'M'
    int 0x10
    call delay
    mov al, 'a'
    int 0x10
    call delay
    mov al, 'k'
    int 0x10
    call delay
    mov al, 's'
    int 0x10
    call delay
    mov al, ' '
    int 0x10
    call delay
    mov al, 'b'
    int 0x10
    call delay
    mov al, 'o'
    int 0x10
    call delay
    mov al, 'o'
    int 0x10
    call delay
    mov al, 't'
    int 0x10
    call delay
    mov al, 'l'
    int 0x10
    call delay
    mov al, 'o'
    int 0x10
    call delay
    mov al, 'a'
    int 0x10
    call delay
    mov al, 'd'
    int 0x10
    call delay
    mov al, 'e'
    int 0x10
    call delay
    mov al, 'r'
    int 0x10
    call delay

    mov ah, 2
    mov al, 1
    mov ch, 1
    mov cl, 2
    mov dh, 0
    mov dl, 0x80
    mov bx, 0x0600
    mov es, bx
    int 0x13
    
    jmp 0x0000:0x0600

times 510-($-$$) db 0
dw 0xAA55

delay:
    mov cx, 0xFFFF
    ret

Here is all info: https://drive.google.com/drive/folders/1CTt4-guasEN8I-UCkBmJ6x1TvUTqBcPa?usp=sharing

Share Improve this question asked Jan 8 at 1:29 Maksym SemeniiMaksym Semenii 111 silver badge1 bronze badge New contributor Maksym Semenii is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct. 5
  • For starters, your image is not a multiple of sector size. VBox might not like that. Your delay isn't delaying, you probably forgot a loop or something. But most importantly it is in the second sector which is not even loaded. That's why you only get the first letter. Move it to before the times line. – Jester Commented Jan 8 at 2:08
  • I made some changes but it didn't help (folder change1 on google drive) – Maksym Semenii Commented Jan 9 at 10:20
  • 1 Also note you do mov es, bx so you load to 0x600:0x600 or in the most recent version to 0x8000:0x8000. You want to zero es. Furthermore you hardcode mov dl, 0x80 which may or may not be the correct drive if you boot from ISO. Just use whatever BIOS provided in dl. – Jester Commented Jan 9 at 14:47
  • I made some changes: changed mov es, bx to: xor ax, ax mov es, ax and deleted line mov dl, 0x80, but as before, it is "Guru Meditation" error – Maksym Semenii Commented 2 days ago
  • 1 In your drive the mov dl, 0x80 is still there. Anyway, mov ch, 1 is also wrong, cylinders are numbered from zero. With that it works here. – Jester Commented yesterday
Add a comment  | 

1 Answer 1

Reset to default 2

There are a good number of errors but the most important one is that the delay routine is outside the 1 sector that BIOS loads to the memory at address 0x7C00. Your call delay arrives at an address where there is nothing to execute!

The lines times 510-($-$$) db 0 and dw 0xAA55 are at the bottom of that single 512-bytes sector that BIOS loads for you. All the rest you must load yourself.
The quick solution is to put the delay routine before those famous last two lines.

I tried to add delay between showing letters,

The code:

delay:
 mov cx, 0xFFFF
 ret

will not delay in the sense that you expect it. You most probably wanted to create a loop that runs about 64KB times. In FASM you can write the following:

delay:
 xor  cx, cx
 loop $
 ret

But unless you can slow down the emulator, this too will finish in less than the blink of an eye!
Alternatively, you could replace each of your call delay instructions by loop $, shaving off a lot of bytes.

The part that tries to load the one-sector kernel exhibits a few problems:

  • The cylinder number is probably wrong: specifying a sector number of 2, logically one would expect to find the kernel on the same cyclinder as the bootsector and that is cylinder 0.
  • You should not hardcode the drivenumber to be 0x80. BIOS gave you the correct drivenumber in the DL register upon starting your bootloader. Use it.
  • The way you have initialized the ES:BX far pointer is not in accordance with how you jump to it through jmp 0x0000:0x0600. You need to set ES to zero.
  • Sometimes loading a sector fails. So, you should inspect the carry flag that BIOS returns to you, and maybe display a suitable error message followed by entering an infinite loop:
  mov  ah, 2      ; Function number
  mov  al, 1      ; Count
  mov  ch, 0      ; Cylinder
  mov  cl, 2      ; Sector
  mov  dh, 0      ; Head
  xor  bx, bx     ; Buffer at 0x0000:0x0600
  mov  es, bx
  mov  bx, 0x0600
  int  0x13
  jc   error
  jmp  0x0000:0x0600
error:
  ...             ; Show an error message
  jmp  $          ; Infinite loop

There's room to optimize this further (like outputting from a loop instead of those many separate teletypes), but you should first concentrate on getting it work...


Following the OP's comment, I'm not sure whether VBOX's Teletype respects to not clobber the AX register. Try next way of outputting the message:

org 0x7C00
use16

start:
  xor  cx, cx
  mov  ds, cx
  mov  ss, cx
  mov  sp, 0x7C00
  push dx         ; Preserve bootID

  mov  si, msg
  mov  bx, 0x000F
  cld
  lodsb
more:
  mov  ah, 0x0E   ; BIOS.Teletype
  int  0x10
  loop $          ; Tiny delay
  lodsb
  cmp  al, 0
  jne  more

  pop  dx         ; Restore bootID
  mov  ax, 0x0201 ; Function number and Count
  mov  cx, 0x0002 ; Cylinder and Sector
  mov  dh, 0      ; Head
  xor  bx, bx     ; Buffer at 0x0000:0x8000
  mov  es, bx
  mov  bx, 0x8000
  int  0x13
  jc   error
  jmp  0x0000:0x8000
error:
  ...             ; Show an error message
  jmp  $          ; Infinite loop

msg db 'Maks bootloader'

times 510-($-$$) db 0
dw 0xAA55

本文标签: assemblyquotGuru Meditationquot error in VBox with custom bootloaderStack Overflow