Using the .org directive with data in the .data section: In relation to ld

In my attempts to figure out how to use GNU binutils to create a simple bootloader using gas I came across the question of how do you tell the linker where to put its data in the file that uses. org to advance the location counter while keeping the file size 512 bytes. I can't seem to find a way to do this.

The build program that tries to do this:

# Author: Matthew Hoggan
# Date Created: Tuesday, Mar 6, 2012

.code16                      # Tell assembler to work in 16 bit mode
.section .data
msg:                         # Message to be printed to the screen
  .asciz "hello, world"

.section .text
.globl _start                # Help linker find start of program
  xor  %ax,  %ax             # Zero out ax register (ah used to specify bios function to Video Services) 
  movw %ax,  %ds             # Since ax is 0x00 0x00 use it to set data segment to 0
  mov  $msg, %si             # Use source index as pointer to string

  movb %ds:(%si), %al        # Pass data to BIOS function in low nibble of ax
  inc  %si                   # Advance the pointer
  or   %al, %al              # If byte stored in al is equal to zero then...
  jz   _hang                 # Zero signifies end of string
  call print_char            # Print current char in al
  jmp loop                   # Repeat

# Function that uses bios function calls
# to print char to screen
  movb $0x0e, %ah             # Function to print a character to the screen
  movb $0x07, %bl             # color/style to use for the character
  int  $0x10                  # Video Service Request to Bios

# Function used as infinite loop
  jmp  _hang

.org 510
.byte 0x55, 0xAA



UPDATE Using the following commands, I get the following error:

mehoggan@mehoggan-laptop:~/Code/svn_scripts/assembly/bootloader/gas$ ld --oformat binary -o string string.o 
string.o: In function `_start':
(.text+0x5): relocation truncated to fit: R_X86_64_16 against `.data'



source to share

1 answer

For this to work, you must write your own linker script . Just pass it to the linker with the option -T


My script for a nearly identical problem was:

    . = 0x1000;
    bootsec :
        endbootsec = .;
        . = 0x1FE;
    endbootsecw = endbootsec / 2;
    image = 0x1200;


With this trick, you don't need to put 0x55 0xAA

in assembler!


at the beginning: in fact, all jumps are relative, so they are not used, but this is needed later to enter protected mode ...


, endbootsec

and image

are symbols used elsewhere in the code.



All Articles