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