我正在编写一个具有键盘/光标支持的小型内核。在我从unistd.h添加一个函数之前,一切都很好
kernel.c
#include "keyboard_map.h"
#include "keyboard.c"
#include "video.c"
#include <unistd.h>
void kmain(void)
{
terminal_initialize();
terminal_writestring("Hello, kernel World!\n");
idt_init();
kb_init();
kprint_newline();
writeSector();
sleep(1);
unsigned char c = readSector2();
kprint((const char *)c);
while(1);
}kernel.asm
bits 32
%define COLS 80
section .text
;multiboot spec
align 4
dd 0x1BADB002 ;magic
dd 0x00 ;flags
dd - (0x1BADB002 + 0x00) ;checksum. m+f+c should be zero
global start
global keyboard_handler
global read_port
global write_port
global load_idt
extern kmain ;this is defined in the c file
extern keyboard_handler_main
read_port:
mov edx, [esp + 4]
;al is the lower 8 bits of eax
in al, dx ;dx is the lower 16 bits of edx
ret
write_port:
mov edx, [esp + 4]
mov al, [esp + 4 + 4]
out dx, al
ret
load_idt:
mov edx, [esp + 4]
lidt [edx]
sti ;turn on interrupts
ret
keyboard_handler:
call keyboard_handler_main
iretd
start:
cli ;block interrupts
mov esp, stack_space
call kmain
hlt ;halt the CPU
section .bss
resb 8192; 8KB for stack
stack_space:link.ld
OUTPUT_FORMAT(elf32-i386)
ENTRY(start)
SECTIONS
{
. = 0x100000;
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss) }
}我正在用gcc交叉编译器通过终端编译它,并在qemu上运行它。
nasm -f elf /Users/par/Desktop/kernel.asm -o kasm.o
/usr/local/gcc-4.8.1-for-linux32/bin/i586-pc-linux-gcc -m32 -c -std=c99 /Users/par/Documents/HelloC/HelloC/kernel.c -o kc.o
/usr/local/gcc-4.8.1-for-linux32/bin/i586-pc-linux-ld -m elf_i386 -T /Users/par/Desktop/link.ld -o kernel kasm.o kc.o
qemu-system-i386 -kernel kernel我刚开始使用c++编程,所以希望这对其他人来说是个简单的问题。该项目中还有其他几个c文件,但我相信问题肯定在上面的某个地方。同样,如果移除unistd.h和when (),一切都会正常工作,但是当试图与该引用链接时,会产生一个错误,即“kc.o中函数睡眠()的未定义引用”。
此外,这些参考资料在项目的其他地方也很有用.
#include <stddef.h>
#include <stdint.h> ...which进一步迷惑了我为什么Unist.h不链接..。但会编译。
发布于 2015-12-09 19:53:49
包含unistd.h只是告诉编译器一些事情(函数等)。在库中定义的。它描述了库的接口,而不是库功能的实现。
这就是为什么你的程序编译。H中有一个睡眠()声明。它看起来可能是这样的:
unsigned sleep(unsigned);你可以看看,这是个文本文件。
问题是,当您尝试链接时,没有什么定义睡眠()。通常,预编译库中存在睡眠()和其他标准函数。名为libc.a的.a文件是包含实现库功能的对象文件的存档,链接器可以将其链接到您的对象文件,以解析对睡眠()之类事物的引用。
Hstdint.h之所以工作,是因为它们主要定义在编译时使用的类型和宏,但不需要在链接时使用任何额外的对象代码。
您的链接线不包括任何库。我怀疑那是因为你的裸金属环境没有。
你有几个选择。您可以尝试移植一个已存在的库以在您的环境中工作,或者您可以编写自己的try ()函数。
您可以看看ELLCC,它是提供库的(几个)交叉开发工具链之一。ELLCC的裸金属库是一项正在进行的工作,但看看麋鹿博客帖子可能会给你一些想法。
https://stackoverflow.com/questions/34184743
复制相似问题