I am currently trying to build a two-stage bootloader in GNU assembler. I use the as
command to compile the assembly files and the ld
command to link them to the final binary. Some information beforehand:
$ as --version
GNU assembler (GNU Binutils for Debian) 2.28 [...]
This assembler was configured for a target of `x86_64-linux-gnu'
And ld
:
$ ld --version
GNU ld (GNU Binutils for Debian) 2.28 [...]
The affected assembly file:
.code16
.section .test
label: .short 0x1234
.section .text
.global _setup32
_setup32:
cli
xor %ax, %ax
# Some more code [...]
And the linker script used to build the binary file: Before anyone asks, the following linker script is the stage-2 part of my bootloader, hence the origin of 0x8000
.
OUTPUT_FORMAT(binary)
ENTRY(_setup32)
SECTIONS
{
. = 0x8000;
_SETUP_START = .;
.test ALIGN(0x10) : {
*(.test*)
}
.text ALIGN(0x10) : {
_TEXT_START = .;
*(.text*)
_TEXT_END = .;
}
.rodata ALIGN(0x10) : {
_RODATA_START = .;
*(.rodata*)
_RODATA_END = .;
}
.data ALIGN(0x10) : {
_DATA_START = .;
*(.data*)
_DATA_END = .;
}
.bss ALIGN(0x10) : {
_BSS_START = .;
*(.bss*)
_BSS_END = .;
}
/DISCARD/ : {
*(.comment*)
}
_SETUP_END = .;
}
However, after the final setup.bin
file has been built, the value 0x1234
is not located at the beginning of the hexdump. In fact, it is not even included in the final built. The bootloader is working absolutely fine, I'm just unable to assign variables or in general, bytes to individual sections.
I am using the following, very basic rules in my Makefile:
$(SETUPBIN): $(SETUP).o
$(LD) -T setup.ld $(SETUP).o -o $@
%.o: %.asm
$(AS) $< -o $@
Furthermore: I know about GNU AS directives .text
and .data
, but they only store the instructions and bytes in fixed locations of the binary: Everything in the .text
directive is located at the beginning of the binary whereas everything in .data
is found at the end of the binary.
How do I put everything in a custom section?