我一直在考虑将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
添加到编译器标志