gPXE memory layout

Currently the linker script for each arch is locate at:

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:

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 | 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