Code: Select all
.intel_syntax noprefix
.code16 # use 16 bits
.global _init
.global _startup
.text
_init:
.org 80 # Some BIOSes need a BPB, therefore we fill up space for a fake one
jmp 0x0000, _startup # in case BIOS set cs to 0x7c00. We work with cs:ip
_startup:
cld
mov bp, 0x8000
mov sp, bp # 0x0000:0x7c00 below bootloader
xor ax, ax
mov ds, ax
mov ss, ax
mov es, ax
movb [BOOT_DRIVE], dl
mov bx, offset flat:start_16_str
call print
mov bx, offset flat:read_disk_str
call print
mov dh, 0x1
mov bx, 0x9000 # memory location to load disk to
call load_disk
mov bx, offset flat:read_disk_success_str
call print
call check_lm
mov bx, 0x9000 # Loading test strig from second sectors
call print # It works perfectly
jmp .
check_lm:
pusha
# Check if CPU support Long mode (64 bits)
mov eax, 0x80000001
cpuid
test edx, (1 << 29)
jz .lm_error
mov bx, offset flat:lm_success_str
call print
jmp .lm_done
.lm_error:
mov bx, offset flat:lm_error_str
call print
jmp .lm_done
.lm_done:
popa
ret
.include "print_16.S"
.include "read_disk.S"
start_16_str:
.asciz "Starting in 16-bit mode"
read_disk_str:
.asciz "Loading disk into memory"
read_disk_success_str:
.asciz "Loaded disk successfully !"
lm_error_str:
.asciz "ERROR: FATAL: CPU does not support Long Mode"
lm_success_str:
.asciz "CPU support Long mode "
.set BOOT_DRIVE, 0
.space 510-(.-_init), 0 # add zeroes to make it 510 bytes long
.word 0xaa55 # magic bytes that tell BIOS that this is bootable
msg:
.asciz "Test string"
Code: Select all
...
.space 510-(.-_init), 0 # add zeroes to make it 510 bytes long
.word 0xaa55 # magic bytes that tell BIOS that this is bootable
#Beginning of second sector loaded to 0x0000:0x9000
mov bx, offset flat:msg
call print
msg:
.asciz "Test string"
I'm also leaving my linker script below :
Code: Select all
ENTRY(_init)
OUTPUT_FORMAT(binary)
SECTIONS {
. = 0x7c00;
.text : {
*(.text*)
}
.rodata : {
*(.rodata*)
}
.data : {
*(.data*)
}
.bss : {
*(.bss*)
}
}
Thank you all !