| |
| /* |
| These addresses are fake, but in a particular way that mesh with our expectations. |
| - ".flash" will contain all parts of the app that go into actual flash |
| *app header |
| * code |
| * RO data |
| * initial contents of RW data |
| * initial contents of the GOT |
| * list of relocs |
| * list of symbols |
| - ".ram" will contain all data that uses ram (and is not part of the flash image) |
| * RW data in its actua location |
| * BSS |
| * the GOT |
| - ".trash" contains sections taht GCC simply feel like it MUST produce (link error otherwise) but we have no use for. it will be tripped |
| |
| After this image is produced a nonoapp_postprocess unitily will process relocs and symbols and compress them to a small reloc table |
| while also modifying the app code itself potentially to adjust for new reloc format. This shrinks relocs a lot. GCC produces relocs at 8 |
| bytes per reloc and symbols at 16 bytes per symbol. We remove all symbol infos (as weo not need them) and compress the relevant data |
| from there into relocs and app image itself, generating 4 bytes per reloc of "nano reloc data" |
| |
| Our format allows apps that are up to 256MB of flash and 256MB of ram in size. |
| */ |
| |
| MEMORY |
| { |
| flash : ORIGIN = 0x10000000, LENGTH = 256K /* we write this to flash */ |
| ram : ORIGIN = 0x80000000, LENGTH = 128K /* we allocate this in ram */ |
| trash : ORIGIN = 0xF0000000, LENGTH = 256K /* we throw this away soon after linking */ |
| } |
| |
| SECTIONS |
| { |
| .flash : { |
| /* magic : "GoogleNanoApp", 0x00, 0xff, 0xff first is magix string, then version (0) then two bytes of "FF" that we can later overwrite with zeros in flash to mark apps as dead */ |
| LONG(0x676f6f47) |
| LONG(0x614e656c) |
| LONG(0x70416f6e) |
| LONG(0xffff0070) |
| |
| /* 64-bit app id */ |
| LONG(0x55555555) |
| LONG(0xaaaaaaaa) |
| |
| /* things we need to load it */ |
| LONG(__data_start) |
| LONG(__data_end) |
| LONG(LOADADDR(.data)) |
| |
| LONG(__bss_start) |
| LONG(__bss_end) |
| |
| /* things we need to run it */ |
| LONG(__got_start) |
| LONG(__got_end) |
| LONG(__rel_start) |
| LONG(__rel_end) |
| |
| /* version */ |
| *(.app_version) *(.app_version.*) ; |
| |
| /* reserved */ |
| LONG(0) |
| |
| /* entry points */ |
| *(.app_init) *(.app_init.*) ; |
| |
| /* code */ |
| *(.text) *(.text.*) ; |
| *(.rodata) *(.rodata.*) ; |
| . = ALIGN(4); |
| } > flash = 0xff |
| |
| .data : { |
| |
| . = ALIGN(4); |
| __data_start = ABSOLUTE(.); |
| *(.data); |
| *(.data.*); |
| . = ALIGN(4); |
| __data_end = ABSOLUTE(.); |
| |
| . = ALIGN(4); |
| __got_start = ABSOLUTE(.); |
| *(.got) *(.got.*) ; |
| __got_end = ABSOLUTE(.); |
| |
| } > ram AT > flash |
| |
| .relocs : { |
| |
| . = ALIGN(4); |
| /* relocs */ |
| __rel_start = ABSOLUTE(.); |
| *(.rel) *(.rel.*) *(.rel.data.rel.local) |
| __rel_end = ABSOLUTE(.); |
| . = ALIGN(4); |
| |
| } > flash = 0xff |
| |
| .dynsym : { |
| *(.dynsym); *(.dynsym.*); |
| } > flash = 0xff |
| |
| .bss : { |
| . = ALIGN(4); |
| __bss_start = ABSOLUTE(.); |
| *(.bss) *(.bss.*) *(COMMON); |
| . = ALIGN(4); |
| __bss_end = ABSOLUTE(.); |
| } > ram |
| |
| __data_data = LOADADDR(.data); |
| |
| .dynstr : { |
| *(.dynstr); *(.dynstr.*); |
| } > trash |
| .hash : { |
| *(.hash); *(.hash.*); |
| } > trash |
| .dynamic : { |
| *(.dynamic); *(.dynamic.*); |
| } > trash |
| |
| } |
| |
| |
| ENTRY(_mAppEntry) |