190 likes | 213 Views
Executing an ELF executable. How to load an executable ELF file for execution in ‘extended’ physical memory. What is ‘Extended Memory’?. extended memory. 4GB. extended memory. 16MB. conventional memory. conventional memory. conventional memory. 1MB. 8086/8088
E N D
Executing an ELF executable How to load an executable ELF file for execution in ‘extended’ physical memory
What is ‘Extended Memory’? extended memory 4GB extended memory 16MB conventional memory conventional memory conventional memory 1MB 8086/8088 (20-bit addresses) 80286 (24-bit addresses) 80386+ (32-bit addresses)
8086/8088 addresses segment-address offset-address 0x2345 0x9876 Logical Address x16 + 0x23450 + 0x09876 --------------- 0x2CCC6 0x2CCC6 Physical Address (20-bits)
Biggest 8086/8088 address segment-address offset-address 0xFFFF 0xFFFF Logical Address x16 + 0xFFFF0 + 0x0FFFF --------------- 0x10FFEF 0x0FFEF Physical Address (20-bits) A20
Emulating 8086/8088 on 80286 • Special circuitry provided to ‘disable’ the 21st address-line (named A20) causes addresses to ‘wrap’ at the 1MB boundry • Original IBM-AT used keyboard controller to perform enabling/disabling of A20-line • Newer machines have faster ways to enable/disable A20-line (e.g., port 0x92)
Effect of A20 address-line Highest real-mode address (= 0x10FFEF) Extra 64K Same 64K Highest 20-bit address (= 0x0FFFFF) same memory appears at two places memory differs at these places “extended” memory is above 1MB “conventional” memory is below 1 MB A20 enabled A20 disabled
port 0x92 7 6 5 4 3 2 1 0 FAST A20 FAST RESET (These bits may implement some other system functions, depending on the vendor’s design (not standardized), so beware of modifying them in ‘portable’ system software reset the CPU (1=yes, 0=no) # how you can turn on the A20 address-line in $0x92, %al or $0x02, %al out %al, $0x92 enable A20-line (1=yes, 0=no)
Comparing A20 on/off 0x00A00000 9999999999999 8888888888888 0x00900000 8888888888888 8888888888888 0x00800000 7777777777777 6666666666666 0x00700000 6666666666666 6666666666666 0x00600000 5555555555555 4444444444444 0x00500000 4444444444444 4444444444444 0x00400000 3333333333333 2222222222222 0x00300000 2222222222222 2222222222222 0x00200000 1111111111111 0000000000000 0x00100000 0000000000000 0000000000000 0x00000000 Extended Memory seen by the CPU when A20 is on Extended Memory seen by the CPU when A20 is off Memory-addresses in one-megabyte increments
‘Executable’ versus ‘Linkable’ ELF Header ELF Header Program-Header Table (optional) Program-Header Table Section 1 Data Segment 1 Data Section 2 Data Segment 2 Data Section 3 Data Segment 3 Data … Section n Data … Segment n Data Section-Header Table Section-Header Table (optional) Linkable File Executable File
Linker ‘relocates’ addresses ELF Header ELF Header Section 1 Data Program-Header Table Section 2 Data … Section n Data Segment 1 Data Section-Header Table Segment 2 Data Linkable File … Segment n Data ELF Header Section 1 Data Section 2 Data Executable File … Section n Data Section-Header Table Linkable File
The ‘built-in’ linker script • Two main ideas that the linker implements: • It combines identically-named sections of the linkable ELF files into a single segment • It assigns runtime addresses to the resulting program data and program code which are non-conflicting and are suitably aligned • It may optionally perform other manipulations, depending on directions in its linker script • It uses a built-in linker script if you don’t specify otherwise; you can view it using the command-option: $ ld -verbose
ELF32 File Header 32-bit or 64-bit Initial value for EIP register ΔELF class type program entry-point PHT file-offset PHT entry size PHT entry count PHT = Program-segment Header-Table ‘Executable’ or ‘Linkable’
PHT entries Fields in an ELF32 Program-segment Header Table entry p_type p_offset p_vaddr p_paddr p_filesz p_memsz p_flags p_align Our ‘elfexec.s’ program-loader uses these highlighted fields to simulate program-loading (i.e., to initialize the regions in Extended memory which are needed for program execution
In-Class demo • Suppose we want to execute ‘linuxapp’ using our own custom OS environment • Boot-disk preparation steps: $ as –32 linuxapp.s –o linuxapp.o $ ld –melf_i386 linuxapp.o –o linuxapp $ dd if=linuxapp of=/dev/sda4 seek=65 • We’ll need modifications to our ‘tryelf32.s’
The two program-segments • When used without any linker script, our GNU linker-utility (‘ld’) relocates the ‘.text’ and ‘.data’ and ‘.bss’ program-segments, for residence at specific memory-addreses far above the 1-MB conventional ‘real-mode’ memory-area • The memory-address 0x08048000 is standard for the relocation of an Elf_32 code-segment • So we will need to ‘copy’ some portions of the executable ELF-file’s contents to the specified addresses in ‘Extended’ physical memory
New segment-descriptors • We can setup segment-limits of size 4GB using Descriptor Privilege Level (DPL) =3 • For our (32-bit) data-segment: .quad 00CFF2000000FFFF # 4GB-data • For our (32-bit) code-segment: .quad 00CF7A000000FFFF # 4GB-code • Both these segments include all memory • It’s useful to mark code as ‘Not Present’
Initial values for ESP and EIP • The program’s entry-point is obtained from the .e_entry; field in the ELF-file’s Header) • The decision about an initial value for ESP is largely up to us, taking into account the amount of physical memory installed and the regions of memory already being used for other system purposes
Where’s our ring3 stack? ESP 0x40000000 (at 1-GB) ring3 stack .bss .data 0x08049000 EIP .text 0x08048000 Our OS 0x00010000 IVT and BDA 0x00000000
Demos • Our ‘elfexec.s’ program demonstrates the simulation of ‘on-demand loading’ for two ‘executable’ ELF32 files on our website: • ‘linuxapp’ (which we’ve used previously) • ‘usingbss’ (which illustrates ‘.bss’ loading) • Our ‘elfinfo.cpp’ utility aids in examining an ELF32 files’s PHT entries and entry-point