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:initinit: xor ax, ax mov ds, ax mov es, ax; ===============================; SET BP AND STACK SIZE; ===============================cli; =========================; SET STACK SIZE; =========================mov sp, 0x7C00mov ss, axsti; ; 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_kerneljmp 0x1000:0x0; jmp $%include "helper.s"%include "disk_loader.s"; %include "kernel.s"; =========================; BOOT SECTOR; =========================times 510 - ($ - $$) db 0dw 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_diskload_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, 0x0emov bx, infocall printint 0x10jmp $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 printglobal check_diskglobal clear_screenglobal readprint: mov al, [bx] add bx, 1 int 0x10 cmp al, 0 je done jmp print done: retclear_screen: mov ah, 0x00 mov al, 0x00 int 0x10 retset_official: mov ah, 0x00 mov al, 0x03 int 0x10 retread: 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 retDO: call set_official retgraphical: mov ax, 0x13 int 0x10 ret; ===============================; MESSAGES FOR INPUT; ===============================Welcome: db 13, 10, "Welcome to AOS",13, 10,0x0TEXT: 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.s boot.bin
nasm -f bin -o kernel.s kernel.bin
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.