Page 1 of 2

Bootloader jumps to kernel, but its code isn't executed.

Posted: Thu Mar 27, 2014 11:15 am
by Roman
My previous mistake was attempting to pass seek=512 to dd instead of seek=1, but now I have another problem.

My boot.S:

Code: Select all

	section .text
	use16
	org 0x7C00  ; Load address.

start:
	mov ax, cs
	mov ds, ax ; Select data segment.

	mov ah, 00h ; Set video mode.
	mov al, 2
	int 0x10

    mov ah, 13h ; Print boot message.
	mov al, 1
	mov bh, 0
	mov bl, 0_7h
	mov cx, rst_fd_msg_len
	mov dh, 0
	mov dl, 0
	mov bp, rst_fd_msg
	int 0x10

    mov ah, 0 ; Reset floppy.
    int 0x13
    jc error

    mov ah, 13h
    mov bl, 0_7h
    mov cx, kern_load_msg_len
    inc dh
    mov bp, kern_load_msg
    int 0x10

    mov ah, 2
    mov al, 1
    mov ch, 0
    mov cl, 2
    mov dh, 0
    mov bx, 0x1000
    mov dl, 0
    int 0x13
    jc error

    jmp 0x1000


error:
    mov ah, 00h
    mov al, 2
    int 0x10

    mov ah, 13h
    mov bl, 0_4h
    mov cx, error_msg_len
    mov dh, 0
    mov dl, 0
    mov bp, error_msg
    int 0x10

    jmp not_n_hlt


not_n_hlt:
    mov ah, 13h ; Notify and halt.
    mov bl, 0_7h
    mov cx, cpu_hlt_msg_len
    inc dh
    inc dh
    mov dl, 0
    mov bp, cpu_hlt_msg
    int 0x10

    cli
    hlt


cpu_hlt_msg db "CPU halted."

cpu_hlt_msg_len equ $-cpu_hlt_msg


error_msg db "Critical error occured, cannot continue."

error_msg_len equ $-error_msg


rst_fd_msg db "Resetting fd0."

rst_fd_msg_len equ $-rst_fd_msg


kern_load_msg db "Loading kernel."

kern_load_msg_len equ $-kern_load_msg


finish:
	times 0x1FE-finish+start db 0
	db   0x55, 0xAA ; Boot signature
kernel.S:

Code: Select all

    section .text
    use16

start:
    mov ah, 00h ; Set video mode.
	mov al, 2
	int 0x10

    mov al, 1
    mov bh, 0
    mov bl, 0_7h
    mov cx, kern_start_msg_len
    mov dh, 3
    mov dl, 0
    mov bp, kern_start_msg
    int 0x10

    jmp endless_loop


endless_loop:
    jmp $


kern_start_msg db "Kernel started."

kern_start_msg_len equ $-kern_start_msg

finish:
	times 0x1FE-finish+start db 0
boot.bin hex dump (via hexdump utility):

Code: Select all

0000000 8c c8 8e d8 b4 00 b0 02 cd 10 b4 13 b0 01 b7 00
0000010 b3 07 b9 0e 00 b6 00 b2 00 bd a9 7c cd 10 b4 00
0000020 cd 13 72 26 b4 13 b3 07 b9 0f 00 fe c6 bd b7 7c
0000030 cd 10 b4 02 b0 01 b5 00 b1 02 b6 00 bb 00 10 b2
0000040 00 cd 13 72 05 e9 b8 93 eb 18 b4 00 b0 02 cd 10
0000050 b4 13 b3 04 b9 28 00 b6 00 b2 00 bd 81 7c cd 10
0000060 eb 00 b4 13 b3 07 b9 0b 00 fe c6 fe c6 b2 00 bd
0000070 76 7c cd 10 fa f4 43 50 55 20 68 61 6c 74 65 64
0000080 2e 43 72 69 74 69 63 61 6c 20 65 72 72 6f 72 20
0000090 6f 63 63 75 72 65 64 2c 20 63 61 6e 6e 6f 74 20
00000a0 63 6f 6e 74 69 6e 75 65 2e 52 65 73 65 74 74 69
00000b0 6e 67 20 66 64 30 2e 4c 6f 61 64 69 6e 67 20 6b
00000c0 65 72 6e 65 6c 2e 00 00 00 00 00 00 00 00 00 00
00000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
00001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa
0000200
kernel.bin hex dump (also via hexdump):

Code: Select all

0000000 b4 00 b0 02 cd 10 b0 01 b7 00 b3 07 b9 0f 00 b6
0000010 03 b2 00 bd 1c 00 cd 10 eb 00 eb fe 4b 65 72 6e
0000020 65 6c 20 73 74 61 72 74 65 64 2e 00 00 00 00 00
0000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
00001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00      
00001fe
floppy.img hex dump:

Code: Select all

