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

Multi tool use
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 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





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.

EAc1mx,zR4SrROx9
2JIilMm38PtTS

Popular posts from this blog

Rothschild family

Cinema of Italy