簡體   English   中英

從ASM調用的C ++代碼中的標准庫的鏈接

[英]Linkage of standard libraries in C++ code called from ASM

當我開發“ OsDev”項目時,我正在學習一個新的東西(對於那些由於Web開發很長時間沒有用C / C ++編寫代碼的人來說,這有點“新”)。 我在另一個線程中發現,從ASM調用C ++函數需要有一個extern "C"前綴,但是現在我對標准庫的內襯(例如cstdio等)有疑問。我堅持此消息。

kc.o: In function `kmain':
kernel.cpp:(.text+0x3e4): undefined reference to `strlen`

C ++

#include <string.h>
#include <cstdio>

#include "inc/screen.h"

extern "C" void kmain()
{
    clearScreen();
    kernel_print((char*)"Hello Github! :-)", 0x04);
}

如果我嘗試使用strlen() ,它將不會鏈接。 (順便說一句,包括screen.h由於某種原因在工作)。 編譯腳本

nasm -f elf32 kernel.asm -o kasm.o
g++ -c kernel.cpp -o kc.o -lgcc -m32  -Wall -Wextra -O2
ld -m elf_i386 -T link.ld -o kernel.bin kasm.o kc.o

鏈接

OUTPUT_FORMAT(elf32-i386)
ENTRY(start)
SECTIONS
 {
   . = 0x100000;
   .text : { *(.text) }
   .data : { *(.data) }
   .bss  : { *(.bss)  }
 }

感謝您的任何建議。 :)

您的代碼無法工作,因為內核無法直接使用共享庫。

為什么我不能直接在內核中使用共享庫?

當操作系統加載應用程序時,所有必需的文件都被帶入其地址空間。 這包括可執行文件和任何動態庫(所有符合ABI的ELF應用程序將始終與系統庫-C標准庫或libc鏈接 )。

但是在加載內核時,僅加載原始可執行文件。 Multiboot 2(使用GRUB bootloader)將允許您加載可以是動態庫的內核模塊 但是,內核仍然必須知道如何鏈接自身和物理內存中的內核模塊。 為此,您必須在內核中實現ELF解析器和動態鏈接器。

在實施內核之前,請確保您的內核足夠成熟,可以系統地處理動態內存分配,分頁和其他基本功能。

如何使用libc的功能?

通常,您不會使用libc的所有用戶空間功能。 但是像memcpystrlenstrcpyn類的東西是絕對必要的。 您將必須自己實現這些功能,但是更好的是,您可以更改這些功能的名稱。 例如,如果您更喜歡使用camelCase作為函數名,那么還可以使用函數名,例如copyMemorylengthOfString等。

https://github.com/SukantPal/Silcos-Kernel

我已經構建了自己的內核,該內核在KernelHost / Source / Util / CircuitPrimitive.cpp中具有所需功能的一些實現。 您可以調查一下。 此外,它還具有完整的模塊鏈接器。 (KernelHost,ModuleFramework等。這些父文件夾包含單獨的內核模塊源代碼)。

到目前為止,請確保不要在內核中使用標准的C標頭。 自行實現所有必需的功能,包括printf

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM