gnuriscvobjcopy

Struggling to understand riscv64-unknown-elf-objcopy -O verilog output


I'm using riscv64-unknown-elf-objcopy -O verilog to convert a RISCV elf file. I can see that there is a related option --verilog-data-width which affects the output.

For example, with --verilog-data-width 1 (which is also the default) the output looks like this...

@00040000
97 02 00 00 93 82 02 11 73 90 52 30 81 40 81 41
01 42 81 42 01 43 81 43 01 44 81 44 01 45 81 45
...

And with --verilog-data-width 4 the output looks like this...

@00010000
00000297 11028293 30529073 41814081
42814201 43814301 44814401 45814501
...

Clearly it has grouped the data into 4 byte chunks.

Question 1: how is the endianness detected? Does riscv64-unknown-elf-objcopy know the endianness of the target from the elf file header or similar?

Question 2: why does the address / offset (i.e. the @00010000, etc.) change. It's clearly been divided by 4, but why? An address is an address, whether writing bytes or words (4-bytes), or is this some quirk of verilog memory file format?

Thanks.


Solution

  • In the absence of a better answer, I'll try answering my own question here - hopefully someone might find it useful. However, if someone has a more authoritative answer please go ahead.

    Answer 1: As suspected, the endianness is taken from the input elf file by default (it's defined in the elf header). In case that endianness is not defined, or you want it different to the input file then I think newer versions have an option --verilog-data-endianness to set this. Unfortunately, the version that I have access to does not support this, so I can't comment. In any case, since the output file is plain text, with data in hexadecimal format, it is easy enough to change endianness with some text processing.

    Answer 2: This is a bit of a guess, but I think this is just how the mem file is interpreted. I was thinking of the address as just byte address, but if you think of it as an offset, it makes more sense. For example, if width is 1 (i.e. bytes) the "address" is the byte offset; if the width is, say 4, (i.e. 32-bit words) then the "address" is the word offset - which is the byte offset / 4 in this case. At least, that's how I'm rationalizing the behaviour.