为什么elf文件有这么多未使用/浪费的空间



我一直在考虑将elf文件加载到内存中,但在此过程中,我发现文件中有大量未使用的空间。

这是我得到的elf文件https://cyao.page/kernel.elf (~2.1Mib),这是我的链接器脚本:

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

当您查看程序头(地址0x40)中的p_offset时,您将看到偏移量为0x200000,并且在所有节表中,所有它们的偏移量都大于0x200000

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

它不应该是对齐,因为它对齐到0x1000,而不是0x200000。

现在的问题是:0x78(报头的结束)到0x200000的空间是用来做什么?整整浪费了2兆!(是的,这是很多相比之下,我只保留512mb的内存为我的内核)

这是我的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 $@

完整的makefile可以在这里查看https://github.com/cheyao/AchieveOS/blob/master/Makefile

感谢michael Petch在他们的评论中,解决方案是将-z max-page-size=0x1000添加到编译器标志

相关内容

  • 没有找到相关文章

最新更新