0000000 8c c8 8e d8 b4 00 b0 02 cd 10 b4 13 b0 01 b7 00
0000010 b3 07 b9 0e 00 b6 00 b2 00 bd a9 7c cd 10 b4 00
0000020 cd 13 72 26 b4 13 b3 07 b9 0f 00 fe c6 bd b7 7c
0000030 cd 10 b4 02 b0 01 b5 00 b1 02 b6 00 bb 00 10 b2
0000040 00 cd 13 72 05 e9 b8 93 eb 18 b4 00 b0 02 cd 10
0000050 b4 13 b3 04 b9 28 00 b6 00 b2 00 bd 81 7c cd 10
0000060 eb 00 b4 13 b3 07 b9 0b 00 fe c6 fe c6 b2 00 bd
0000070 76 7c cd 10 fa f4 43 50 55 20 68 61 6c 74 65 64
0000080 2e 43 72 69 74 69 63 61 6c 20 65 72 72 6f 72 20
0000090 6f 63 63 75 72 65 64 2c 20 63 61 6e 6e 6f 74 20
00000a0 63 6f 6e 74 69 6e 75 65 2e 52 65 73 65 74 74 69
00000b0 6e 67 20 66 64 30 2e 4c 6f 61 64 69 6e 67 20 6b
00000c0 65 72 6e 65 6c 2e 00 00 00 00 00 00 00 00 00 00
00000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
00001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa
0000200 b4 00 b0 02 cd 10 b0 01 b7 00 b3 07 b9 0f 00 b6
0000210 03 b2 00 bd 1c 00 cd 10 eb 00 eb fe 4b 65 72 6e
0000220 65 6c 20 73 74 61 72 74 65 64 2e 00 00 00 00 00
0000230 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
00003f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00      
00003fe
QEMU memory at 0x1000 hex dump:

Code: Select all

0000000 b4 00 b0 02 cd 10 b0 01 b7 00 b3 07 b9 0f 00 b6
0000010 03 b2 00 bd 1a 00 cd 10 fa f4 4b 65 72 6e 65 6c
0000020 20 73 74 61 72 74 65 64 2e 00 00 00 00 00 00 00
0000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
0000200
It looks like kernel is loaded, but not executed, why?

Also video mode was changed. (blinking cursor began much bigger)

Before I added

Code: Select all

jmp 0x1000
boot.S messages stayed on screen.

What I expected: screen is cleared after jumping to 0x1000, message "Kernel started." appeared.
What I got: screen is cleared, but message didn't appear, cursor became very big.

EDIT: figured out, that boot loader really jumps to 0x1000, but something wrong happens next.

PS. Tell me if my english is bad, it's not my native language.

Re: Bootloader jumps to kernel, but its code isn't executed.

Posted: Thu Mar 27, 2014 12:32 pm
by DavidCooper
Roman wrote:

Code: Select all

    mov al, 1
    mov bh, 0
    mov bl, 0_7h
    mov cx, kern_start_msg_len
    mov dh, 3
    mov dl, 0
    mov bp, kern_start_msg
    int 0x10
What have you not done here that you did every other time you printed? Ah!

Re: Bootloader jumps to kernel, but its code isn't executed.

Posted: Thu Mar 27, 2014 12:49 pm
by Roman
DavidCooper wrote:
Roman wrote:

Code: Select all

    mov al, 1
    mov bh, 0
    mov bl, 0_7h
    mov cx, kern_start_msg_len
    mov dh, 3
    mov dl, 0
    mov bp, kern_start_msg
    int 0x10
What have you not done here that you did every other time you printed? Ah!
Thank you, but now it prints very strange characters.

Re: Bootloader jumps to kernel, but its code isn't executed.

Posted: Thu Mar 27, 2014 12:55 pm
by DavidCooper
Roman wrote:Thank you, but now it prints very strange characters.
Which segment do you think it's reading the message from?

Re: Bootloader jumps to kernel, but its code isn't executed.

Posted: Thu Mar 27, 2014 1:05 pm
by Roman
DavidCooper wrote:
Roman wrote:Thank you, but now it prints very strange characters.
Which segment do you think it's reading the message from?
From the first one? CPU is still in real mode at the stage of kernel.

PS. I am new to low-level programming.

Re: Bootloader jumps to kernel, but its code isn't executed.

Posted: Thu Mar 27, 2014 1:13 pm
by DavidCooper
Roman wrote:
DavidCooper wrote:
Roman wrote:Thank you, but now it prints very strange characters.
Which segment do you think it's reading the message from?
From the first one? CPU is still in real mode at the stage of kernel.

PS. I am new to low-level programming.
I misremembered how the int 13h thing works - thought you were loading to a different segment. The problem may be a missing org statement then. It looks as if it's failing to line up on the message you're trying to print.

Re: Bootloader jumps to kernel, but its code isn't executed.

Posted: Thu Mar 27, 2014 1:24 pm
by Roman
Thank you very much, it works!

Re: Bootloader jumps to kernel, but its code isn't executed.

