0

I'm attempting to write some boot code for a MIPS Malta board, emulated in QEMU.

As I understand it, the Malta board loads 4MB of code from flash to a specific position in physical RAM (0x1fc00000, which is 0xbfc00000 in the MIPS program address space: the MIPS32 reset interrupt location). I'm trying to produce the code that will be loaded and run at this location.

I have a simple assembly program which just loops forever:

        .text
_start:
        b _start

When I assemble this with the GNU assembler, I get an ELF file with a .text section containing this code. Disassembling it with objdump:

Disassembly of section .text:

00000000 <_start>:
   0:   1000ffff        b       0 <_start>
   4:   00000000        nop
        ...

Using a linker script I can relocate the .text section to 0x8fc00000, at which point the disassembly yields:

Disassembly of section .text:

8fc00000 <_start>:
8fc00000:       1000ffff        b       8fc00000 <_start>
8fc00004:       00000000        nop
        ...

Since the ELF file contains other sections, ELF headers, etc, which are non-executable, I use objcopy to dump only the text section:

mips-freebsd-objcopy -O binary --only-section .text boot.o.ld boot.bin

However, since the branch operand is still relative, the resultant code does not use absolute addressing and branches to 0x0 rather than 0x8fc00000:

% mips-freebsd-objdump -D -m mips -b binary boot.bin

boot.bin:     file format binary


Disassembly of section .data:

00000000 <.data>:
   0:   ffff0010        b       0x0
   4:   00000000        nop
        ...

I've searched in vain for flags to objcopy or ld that would resolve relative addresses to absolute ones in the output. There are objcopy flags to manipulate section start addresses, but I believe these just alter the offset tables in the output format, and so don't affect binary output (which obviously has no such tables).

The only workaround I've found so far is to add a .org directive in the assembly source:

        .org 0x8fc00000

This understandably produces a ~2GB file front-padded with zeroes, but yields code with absolute addressing which I can chop out.

Is there a correct way to do this?

Sacha
  • 21
  • 3
  • 1
    Why do you care? The nice thing about relative addressing is that it will work no matter where you load it. As I see it, you have no problem whatsoever. – Jester Oct 03 '15 at 21:43
  • I think you're right - I'm new to assembler too; I'd forgotten the operand to the 'b' instruction was PC-relative, I'd assumed that once 'compiled' it would be absolute. – Sacha Oct 03 '15 at 21:53

0 Answers0