這就是問題所在:
當我用C鏈接到我的腳本,使用LD,當我產生ELF32-I386文件在LD輸出格式,把它作爲OUTPUT_FORMAT()在ld腳本中,我沒有任何錯誤,但是如果我嘗試放入這最後一個OUTPUT_FORMAT()「二進制文件」或嘗試輸出帶.bin擴展名的文件,我會得到如下錯誤的混合:未定義參考_GLOBAL_OFFSET_TABLE_(僅當生成的二進制文件)
kernel.o: In function `k_main':
kernel.c:(.text+0xe): undefined reference to `_GLOBAL_OFFSET_TABLE_'
kernelutils.o: In function `k_clear_screen':
kernelutils.c:(.text+0xc): undefined reference to `_GLOBAL_OFFSET_TABLE_'
kernelutils.o: In function `k_clear_screen_front':
kernelutils.c:(.text+0x56): undefined reference to `_GLOBAL_OFFSET_TABLE_'
kernelutils.o: In function `k_printf':
kernelutils.c:(.text+0xa0): undefined reference to `_GLOBAL_OFFSET_TABLE_'
kernelutils.o: In function `k_sleep_3sec':
kernelutils.c:(.text+0x152): undefined reference to `_GLOBAL_OFFSET_TABLE_'
kernelmalloc.o:kernelmalloc.c:(.text+0xc): more undefined references to `_GLOBAL_OFFSET_TABLE_' follow
這不僅發生在編譯特定腳本,所有嘗試使用ld鏈接的腳本或gcc(因爲這會調用ld),而是在嘗試獲取擴展名爲.bin的二進制文件時發生。
當顯示其中一個可執行文件(在上面的輸出中的kernel.o)的符號時,我看到符號_GLOBAL_OFFSET_TABLE_未定義,並且是最可怕的部分,所有在上面的錯誤輸出中返回錯誤的函數都有它們的符號消失,這是nm輸出:
[email protected]:~/Desktop/kernel/0.0.3/Archivos$ nm kernel.o
U _GLOBAL_OFFSET_TABLE_
U k_clear_screen
U k_clear_screen_front
00000000 T k_main
U k_malloc
U k_printf
U k_sleep_3sec
00000000 T __x86.get_pc_thunk.bx
我該如何解決這個問題?我將在下面保留鏈接器腳本,以確保它不是.ld文件的問題,同時包含「獲取elf」和「獲取二進制」版本。提前致謝!
Ld的腳本:
爲了得到二進制:
ENTRY(loader)
OUTPUT_FORMAT(binary)
SECTIONS {
/* The kernel will live at 3GB + 1MB in the virtual
address space, which will be mapped to 1MB in the
physical address space. */
. = 0xC0100000;
.text : AT(ADDR(.text) - 0xC0000000) {
*(.text)
*(.rodata*)
}
.data ALIGN (0x1000) : AT(ADDR(.data) - 0xC0000000) {
*(.data)
}
.bss : AT(ADDR(.bss) - 0xC0000000) {
_sbss = .;
*(COMMON)
*(.bss)
_ebss = .;
}
}
要獲取ELF:
ENTRY(loader)
OUTPUT_FORMAT(elf32-i386)
SECTIONS {
/* The kernel will live at 3GB + 1MB in the virtual
address space, which will be mapped to 1MB in the
physical address space. */
. = 0xC0100000;
.text : AT(ADDR(.text) - 0xC0000000) {
*(.text)
*(.rodata*)
}
.data ALIGN (0x1000) : AT(ADDR(.data) - 0xC0000000) {
*(.data)
}
.bss : AT(ADDR(.bss) - 0xC0000000) {
_sbss = .;
*(COMMON)
*(.bss)
_ebss = .;
}
}
由於喲天亞社之間都只有改變OUTPUT_FORMAT()行見。
看起來像您的主機GCC環境(可能是Ubuntu 16.04+或Debian 9+之類的更新版本)正在生成與位置無關的代碼。當你用_GCC_編譯時,你可能想用'-fno-pic'編譯所有的文件。這是使用GCC交叉編譯器進行操作系統開發的一個很好的理由。你可以閱讀關於創建一個在這裏:http://wiki.osdev.org/GCC_Cross-Compiler –
謝謝,我將建立交叉編譯器 – Rottenheimer2
在旁註 - 爲什麼你生成一個二進制文件?我知道你以前使用的是一個多引導兼容加載器。使用二進制文件可能會導致你的問題,除非你現在正在編寫你自己的引導程序,或者你改變了你的多引導頭來支持a.out kludge。 –