3

In my efforts to understand how to use the GNU binutils to build a simple boot loader using gas I have come across the question, how do you tell the linker where to put your data, in a file that uses .org to advance the location counter while keeping the file size at 512 bytes. I can't seem to find a way to do this.

The assembly program that tries to do this is:

# 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
_start:
  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

loop:
  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
#
print_char:
  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
  ret

#
# Function used as infinite loop
#
_hang:
  jmp  _hang

.org 510
.byte 0x55, 0xAA

.end

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'
Matthew Hoggan
  • 7,402
  • 16
  • 75
  • 140
  • Minimal example that generates this error and what it means: http://stackoverflow.com/a/32639540/895245 Repository with working boot sector + BIOS examples: https://github.com/cirosantilli/x86-bare-metal-examples – Ciro Santilli OurBigBook.com Sep 17 '15 at 20:49
  • I think `.org` doesn't work the same way in GAS that it does in NASM. Since GAS is always making a relocatable object file for the linker to fill in addresses, it has no use for absolute addresses. That only comes in when you link with `-Ttext=0x7c00` or a linker script. – Peter Cordes Apr 11 '22 at 04:18
  • Related: [I can't understand why LD gives rilocazione (relocation) error](https://stackoverflow.com/a/35371505) for the necessary `as` and `ld` commands to use 32-bit mode, not the x86-64 default on a 64-bit system. – Peter Cordes Apr 11 '22 at 04:19

1 Answers1

5

For this kind of work you should write your own linker script. Just pass it to the linker with the -T option.

My script for an almost identical problem was:

SECTIONS
{
    . = 0x1000;
    bootsec :
    {
        *(.text)
        *(.data)
        *(.rodata)
        *(.bss)
        endbootsec = .;
        . = 0x1FE;
        SHORT(0xAA55)
    }
    endbootsecw = endbootsec / 2;
    image = 0x1200;
}

With that trick you don't event need to put the 0x55 0xAA in the assembler!

The 0x1000 at the beginning: Actually all the jumps are relative, so that is not used, but it is needed later for the jump into protected mode...

endbootsecw, endbootsec and image are symbols used elsewhere in the code.

rodrigo
  • 94,151
  • 12
  • 143
  • 190
  • I get: `a.ld:11 cannot move location counter backwards (from 0000000000001200 to 00000000000011fe)` with that linker script on Binutils 2.24. – Ciro Santilli OurBigBook.com Sep 06 '15 at 16:49
  • 1
    @CiroSantilli六四事件法轮功纳米比亚威视: Well, it looks like you are overflowing your section. That is, your code ends in `0x1200` and then in the linker you are trying to move the pointer back to `0x11FE`, and that is not allowed. That may happen if you have too much code in your asm, or if you are doing my linker trick **and** the `.org` thing at the same time. – rodrigo Sep 07 '15 at 12:53
  • "are doing my linker trick and the .org thing at the same time" DOH! – Ciro Santilli OurBigBook.com Sep 07 '15 at 14:16