3

I've been looking at loading a elf file into the memory, but in the process, I've found out that there is huge chunk of unused space in the file.

This is the elf file i got https://cyao.page/kernel.elf (~2.1Mib) and this is my linker script:

ENTRY(start)
OUTPUT_FORMAT(elf64-x86-64)

SECTIONS {
    . = 0xC00000;
    phys = .;

    .text ALIGN(0x1000): {
        code = .;
        *(.text)
        . = ALIGN(0x1000);
    }

    .rodata ALIGN(0x1000): {
        *(.rodata*)
        . = ALIGN(0x1000);
    }

    .data ALIGN(0x1000): {
        data = .;
        *(.data)
        . = ALIGN(0x1000);
    }

    .bss ALIGN(0x1000): {
        bss = .;
        *(.bss)
        . = ALIGN(0x1000);
    }

    end = .; _end = .; __end = .;

    /DISCARD/ : {
        *(.comment)
        *(.note.gnu.build-id)
    }
}

When I you look at the p_offset in the program header (in adress 0x40), you will see that the offset is 0x200000, and in all the section tables, all their's offset are bigger then 0x200000

The same goes with x86_64-elf-objdump

cdcontents/!kernel.bin:     file format elf64-x86-64
cdcontents/!kernel.bin
architecture: i386:x86-64, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x000000000c000000

Program Header:
    LOAD off    0x0000000000200000 vaddr 0x000000000c000000 paddr 0x000000000c000000 align 2**12
         filesz 0x0000000000009384 memsz 0x000000000000b000 flags rwx

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         00006000  000000000c000000  000000000c000000  00200000  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .text.startup 00000094  000000000c006000  000000000c006000  00206000  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .data         00001000  000000000c007000  000000000c007000  00207000  2**5
                  CONTENTS, ALLOC, LOAD, DATA
  3 .rodata       00001000  000000000c008000  000000000c008000  00208000  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .eh_frame     00000384  000000000c009000  000000000c009000  00209000  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .bss          00001000  000000000c00a000  000000000c00a000  00209384  2**5
                  ALLOC
  6 .debug_info   000035be  0000000000000000  0000000000000000  00209384  2**0
                  CONTENTS, READONLY, DEBUGGING, OCTETS
  7 .debug_abbrev 00000db5  0000000000000000  0000000000000000  0020c942  2**0
                  CONTENTS, READONLY, DEBUGGING, OCTETS
  8 .debug_loclists 00006865  0000000000000000  0000000000000000  0020d6f7  2**0
                  CONTENTS, READONLY, DEBUGGING, OCTETS
  9 .debug_aranges 000001b0  0000000000000000  0000000000000000  00213f5c  2**0
                  CONTENTS, READONLY, DEBUGGING, OCTETS
 10 .debug_rnglists 0000059a  0000000000000000  0000000000000000  0021410c  2**0
                  CONTENTS, READONLY, DEBUGGING, OCTETS
 11 .debug_line   00002046  0000000000000000  0000000000000000  002146a6  2**0
                  CONTENTS, READONLY, DEBUGGING, OCTETS
 12 .debug_str    000005f3  0000000000000000  0000000000000000  002166ec  2**0
                  CONTENTS, READONLY, DEBUGGING, OCTETS
 13 .debug_line_str 0000015c  0000000000000000  0000000000000000  00216cdf  2**0
                  CONTENTS, READONLY, DEBUGGING, OCTETS

It shouldn't be the alignment since its aligned to 0x1000, not 0x200000.

Now the problem is: What is the space 0x78 (end of the headders) to 0x200000 used for? thats a whole 2 Mib wasted! (yea it's a lot compared to that i only reserved 512 Mib of memory for my kernel)

Here is a reduced version of my makefile:

C_SOURCES = $(wildcard lib/*.c) $(wildcard libc/*.c)
HEADERS = $(wildcard include/*.h) $(wildcard include/kernel/*.h)
OBJ = ${C_SOURCES:.c=.o} lib/idtr.o asmlib/memmove.o asmlib/memcpy.o asmlib/unalignedisfaster.o asmlib/instrset.o \
       asmlib/cputype.o asmlib/cachesize64.o

CFLAGS = -O2 -std=gnu11 -g -static -Wall -Wextra -Werror -Wno-unused-function \
         -Wno-unused-parameter -nostartfiles -Wno-unused-but-set-variable  \
         -Wstrict-prototypes -Wpointer-arith -Wcast-align -Wwrite-strings -Wshadow \
         -fno-stack-protector -Wundef -nostdlib -fno-builtin -nodefaultlibs \
         -fms-extensions -ffreestanding -mcmodel=large -fverbose-asm -nostartfiles \
         -mno-red-zone -mno-mmx -mno-sse -mno-sse2 -Iinclude -Wfloat-equal

all: kernel.bin

kernel.bin: lib/kernel_start.o ${OBJ}
    x86_64-elf-gcc -o $@ $^ -T link.ld -ffreestanding -O2 -nostdlib -lgcc

%.o: %.c
    x86_64-elf-gcc ${CFLAGS} -c $< -o $@

%.o: %.asm
    nasm $< -f elf64 -o $@

for the full makefile you can look here https://github.com/cheyao/AchieveOS/blob/master/Makefile

Cyao
  • 727
  • 4
  • 18
  • 1
    What happens if you link the kernel with the `-z max-page-size=0x1000` option? – Michael Petch Dec 04 '22 at 09:09
  • @MichaelPetch Still the same, no changes – Cyao Dec 04 '22 at 10:56
  • What size is your file? Links are fine for additional info, the question should still make sense if the links are all dead. So the linker script needs to be in your question in a `code block`, and some basic stuff about the ELF file needs to be in the question, too, like its size. – Peter Cordes Dec 04 '22 at 14:48
  • There you go, although dunno how it will help solve my question ¯\\_(ツ)_/¯ – Cyao Dec 04 '22 at 15:06
  • It helps because people who would otherwise not have bothered to look at your question or the linker script might now have a look over it. – Peter Cordes Dec 04 '22 at 15:13
  • Can you show us the commands you use to link to `kernel.elf` – Michael Petch Dec 04 '22 at 15:25
  • added the makefile – Cyao Dec 04 '22 at 15:42
  • So you added `-z max-page-size=0x1000` to the command `x86_64-elf-gcc -o $@ $^ -T link.ld -ffreestanding -O2 -nostdlib -lgcc` and it didn't change anything? – Michael Petch Dec 04 '22 at 15:46
  • Ahh wait I just retried and it worked! now the blank is just 0x7* - 0x1000! I think i forgot to `make clean` last time. Thx for the solution! – Cyao Dec 04 '22 at 15:49
  • 2
    Just a note: you should _never_ use `objdump` on ELF files: https://stackoverflow.com/a/22188584/50617 – Employed Russian Dec 04 '22 at 16:33

1 Answers1

0

Thanks to Michal Petch in their comment, the solution is to add -z max-page-size=0x1000 to the compiler flags

cigien
  • 57,834
  • 11
  • 73
  • 112
Cyao
  • 727
  • 4
  • 18