0
votes

Some sections within my program are located at different places in memory and there are some unused memory locations. The following is a part of the object file of my program:

a0000128:   20cf8f93            addi    t6,t6,524 # a0000330 <region_1>
a000012c:   000f8067            jr  t6

Disassembly of section .fill:

00000000a0000130 <_end-0x800290>:
    a0000130:   deaa                    sw  a0,124(sp)
    a0000132:   c0ad                    beqz    s1,a0000194 <_start+0x194>
    a0000134:   dede                    sw  s7,124(sp)
    a0000136:   c0ad                    beqz    s1,a0000198 <_start+0x198>
    ...

Disassembly of section .s_region_1:

00000000a0000330 <region_1>:
    a0000330:   00400f97            auipc   t6,0x400
    a0000334:   00cf8f93            addi    t6,t6,12 # a040033c <region_2>
    a0000338:   000f8067            jr  t6

As shown, instruction at address 0xa000012c jumps to another instruction at address 0xa0000330. Since there are unused memory locations, I used FILL command in linker script. However, corresponding HEX file (generated with objcopy -O verilog) does not include the machine code of region_1. That is, HEX file only includes .text section and the data that is used to pad unused memory region:

13 0F 00 00 9B 0F 10 00 93 9F FF 01 1B 08 F0 FF 
13 18 38 03 13 08 18 04 13 18 C8 00 13 08 98 12 
73 10 18 30 97 0F 00 00 93 8F CF 20 67 80 0F 00 
@A0000130
AA DE AD C0 DE DE AD C0 DE DE AD C0 DE DE AD C0 
DE DE AD C0 DE DE AD C0 DE DE AD C0 DE DE AD C0 
DE DE AD C0 DE DE AD C0 DE DE AD C0 DE DE AD C0 
DE DE AD C0 DE DE AD C0 DE DE AD C0 DE DE AD C0 
...

The following is the content of the linker script:

SECTIONS
{
  . = 0xA0000000;
  .text : { *(.text) }
.fill :
{
    FILL(0xDEADC0DE);
    BYTE(0xAA); 
    . = . + 0x1FF;
}
.s_region_1 : { *(s_region_1) }
.bss : { *(.bss) }
_end = .;
}

What is wrong with the linker script above?

This is the memory map I want to generate:

/*************************/





            .text





/*************************/



    /* EMPTY REGION */



/*************************/



        .section_1



/*************************/
1

1 Answers

0
votes

I noticed that I have to add "aw" flags within my assembly code when defining the section:

.section ".sregion1","aw"
region_1:
    la x31, region_2
    jr x31

After adding "aw" flags, the HEX file was generated by objcopy as expected:

@80000000
1B 00 10 00 13 10 F0 01 B7 F0 0F 00 9B 80 70 81 
93 90 C0 00 93 80 90 A5 13 01 80 00 93 01 80 00 
1B 02 10 00 13 12 F2 01 B7 B2 0F 00 9B 82 12 FB
...
@80400130
97 0F 00 00 93 8F CF 00 67 80 0F 00 97 0F 00 00 
93 8F 0F 00 67 80 0F 00

The following is the final version of my linker file:

OUTPUT_ARCH( "riscv" )
ENTRY(_start)

/*
MEMORY {
       text (RX): o = 0x80000000, LENGTH = 128M
       s_region_1 (RX): o = 0x80400000, LENGTH = 256K
}
*/

SECTIONS
{

  . = 0x80000000;
  .text :
  {
    *(.text);
    
  }

  . = . + 0x400000;
  .sregion1 : { *(.sregion1) }
  . = . + 0x400000;
  .bss : { *(.bss) }
  _end = .;
}