==== gPXE memory layout ====
Currently the linker script for each arch is locate at:
* ''src/arch/x86/scripts/efi.lds''
* ''src/arch/i386/scripts/i386-kir.lds''
* ''src/arch/i386/scripts/i386.lds''
We can reference ''src/arch/i386/README.i386'' for the difference
between ''i386-kir.lds'' and ''i386.lds'', the ''efi.lds'' should
be obvious as its file name that is for Extensible Firmware Interface
(EFI). In this note we take the binary linked against
''src/arch/i386/scripts/i386.lds'' linker script for instance.
\\
To see the memory layout of an target image, for instance ''gpxe.pxe'',
the all driver PXE loadable image. Use one of the following command:
* objdump -h bin/gpxe.pxe.tmp
* readelf -S bin/gpxe.pxe.tmp
It can tell you each section's size and where it will put in the memory
while execution(VMA).
== objdump -h bin/gpxe.pxe.tmp ==
bin/gpxe.pxe.tmp: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .prefix 0000081a 00000000 00000000 00000160 2**4
CONTENTS, ALLOC, LOAD, CODE
1 .text16 00000854 00000000 00000820 00000980 2**4
CONTENTS, ALLOC, LOAD, CODE
2 .data16 000004a2 00000000 00001080 000011e0 2**4
CONTENTS, ALLOC, LOAD, DATA
3 .bss.data16 000029a0 000004a8 000963f0 00096540 2**3
ALLOC
4 .textdata 00094e7c 00000000 00001530 00001684 2**2
CONTENTS, ALLOC, LOAD, CODE
5 .bss.textdata 00058b68 00094e80 000963f0 00096580 2**7
ALLOC
6 .zinfo 00000040 00000000 000963b0 00096500 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .debug_abbrev 000346c3 00000000 00000000 00096540 2**0
CONTENTS, READONLY, DEBUGGING
8 .debug_info 002274b7 00000000 00000000 000cac03 2**0
CONTENTS, READONLY, DEBUGGING
9 .debug_line 000384b6 00000000 00000000 002f20ba 2**0
CONTENTS, READONLY, DEBUGGING
10 .debug_frame 0001953c 00000000 00000000 0032a570 2**2
CONTENTS, READONLY, DEBUGGING
11 .debug_loc 00091542 00000000 00000000 00343aac 2**0
CONTENTS, READONLY, DEBUGGING
12 .debug_pubnames 0000fffd 00000000 00000000 003d4fee 2**0
CONTENTS, READONLY, DEBUGGING
13 .debug_aranges 00002460 00000000 00000000 003e4feb 2**0
CONTENTS, READONLY, DEBUGGING
14 .debug_ranges 00006f58 00000000 00000000 003e744b 2**0
CONTENTS, READONLY, DEBUGGING
15 .debug_str 0003c4ef 00000000 00000000 003ee3a3 2**0
CONTENTS, READONLY, DEBUGGING
\\
To see each symbol's memory location, use one of the following command:
* objdump -t bin/gpxe.pxe.tmp
* readelf -s bin/gpxe.pxe.tmp
== objdump -t bin/gpxe.pxe.tmp | sort -k1 | tail -n 30 ==
000ec9e4 g O .bss.textdata 00000000 .hidden obj_dhcppkt
000ec9e4 g O .bss.textdata 00000000 .hidden obj_eapol
000ec9e4 g O .bss.textdata 00000000 .hidden obj_editstring
000ec9e4 g O .bss.textdata 00000000 .hidden obj_hmac
000ec9e4 g O .bss.textdata 00000000 .hidden obj_ib_mcast
000ec9e4 g O .bss.textdata 00000000 .hidden obj_ib_pathrec
000ec9e4 g O .bss.textdata 00000000 .hidden obj_icmp
000ec9e4 g O .bss.textdata 00000000 .hidden obj_iwmgmt
000ec9e4 g O .bss.textdata 00000000 .hidden obj_iwmgmt_cmd
000ec9e4 g O .bss.textdata 00000000 .hidden obj_job
000ec9e4 g O .bss.textdata 00000000 .hidden obj_linebuf
000ec9e4 g O .bss.textdata 00000000 .hidden obj_monojob
000ec9e4 g O .bss.textdata 00000000 .hidden obj_readline
000ec9e4 g O .bss.textdata 00000000 .hidden obj_sec80211
000ec9e4 g O .bss.textdata 00000000 .hidden obj_sha1
000ec9e4 g O .bss.textdata 00000000 .hidden obj_sha1extra
000ec9e4 g O .bss.textdata 00000000 .hidden obj_smbios
000ec9e4 g O .bss.textdata 00000000 .hidden obj_tcp
000ec9e4 g O .bss.textdata 00000000 .hidden obj_wep
000ec9e4 g O .bss.textdata 00000000 .hidden obj_wpa
000ec9e4 g O .bss.textdata 00000000 .hidden obj_wpa_ccmp
000ec9e4 g O .bss.textdata 00000000 .hidden obj_wpa_psk
000ec9e4 g O .bss.textdata 00000000 .hidden obj_wpa_tkip
000ec9e8 g .bss.textdata 00000000 _stack
000ed9e8 g *ABS* 00000000 _textdata_memsz
000ed9e8 g .bss.textdata 00000000 _estack
000ed9e8 g .bss.textdata 00000000 .hidden _etextdata
00400000 g *ABS* 00000000 HIGHMEM_LOADPOINT
bin/gpxe.pxe.tmp: file format elf32-i386
SYMBOL TABLE:
==== Memory usage ====
We can see the current memory usage by the symbols
exported by linker. Which is defined in the linker
script mentioned in the previours section.
For ''i386.lds'', if we want to know how much memory
was used. We can simply check for _etextdata, or _stack.
The heap was declared as globle variable in ''src/core/malloc.c'',
which would put in bss section. We can get its address by:
== objdump -t bin/gpxe.pxe.tmp | grep ' heap$' ==
000b3c5c l O .bss.textdata 00020000 heap
As long as the _stack plus real stack usage at runtime dose
not exceed 1MB, we should be safe.
We can also exam the what symbol cost most memory size by:
== readelf -W -s bin/gpxe.pxe.tmp | sort -n -k 3 | tail ==
463: 0007c7a4 6104 OBJECT LOCAL DEFAULT 5 bnx2_rv2p_proc2
1337: 000a505c 6320 OBJECT LOCAL DEFAULT 6 rxb
3869: 00091738 8192 OBJECT GLOBAL HIDDEN 5 linda_ib_fw
1351: 000a6f4c 9084 OBJECT LOCAL DEFAULT 6 rx_buffer
391: 00094e9c 9348 OBJECT LOCAL DEFAULT 6 amd8111e
469: 00083838 22348 OBJECT LOCAL DEFAULT 5 bnx2_TXP_b06FwText
479: 0008a1b4 22464 OBJECT LOCAL DEFAULT 5 bnx2_COM_b06FwText
464: 0007df7c 22672 OBJECT LOCAL DEFAULT 5 bnx2_RXP_b06FwText
461: 00099874 41848 OBJECT LOCAL DEFAULT 6 bnx2_bss
1344: 000a92c8 43064 OBJECT LOCAL DEFAULT 6 virtqueue
The number bigger than 5 digits in decimal, were displayed as hex.
== readelf -W -s bin/gpxe.pxe.tmp | grep ' 0x[0-9]\+ ' ==
2052: 000b3c5c 0x20000 OBJECT LOCAL DEFAULT 6 heap
3141: 000d4100 0x18808 OBJECT GLOBAL HIDDEN 6 _shared_bss