如何控制通过grub从磁盘加载到内存的内容量?

问题描述

我正在使用由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在这里。


您可能要查看的另一个选项是使用多重引导模块。将文件作为模块可能是一种更简单的方法,但是使您对文件的加载位置/方式的控制较少。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...