自制内核GDT/IDT加载器链接报错:undefined reference to memset/memcpy
解决自制内核中
memcpy/memset未定义引用的问题 嘿,这个坑我当初写第一个x86内核的时候也踩过!其实原因很简单——你现在是在裸机内核环境里,标准C库的memset、memcpy这些函数根本没法直接用,哪怕你包含了<string.h>也没用。
为什么会报错?
<string.h>只是提供了这些函数的声明,而它们的实现属于标准C库(比如glibc),这些实现依赖用户态的系统调用、进程环境等,而你的内核是直接跑在硬件上的,没有加载任何用户态库,所以链接器ld找不到这些函数的具体实现代码,自然会报“undefined reference”。
解决办法:自己实现基础内存操作函数
内核里需要的内存操作逻辑其实很简单,完全可以自己写轻量版的实现,不用依赖标准库。
1. 实现memset
在你的内核代码里(比如common.c或者新建一个mem_utils.c)添加以下代码:
#include "common.h" #include <stdint.h> void* memset(void* ptr, int value, size_t num) { // 转换成无符号char指针,按字节操作 unsigned char* p = (unsigned char*)ptr; while (num-- > 0) { *p++ = (unsigned char)value; } return ptr; }
2. 实现memcpy
同样在同一个文件里添加:
void* memcpy(void* dest, const void* src, size_t num) { unsigned char* d = (unsigned char*)dest; const unsigned char* s = (const unsigned char*)src; while (num-- > 0) { *d++ = *s++; } return dest; }
3. 编译链接时包含这些文件
确保把实现这些函数的.c文件和你的desc_tables.c一起编译,比如你的编译命令可能是:
gcc -m32 -ffreestanding -c desc_tables.c -o desc_tables.o gcc -m32 -ffreestanding -c common.c -o common.o ld -m elf_i386 -T linker.ld desc_tables.o common.o -o kernel.bin
(注意-ffreestanding参数,告诉gcc我们是在独立环境下编译,不需要依赖标准库的启动代码)
额外提醒
如果后续还遇到类似标准库函数未定义的问题,比如memcmp之类的,都可以用同样的思路——自己实现轻量版的内核专用函数,毕竟内核环境不需要标准库那些复杂的兼容性处理,满足自己的需求就行。
内容的提问来源于stack exchange,提问作者권민수
相关产品推荐
相关产品推荐

