问题描述
我正在使用由grub引导的玩具OS。
但是,内核映像中的某些部分(尤其是原始内核映像的目标文件)在引导时未加载到物理内存中。 (即,跳转到内核小精灵定义的ENTRY之后)
这是一些问题。
是什么决定由grub从磁盘加载到内存中的内容大小的大小?我可以配置它吗?
或者大小是固定的,我是否应该从磁盘上手动读取其余部分?
################更新###############
There are 21 section headers,starting at offset 0x279bfc:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 01000000 001000 009a79 00 AX 0 0 16
[ 2] .rodata PROGBITS 0100a000 00b000 0012b0 00 A 0 0 4096
[ 3] .eh_frame PROGBITS 0100b2b0 00c2b0 0041b0 00 A 0 0 4
[ 4] .data PROGBITS 02000000 011000 002400 00 WA 0 0 4096
[ 5] .bss NOBITS 02002400 013400 108430 00 WA 0 0 1024
[ 6] .percpu_data PROGBITS 0210a880 11b880 002880 00 WA 0 0 4096
[ 7] .comment PROGBITS 00000000 11e100 000011 01 MS 0 0 1
[ 8] .debug_aranges PROGBITS 00000000 11e118 000620 00 0 0 8
[ 9] .debug_info PROGBITS 00000000 11e738 011352 00 0 0 1
[10] .debug_abbrev PROGBITS 00000000 12fa8a 004750 00 0 0 1
[11] .debug_line PROGBITS 00000000 1341da 00577b 00 0 0 1
[12] .debug_str PROGBITS 00000000 139955 00403c 01 MS 0 0 1
[13] .debug_loc PROGBITS 00000000 13d991 008966 00 0 0 1
[14] .debug_ranges PROGBITS 00000000 1462f7 000840 00 0 0 1
[15] .part1 PROGBITS 0c000000 147000 096ba8 00 A 0 0 1
[16] .part2 PROGBITS 0c100000 1de000 096b58 00 A 0 0 1
[17] .srtos_conf PROGBITS 0c1a0000 275000 00064f 00 A 0 0 1
[18] .symtab SYMTAB 00000000 275650 002780 10 19 157 4
[19] .strtab STRTAB 00000000 277dd0 001d64 00 0 0 1
[20] .shstrtab STRTAB 00000000 279b34 0000c7 00 0 0 1
Key to Flags:
W (write),A (alloc),X (execute),M (merge),S (strings),I (info),L (link order),O (extra OS processing required),G (group),T (TLS),C (compressed),x (unknown),o (OS specific),E (exclude),p (processor specific)
Elf file type is EXEC (Executable file)
Entry point 0x1000038
There are 2 program headers,starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x001000 0x01000000 0x01000000 0x0f460 0x0f460 R E 0x1000
LOAD 0x011000 0x02000000 0x02000000 0x10d100 0x10d100 RW 0x1000
Section to Segment mapping:
Segment Sections...
00 .text .rodata .eh_frame
01 .data .bss .percpu_data
特别是,我希望GRUB加载.part1
,.part2
和.srtos_conf
部分。
我猜他们没有被加载,因为它们不是程序头文件的一部分。
如何将这些部分添加为程序标题?
当前,它们使用objcopy --add-section XXX
合并到内核,并且段标志为alloc,readonly,load,contents
。
我必须使用哪个选项将这些部分添加到程序头中?
解决方法
向ELF添加新节的objcopy方法似乎太受限制。 https://reverseengineering.stackexchange.com/a/14780表示不可能 以这种方式添加程序头条目。
相反,我建议使用objcopy为.part1
等创建目标文件,
然后在构建kernel.elf时将它们指定为链接器的其他输入。 Objcopy将放置文件
.data
部分中的内容,并会创建符号
_binary_x_start
/ _binary_x_end
/ _binary_x_size
为方便起见。
例如:
使用任何类型的文件创建目标文件(替换目标三元组):
i686-elf-objcopy --input binary -B i386 -O elf32-i386 x x.o
在链接器输入中添加x.o会扩展.data
输出部分,以包含
文件内容,自然导致加载程序将其加载。
如果需要,您可以使用链接器脚本来控制文件的加载位置。 (带有正确参数的objcopy也可以为您执行此操作,但是有一个链接描述文件 通常是一种更清洁的方法。
例如,要将文件专门放置在0x200000,可以执行以下操作:
/* ... */
.data : {
*(EXCLUDE_FILE(x.o) .data)
}
. = 0x0200000;
.foo : {
x.o (.data)
}
/* ... */
当然,您也可以在目标文件中重命名该部分,以避免
EXCLUDE_FILE
在这里。
您可能要查看的另一个选项是使用多重引导模块。将文件作为模块可能是一种更简单的方法,但是使您对文件的加载位置/方式的控制较少。