Here is my code
bits 16
ORG 0x7c00
VIDEO_TEXT_ADDR EQU 0xb8000 ; Hard code beginning of text video memory
ATTR_WHITE_ON_BLACK EQU 0x07 ; White on black attribute
CR EQU 0x0d ; Carriage return
LF EQU 0x0a ; Line feed
; Include a BPB (1.44MB floppy with FAT12) to be more comaptible with USB floppy media
%include "bpb.inc"
boot_start:
xor ax, ax ; DS=SS=0. Real mode code below doesn't use ES
mov ds, ax
mov ss, ax ; Stack at 0x0000:0x7c00 below bootloader
mov sp, 0x7c00
cld ; Set string instructions to use forward movement
mov si, boot_init_msg ; Print boot initialization message
call print_string_rm
cli ; Disable interrupts
in al, 0x92
or al, 2
out 0x92, al ; Enable A20 using Fast Method
mov si, load_gdt_msg ; Print loading GDT message
call print_string_rm
lgdt [gdtr] ; Load our GDT
mov si, enter_pm_msg ; Print protected mode message
call print_string_rm
mov eax, cr0
or eax, 1
mov cr0, eax ; Set protected mode flag
jmp CODE32_SEL:start32 ; FAR JMP to set CS
bits 32
start32:
mov ax, DATA32_SEL ; Setup the segment registers with data selector
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov esp, 0x9c000 ; Set the stack to grow down from area under
; EBDA/Video memory
xor eax, eax ; Clear EAX for the instructions below
mov al, [0x450] ; Byte at address 0x450 = last BIOS column position
mov [cur_col], eax ; Copy to current column
mov al, [0x451] ; Byte at address 0x451 = last BIOS row position
mov [cur_row], eax ; Copy to current row
mov ax, [0x44a] ; Word at address 0x44a = # of columns (screen width)
mov [screen_width], eax ; Copy to screen width
mov eax, in_pm_msg ; Print message we are in protected mode
call print_string_pm ; EAX = first parameter
end_loop:
hlt
jmp end_loop
set_cursor:
mov ecx, [cur_row] ; EAX = cur_row
imul ecx, [screen_width] ; ECX = cur_row * screen_width
add ecx, [cur_col] ; ECX = cur_row * screen_width + cur_col
; Send low byte of cursor position to video card
mov edx, 0x3d4
mov al, 0x0f
out dx, al ; Output 0x0f to 0x3d4
inc edx
mov al, cl
out dx, al ; Output lower byte of cursor pos to 0x3d5
; Send high byte of cursor position to video card
dec edx
mov al, 0x0e
out dx, al ; Output 0x0e to 0x3d4
inc edx
mov al, ch
out dx, al ; Output higher byte of cursor pos to 0x3d5
ret
print_string_pm:
push edi
push esi
push ebx
mov esi, eax ; Set ESI to beginning of string
; Assume base of text video memory is ALWAYS 0xb8000
mov ebx, VIDEO_TEXT_ADDR ; EBX = beginning of video memory
mov eax, [cur_row] ; EAX = cur_row
mul dword [screen_width] ; EAX = cur_row * screen_width
mov edx, eax ; EDX = copy of offset to beginning of line
add eax, [cur_col] ; EAX = cur_row * screen_width + cur_col
lea edi, [ebx + eax * 2] ; EDI = memory location of current screen cell
mov ah, ATTR_WHITE_ON_BLACK ; Set attribute
jmp .getch
.repeat:
cmp al, CR ; Is the character a carriage return?
jne .chk_lf ; If not skip and check for line feed
lea edi, [ebx + edx * 2] ; Set current video memory pointer to beginning of line
mov dword [cur_col], 0 ; Set current column to 0
jmp .getch ; Process next character
.chk_lf:
cmp al, LF ; Is the character a line feed?
jne .write_chr ; If not then write character
mov eax, [screen_width]
lea edi, [edi + eax * 2] ; Set current video memory ptr to same pos on next line
inc dword [cur_row] ; Set current row to next line
mov ah, ATTR_WHITE_ON_BLACK ; Reset attribute
jmp .getch ; Process next character
.write_chr:
inc dword [cur_col] ; Update current column
stosw
.getch:
lodsb ; Get character from string
test al, al ; Have we reached end of string?
jnz .repeat ; if not process next character
.end:
call set_cursor ; Update hardware cursor position
pop ebx
pop esi
pop edi
ret
bits 16
print_string_rm:
mov ah, 0x0e ; BIOS tty Print
xor bx, bx ; Set display page to 0 (BL)
jmp .getch
.repeat:
int 0x10 ; print character
.getch:
lodsb ; Get character from string
test al,al ; Have we reached end of string?
jnz .repeat ; if not process next character
.end:
ret
cur_row: dd 0x00
cur_col: dd 0x00
screen_width: dd 0x00
boot_init_msg:
db "GT-MOS : Booting sequence initialized...", CR, LF, 0
load_gdt_msg:
db "GT-MOS : Loading GDT...", CR, LF, 0
enter_pm_msg:
db "GT-MOS : Entering 32-bit Protected Mode...", CR, LF, 0
in_pm_msg:
db "GT-MOS : Executing code in protected mode!", CR, LF, 0
align 8
gdt_start:
dd 0 ; null descriptor
dd 0
gdt32_code:
dw 0FFFFh ; limit low
dw 0 ; base low
db 0 ; base middle
db 10011010b ; access
db 11001111b ; 32-bit, 4kb granularity, limit 0xffffffff bytes
db 0 ; base high
gdt32_data:
dw 0FFFFh ; limit low (Same as code)
dw 0 ; base low
db 0 ; base middle
db 10010010b ; access
db 11001111b ; 32-bit, 4kb granularity, limit 0xffffffff bytes
db 0 ; base high
end_of_gdt:
gdtr:
dw end_of_gdt - gdt_start - 1
; limit (Size of GDT - 1)
dd gdt_start ; base of GDT
CODE32_SEL equ gdt32_code - gdt_start
DATA32_SEL equ gdt32_data - gdt_start
; Pad boot sector to 510 bytes and add 2 byte boot signature for 512 total bytes
times 510 - ($ - $$) db 0
dw 0xaa55
How do i fix what the title says and load the kernal.
Here is how i compile it
nasm -f bin main.asm -o boot.bin
#Build 1.44MB disk image
dd if=/dev/zero of=disk.img bs=1024 count=1440
dd if=boot.bin of=disk.img conv=notrunc
qemu-system-x86_64 -fda disk.img