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

Recommended Answers

All 2 Replies

My first thought was this would no longer work on today's PC. So much has changed that my bet is this may only work in old PC emulators like QEMU. Sure enough that appears to be going on here.

Read priors to cover this again.

I can't guess if you write this from scratch or copied someone else's work but I don't expect it to work today unless you find some over 10 year old hardware.

Off the top of my head, I'd say the solution is to change line 162 from "times 510 - ($ - $$) db 0" to "times 1022 - ($ - $$) db 0". The error message is telling you that 510 - ($ - $$) is evaluating to -32 which suggests that ($ - $$) evaluates to 542. The module isalready longer than 512 bytes. You cannot pad it to 512 bytes. You are aware of this because you're specifying a block size of 1024 already. If you pad it out to 1022, then the additional two byte signature will make it 1024 and off you go.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.