[英]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的所有用户空间功能。 但是像memcpy
, strlen
, strcpyn
类的东西是绝对必要的。 您将必须自己实现这些功能,但是更好的是,您可以更改这些功能的名称。 例如,如果您更喜欢使用camelCase
作为函数名,那么还可以使用函数名,例如copyMemory
, lengthOfString
等。
https://github.com/SukantPal/Silcos-Kernel
我已经构建了自己的内核,该内核在KernelHost / Source / Util / CircuitPrimitive.cpp中具有所需功能的一些实现。 您可以调查一下。 此外,它还具有完整的模块链接器。 (KernelHost,ModuleFramework等。这些父文件夹包含单独的内核模块源代码)。
到目前为止,请确保不要在内核中使用标准的C标头。 自行实现所有必需的功能,包括printf
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.