1

I think this is more related to GCC rather than ESP8266. I have been trying to put in a constant variable in read only memory section of ESP. The idea is to change the value directly in the binary image before flashing it on a new chip. In the code section, I have added,

const uint32_t device_address __attribute__((section(".device_addr"))) = 0x12345678;

The changes to the linker script in program.ld is; created a new memory region

device_addr_section :           org = 0x40202100, len = 0x04

In the SECTIONS region, added a new section

.addr_section: ALIGN(4)
{
    KEEP(*(.device_addr))
} >device_addr_section

When I compile the code with the new linker, I see the changes and allocation in the map file, but I cannot find the hex value 0x12345678 in the generated binary image. When I remove the attribute from the variable device_address, I do see that hex value in the generated binary image. The full memory region breakdown:

MEMORY
{
  dport0_0_seg :                        org = 0x3FF00000, len = 0x10
  dram0_0_seg :                         org = 0x3FFE8000, len = 0x14000
  iram1_0_seg :                         org = 0x40100000, len = 0x08000
/* irom0 section, mapped from SPI flash
  - Origin is offset by 0x2010 to create spacer for second stage bootloader image,
    header.

  - Length is max 8Mbit of mappable flash, minus start offset
*/
  irom0_0_seg :                         org = 0x40202010, len = (1M - 0x2020)
  device_addr_seg  (rx):                org = 0x40202100, len = 0x04
}

I haven't used GCC in the past any ideas and help would be appreciated.

Thanks, Nishant

agnishant
  • 11
  • 2
  • Did you remove that memory section out of the main one? You can't just arbitrarily allocate bits of another section to a new section, you have to slice it up properly. Can you show your whole memory section so we can see what you are doing? – Majenko Nov 03 '16 at 12:38
  • I have added the memory section in my question. After your comment, I tried reversing the address locations of irom0_0_seg and device_addr_seg, but the result was still the same. – agnishant Nov 06 '16 at 10:54

1 Answers1

1

You have this in your memory section:

irom0_0_seg :          org = 0x40202010, len = (1M - 0x2020)
device_addr_seg  (rx): org = 0x40202100, len = 0x04

That is a block of memory from 0x40202010 to 0x402FFFFF0. Within that you then have another block from 0x40202100 to 0x20202104.

.----------.
|0x40202010|
|          |
|0x40202100| <- Device address lost
\          \
\          \
|0x402FFFEC|
`----------'

That can't happen. You have one memory area (irom0_0_seg) completely covering the other (device_addr_seg) and anything in device_addr_seg will be overwritten by irom0_0_seg.

You have to set aside a specific area for your device address that is not within the irom0_0_seg. That means reducing the size of the irom0_0 segment to leave a space that you can populate with the device address.

You already have a small gap at the top (I don't know off hand why that is?), but if it's not used for something already then you can use it - otherwise you can expand it downwards and use the new space:

irom0_0_seg :          org = 0x40202010, len = (1M - 0x2030)
device_addr_seg  (rx): org = 0x402FFFE0, len = 0x04

.----------.
|0x40202010|
\          \
\          \
|0x402FFFDC|
+----------+
|0x402FFFE0| <- Device address here
|0x402FFFE4|
|0x402FFFE8|
|0x402FFFEC|
`----------'

The purpose of the memory map is to slice the memory up like a cake, or better still, a loaf of bread. You can't remove a slice from the middle of the loaf and keep the loaf as a single item - as soon as you remove the slice you end up with a slice and two smaller half-loaves. You were trying to remove the slice from the middle whilst still keeping it as a single big loaf - that's never going to be possible. So you do what any sensible person does when slicing bread up and cut a slice from one end, not the middle.

Majenko
  • 55,955
  • 9
  • 105
  • 187
  • I did try changing the address and moving the device_add_seg out of the irom section, changed the address to 0x40202000 but the problem is still the same. When I ran objdump on the object file, beside section device_addr_seg I get the message CONTENTS, READONLY where as for others I get CONTENTS, ALLOC, LOAD, READONLY, DATA. This is what is causing the problem and I can't see any way to fix it up. – agnishant Nov 06 '16 at 16:03