So, I am having issues with running the kernel code. I read the second sector, pad it with 512 bytes, then jump to the address where the kernel is to be. But, instead of printing, like it should, it just halts and does nothing.
Here is my code:
boot.s:
[org 0x7C00]
[bits 16]
jmp 0x0000:init
init:
xor ax, ax
mov ds, ax
mov es, ax
; ===============================
; SET BP AND STACK SIZE
; ===============================
cli
; =========================
; SET STACK SIZE
; =========================
mov sp, 0x7C00
mov ss, ax
sti
;
; Mimick old windows machine by requiring user to press
; a key to boot.
;
call read
;
; Load second sector from disk
;
call load_disk
; jmp 0x0:0x1000
; call graphical
;
; Boot kernel
;
; call init_kernel
jmp 0x1000:0x0
; jmp $
%include "helper.s"
%include "disk_loader.s"
; %include "kernel.s"
; =========================
; BOOT SECTOR
; =========================
times 510 - ($ - $$) db 0
dw 0xaa55
; times 512 db 0
helper.s just contains some functions to boot in graphics mode, clear the screen etc.
disk_loader.s:
[bits 16]
global load_disk
load_disk:
mov ax, 0x1000
mov es, ax
xor bx, bx
mov ah, 0x02
mov al, 1
mov ch, 0
mov cl, 0x02
mov dh, 0
mov dl, 0x80
int 0x13
jc failure
cmp ah, 0x0
jne failure
jmp succeed
succeed:
ret
failure:
; jmp load_disk
mov ah, 0x0e
mov bx, reading_err
call print
; Never-ending loop.
jmp $
reading_err: db "Error reading from disk", 0x0
It works perfectly. I set the address to 0x1000, which is where the kernel should be. Here is my kernel.s code:
[bits 16]
[org 0x1000]
; ======================
; 16-BIT KERNEL
; AUTHOR: Moca
; DATE: 07/14/21
; DO NOT COPY
; ======================
mov ah, 0x0e
mov bx, info
call print
int 0x10
jmp $
times 510 - ($ - $$) db 0
Additional, here is my helper.s file:
;
;
; Helper functions to use throughout all assembly files.
; Author: MocaCDeveloper
; DO NOT COPY WITHOUT PERMISSION.
;
[bits 16]
; =====================================
; FUNCTIONS TO USE
; =====================================
global print
global check_disk
global clear_screen
global read
print:
mov al, [bx]
add bx, 1
int 0x10
cmp al, 0
je done
jmp print
done:
ret
clear_screen:
mov ah, 0x00
mov al, 0x00
int 0x10
ret
set_official:
mov ah, 0x00
mov al, 0x03
int 0x10
ret
read:
call clear_screen
mov ah, 0x0e
mov bx, TEXT
call print
int 0x10
mov ah, 0x00
int 0x16
cmp al, 13
je DO
jmp read
ret
DO:
call set_official
ret
graphical:
mov ax, 0x13
int 0x10
ret
; ===============================
; MESSAGES FOR INPUT
; ===============================
Welcome:
db 13, 10, "Welcome to AOS",13, 10,0x0
TEXT:
db "PRESS ENTER TO BOOT"
db 13, 13, 13, 10
db 13, '$'
db 0x00
I align the kernel(in kernel.s) using org 0x1000. I have heard that it's the correct way, and I have also heard that it should be org 0x0.
Either way, after loading the second sector from the disk, and set the address to 0x1000, then jump to it, it simply halts and executes no further.
Here are the commands:
nasm -f bin -o boot.bin boot.s
nasm -f bin -o kernel.bin kernel.s
cat kernel.bin >> boot.bin - this is to insert the kernel after the bootloader.
qemu-system-i386 -L "C:\Program Files\qemu" boot.bin
For some reason qemu fails to run if I do not specify the path of qemu. That's not the problem, however. I am simply looking for an answer as to how to make sure the kernel is at the correct address, and how to correctly jump to it.