2 つの絶対記号を持つカーネル用のリンカー スクリプトがあります:_kernel_start
と_kernel_end
. ただし、リンカーの再配置エラーが発生するのは次の場合のみ_kernel_end
です。
In function `kernel::mem::mm::setup_memorymap':
/home/virtlink/kernel/src/mem/mm.rs:25:(.text._ZN3mem2mm15setup_memorymap):
relocation truncated to fit: R_X86_64_PC32 against symbol `_kernel_end'
defined in *ABS* section in ./kernel.bin
このエラーについて SO で多くの質問がありましたが、特定の問題を解決するものは見つかりませんでした。
どうやら、これ:
_kernel_start = .;
...これは32ビットとして扱われますが、これは次のとおりです。
. += KERNEL_BASE;
_kernel_end = . - KERNEL_BASE;
...64 ビットとして扱われます。_kernel_end
次のように記号を線の上に移動すると. += KERNEL_BASE
:
_kernel_end = .;
. += KERNEL_BASE;
...その後、再び機能します。_kernel_end
しかし、リンカースクリプトの最後に欲しいです。
リンカー スクリプトは、ブート コードをメモリの先頭に配置し、残りのコードを 64 ビット仮想メモリ空間の上位半分に配置します。次のようになります。
OUTPUT_FORMAT(elf64-x86-64)
KERNEL_BASE = 0xFFFFFFFF80000000;
SECTIONS
{
/* Boot code at 1 MiB */
. = 1M;
_kernel_start = .;
.boot :
{
KEEP( *(.multiboot) )
*(.boot)
*(.bootdata)
}
/* Kernel code at high virtual address. */
. += KERNEL_BASE;
.text ALIGN(4K) : AT(ADDR(.text) - KERNEL_BASE)
{
*(.text)
*(.gnu.linkonce.t*)
}
.data ALIGN(4K) : AT(ADDR(.data) - KERNEL_BASE)
{
*(.data)
*(.gnu.linkonce.d*)
}
.rodata ALIGN(4K) : AT(ADDR(.rodata) - KERNEL_BASE)
{
*(.rodata)
*(.gnu.linkonce.r*)
}
.bss ALIGN(4K) : AT(ADDR(.bss) - KERNEL_BASE)
{
*(COMMON)
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b*)
}
_kernel_end = . - KERNEL_BASE;
/DISCARD/ :
{
*(.comment)
*(.eh_frame)
}
}
カーネルは本当に小さいので_kernel_start = 0x00100000
、_kernel_end = 0x00142000
. 再配置エラーが発生することはありません。
_kernel_end
再配置エラーが発生しないようにリンカー スクリプトを書き直すにはどうすればよいですか? mcmodel=large
この1つのシンボルだけに使用したくありません。
シンボルを使用しているコードは次のとおりです。ラストです。
fn get_kernel_location() -> (*const u8, *const u8) {
extern {
static _kernel_start: u8;
static _kernel_end: u8;
}
let kernel_start: *const u8 = &_kernel_start;
let kernel_end: *const u8 = &_kernel_end;
println!("{:p}", kernel_start);
println!("{:p}", kernel_end);
(kernel_start, kernel_end)
}
以下は、Rust でコンパイルされたオブジェクト ファイルの再配置テーブルのエントリです。
Offset Info Type Sym. Value Sym. Name + Addend
000000000012 058800000009 R_X86_64_GOTPCREL 0000000000000000 _kernel_end - 4
000000000019 058900000009 R_X86_64_GOTPCREL 0000000000000000 _kernel_start - 4