Using ld to link a file makes it too big for a boot loader, works in nasm though :(

Multi tool use
Using ld to link a file makes it too big for a boot loader, works in nasm though :(
I'm trying to make a simple bootloader, but running into issues with ld (I think).
When I compile my assembly file (below) with nasm -f bin
, it works and I get a nice 512 byte file. For that one I include org 0x7c00 at the top and everything works as expected.
nasm -f bin
However, now I'm trying to do something a bit more complicated and link in a C kernel (unclear if I'm on the right path there, but I'm sure I'll learn that soon). Anyway, when I compile it with nasm -f elf -o loader_elf bootloader.asm
and link it with i386-elf-ld loader_elf -o loader_exe -Ttext 0x7C00
, I get a file that is 4196 bytes (with a 1152 byte elf file).
nasm -f elf -o loader_elf bootloader.asm
i386-elf-ld loader_elf -o loader_exe -Ttext 0x7C00
What do I need to do for either the elf file or ld to get an executable with a proper file size?
Thanks for your help!
Here's the file in question:
bits 16 ; 16-bit Real Mode
;org 0x7c00 ; BIOS boot origin... only used for bin, not elf
global _start
Message db "Starting YADBL", 0x0
jmp _start ;Jump to start main() entry-point
;Print characters to the screen
Println:
lodsb ;Load string
or al, al
jz complete
mov ah, 0x0e
int 0x10 ;BIOS Interrupt 0x10 - Used to print characters on the screen via Video Memory
jmp Println ;Loop
complete:
call PrintNwL
;Prints empty new lines like 'n' in C/C++
PrintNwL:
mov al, 0 ; null terminator ''
stosb ; Store string
;Adds a newline break 'n'
mov ah, 0x0E
mov al, 0x0D
int 0x10
mov al, 0x0A
int 0x10
ret
;Reboot the Machine
AToHalt:
call GetPressedKey
; Inputted key is in al
cmp al, 'A'
jne rbt
; We got an A!!!
; mov si, Halting
; call Println
cli
hlt
rbt:
ret ; we're returning, not rebooting
;Sends us to the end of the memory
;causing reboot
;db 0x0ea
;dw 0x0000
;dw 0xffff
jmp 0xffff:0000h ; also restarts
;Gets the pressed key
GetPressedKey:
mov ah, 0
int 0x16 ;BIOS Keyboard Service
ret
;Bootloader entry-code
_start:
cli ;Clear interrupts
;Setup stack segments
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
sti ;Enable interrupts
;Print the first characters
mov si, Message
call Println
call AToHalt
times 510 - ($-$$) db 0 ;Fill the rest of the bootloader with zeros
dw 0xAA55 ;Boot signature
You could add
--oformat binary
to your linker command. But you are going to have real problems when you start adding in C objects with data, bss, rodata sections. Most people for simplicity create their bootloader separate from their C kernel– Michael Petch
Jul 2 at 5:01
--oformat binary
You really shouldn't link your kernel into your bootloader. Instead, make your kernel a separate file you load from your bootloader.
– fuz
Jul 2 at 7:17
You also have
Message db "Starting YADBL", 0x0
before code. When the file is generated this data will be interpreted as code by the processor. Place your data after the last line of usable code and before the boot signature,– Michael Petch
Jul 2 at 13:43
Message db "Starting YADBL", 0x0
Here is a previous SO answer that has a complete same of what you can do: stackoverflow.com/a/33619597/3857942 in the section
Code After Making All Recommended Changes
– Michael Petch
Jul 2 at 16:21
Code After Making All Recommended Changes
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
You may be able to get the linker to create an ELF file that's less than 512 bytes, but what would be the point? BIOSes can't load ELF files. Have the linker create a binary file instead.
– Ross Ridge
Jul 2 at 4:40