0

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

0 Answers0