Posted: Thu Mar 27, 2014 1:29 pm
by DavidCooper
Roman wrote:Thank you very much, it works!
That's good. The mov bp part was lining up on 001c (bd 1c 00) instead of 101c.

Re: Bootloader jumps to kernel, but its code isn't executed.

Posted: Thu Mar 27, 2014 5:24 pm
by Roman
DavidCooper wrote:
Roman wrote:Thank you very much, it works!
That's good. The mov bp part was lining up on 001c (bd 1c 00) instead of 1000h.
Why does

Code: Select all

mov ax, 0xee
make CPU halt?

Re: Bootloader jumps to kernel, but its code isn't executed.

Posted: Thu Mar 27, 2014 11:55 pm
by Antti
Roman wrote:Why does

Code: Select all

mov ax, 0xee
make CPU halt?
According to CPU manuals, this instruction ("mov r16, imm16") in itself does not halt or trigger exceptions. If this instruction seems to halt code execution, there is a problem elsewhere. Are you sure that it is this instruction that halts and not the previous one?

Re: Bootloader jumps to kernel, but its code isn't executed.

Posted: Fri Mar 28, 2014 12:20 am
by Brendan
Hi,

Here's a list of some bugs:
  • You can't assume that (when BIOS starts your code) CS is zero. BIOS can do "jmp 0x0000:0x7C00" or "jmp 0x07C0:0x0000" or anything else. This means that copying CS into DS is a bad idea. It also means that "jmp 0x1000" could jump anywhere (e.g. to 0x07C0:0x1000 and not to 0x0000:0x1000).
  • The BIOS function to read sectors will read those sectors to the address specified in ES:BX. The ES segment register is never set to anything, therefore the BIOS could load the sectors anywhere.
  • When the BIOS starts your code the stack is wherever the BIOS felt like leaving it. There is no guarantee that your stack isn't in memory that's overwritten by the sectors you load.
  • There is no guarantee that your code was booted from "device number 0x00". When your code is started, whoever started it (which may not be the BIOS in chain-loading scenarios) puts the actual device number in DL.

Cheers,

Brendan

Re: Bootloader jumps to kernel, but its code isn't executed.

Posted: Fri Mar 28, 2014 6:45 am
by Roman
Antti wrote:
Roman wrote:Why does

Code: Select all

mov ax, 0xee
make CPU halt?
According to CPU manuals, this instruction ("mov r16, imm16") in itself does not halt or trigger exceptions. If this instruction seems to halt code execution, there is a problem elsewhere. Are you sure that it is this instruction that halts and not the previous one?
Sorry, I was not sure, CPU was halted by another code, now it was fixed.

How can I read input from a keyboard using BIOS calls or something else? (if it depends, I need PS/2 keyboard support first, because it is emulated by QEMU, isn't it?)

Re: Bootloader jumps to kernel, but its code isn't executed.

Posted: Fri Mar 28, 2014 7:11 am
by Bender
Roman wrote:
Antti wrote:
Roman wrote:Why does

Code: Select all

mov ax, 0xee
make CPU halt?
According to CPU manuals, this instruction ("mov r16, imm16") in itself does not halt or trigger exceptions. If this instruction seems to halt code execution, there is a problem elsewhere. Are you sure that it is this instruction that halts and not the previous one?
Sorry, I was not sure, CPU was halted by another code, now it was fixed.

How can I read input from a keyboard using BIOS calls or something else? (if it depends, I need PS/2 keyboard support first, because it is emulated by QEMU, isn't it?)
Hi,
You've got BIOS Interrupt 0x16 for keyboard. You shouldn't need PS/2 Code if you're using INT 0x16 (one of the 100 reasons why beginners love BIOS so much). For more information on this routine, what it expects/returns better checkout RBIL or similar.
Even real USB keyboards provide PS/2 Emulation, On one of my laptops there is a option to enable/disable PS/2 Emulation.
And PS/2 is possibly one of the over-documented things on the internet,
Google should be getting a result overflow :)
Seeing that you've got second stage working I'd suggest moving onto Protected/Long Mode, there are a few concepts left to be covered ex: A20 and the like, but they don't take much time to learn.
So yeah, Congratulations on getting it working...

Re: Bootloader jumps to kernel, but its code isn't executed.

Posted: Fri Mar 28, 2014 7:58 am
by Roman
That halts CPU, what am I doing wrong?

Code: Select all

inpt:
	mov ah, 0x00
	int 0x16
	
	mov dl, al
	mov ah, 2
	int 0x21
	
	jmp inpt
EDIT: commented int 0x16, CPU doesn't halt. What's wrong with that call?

EDIT: oh, QEMU said, that CPU is halted, because it was waiting for keyboard input.

Re: Bootloader jumps to kernel, but its code isn't executed.

Posted: Fri Mar 28, 2014 10:18 am
by Bender
Why are you using int 0x21? It's a DOS interrupt, not a BIOS interrupt.