I'm trying to put a small boot loader into the mbr of an exfat drive, but I'm having trouble getting ld
to set the virtual address correctly.
according to the ExFat Specification, I need to put the bootloader at byte 0x78 (120)
. So I set the location counter to 0x7C78
. But when I used readelf
on the result, I found that ld put the virtual address at 0x7C80
instead.
This is sadly not what I want, so I tried to set the virtual address to different values and found that ld will always put the section with a 16 byte alignment. e.g. at 0x7C70
and 0x7C80
My question is: Is there any way to disable/override this alignment, and put my section at the specific address
The boot code
bits 16
global boot
boot:
mov ax, 0x0202
mov bx, 0x7E00
mov cx, 0x0002
mov dx, 0x0080
int 0x13
jmp 0x0000:0x7e00
times 388-($-$$) db 0x00
dw 0xAA55
The linkerscript
OUTPUT_FORMAT("binary")
SECTIONS {
. = 0x7c78;
.text :
{
*.mbr.o(.text)
}
.text :
{
*.o(.text)
}
}
The readelf result
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS src/boot/boot.mbr.s
2: 0000000000000000 0 SECTION LOCAL DEFAULT 4 .debug_info
3: 0000000000000000 0 SECTION LOCAL DEFAULT 5 .debug_abbrev
4: 0000000000000000 0 SECTION LOCAL DEFAULT 6 .debug_line
5: 0000000000007c93 1 OBJECT LOCAL DEFAULT 1 boot.end
6: 0000000000000000 0 FILE LOCAL DEFAULT ABS src/boot/boot.s
7: 0000000000007e10 0 SECTION LOCAL DEFAULT 2 .text
wrong > 0000000000007c80 0 NOTYPE GLOBAL DEFAULT 1 boot
9: 0000000000007e10 0 NOTYPE GLOBAL DEFAULT 2 stage2
I used these flags to call nasm
:
nasm -felf64 -g -F dwarf -o boot.mbr.o boot.mbr.s
and these flags to call ld
i386-elf-gcc -nostdlib -n -Wl,--oformat=elf64-little -T linker.ld -o boot.elf boot.mbr.o