The following files and build process worked for me. I tested it in Bochs as a floppy disk image.
mbr.asm:
%macro print 2
mov ah, 0xa
mov al, [%1]
mov bl, 0xf
mov bh, 0
mov cx, %2
int 0x10
%endmacro
%macro printr 2
mov al, %1
mov bl, 0xf
mov bh, 0
mov cl, %2
mov ah, 0xa
int 0x10
%endmacro
[ORG 0x7c00]
[BITS 16]
jmp 0x0000:bootstart ; jump to set up CS:IP
bootstart:
; Set our data segment
xor ax, ax
mov ds, ax
mov es, ax
mov [dlvalue], dl
cli
print greeting, 2
jmp reset
; 512 bytes per sector
; 18 sectors per track
; 63 tracks
reset:
mov ah, 0 ; reset floppy disk function
mov dl, [dlvalue]
int 0x13 ; call BIOS
jmp readCD
print reading, 3
jc reset
readCDerror:
xor ch, ch
xor cl, cl
mov dl, [dlvalue]
print error, 4
jmp reset
readCD: ; Read 0x7700 bytes from the disk to point 0x500 in memory from beginning of cd
mov dh, 0 ; Drive head
mov ax, 0x500
mov es, ax ; Set es to 0x500, where we want to buffer to
xor bx, bx ; buffer is at 500:0, es:bx
mov ch, 0 ; Set track to 0
mov cl, 2 ; sector to 2
mov ah, 0x2 ; What we want to do with 0x13
mov al, 0x2 ; How much we want to read
mov dl, [dlvalue]
clc
int 0x13
jc readCDerror ; There was a problem with reading
jumpOut:
print load, 5
; Load GDT
cli
xor ax, ax
mov ds, ax
mov es, ax
mov ax, 0x9000 ; set stack at 0x9000-0xffff
mov ss, ax
mov sp, 0xFFFF
pusha
lgdt [TGDT]
popa
jmp 0x500:0x0 ; No problem, just jump to the entry point
data:
greeting db 'G'
error db 'E'
load db 'L'
reading db 'R'
dlvalue db 0
;========================================
;===================GDT==================
;========================================
;align 4
BGDT:
; Null
dd 0
dd 0
; Code
dw 0xFFFF ; limit low
dw 0 ; base low
db 0 ; base middle
db 10011010b ; access
db 11001111b ; granularity
db 0 ; base high
; Data
dw 0xFFFF ; limit low
dw 0 ; base low
db 0 ; base middle
db 10010010b ; access
db 11001111b ; granularity
db 0 ; base high
EGDT:
TGDT:
dw EGDT - BGDT - 1 ; limit (Size of GDT)
dd BGDT
times 510-($-$$) db 0
dw 0xAA55
lbr.asm:
ORG 0x5000
%macro print 2
mov ah, 0xa
mov al, [%1]
mov bl, 0xf
mov bh, 0
mov cx, %2
int 0x10
%endmacro
%macro printr 2
mov al, %1
mov bl, 0xf
mov bh, 0
mov cl, %2
mov ah, 0xa
int 0x10
%endmacro
[BITS 16]
ssblstart:
; Set our data segment
mov eax, cr0
or eax, 1
mov cr0, eax
cli
; hlt
jmp 0x8:PmodeE
; printr [greeting2], 12
; mov ax, cr0
; or ax, 1
; mov cr0, axe
[BITS 32]
PmodeE:
cli
mov ax, 0x10 ; set data segments to data selector (0x10)
mov ds, ax
mov ss, ax
mov es, ax
mov esp, 90000h
cli
.hang:
inc DWORD[0x000B8000]
jmp .hang
hlt
greeting2 db 'A'
error db '2'
load db '3'
times 510-($-$$) db 0
dw 0xAA55
floppy.asm:
incbin "mbr.bin"
incbin "lbr.bin"
TIMES 1474560-($-$$) DB 0
build process:
nasm -f bin -o mbr.bin mbr.asm
nasm -f bin -o lbr.bin lbr.asm
nasm -f bin -o floppy.img floppy.asm
Please note that I commented out align in the MBR because NASM 2.09.03 (and perhaps even earlier versions) is messing up the alignment, padding much more than expected.
Also, the ALIGN directives in your linker script might be causing problems, as Frank expressed in his above post. I'm also not sure if OUTPUT_FORMAT("i386") is working for you, since that might default to ELF. Try OUTPUT_FORMAT("binary") instead.