gpt4 book ai didi

c - 内核编译但不会与 unistd.h 引用链接

转载 作者:行者123 更新时间:2023-11-30 15:14:05 24 4
gpt4 key购买 nike

我正在编写一个支持键盘/光标的小内核。一切都工作得很好,直到我添加了 unistd.h 中的函数

内核.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);
}

内核.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:

链接.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 和 sleep(),一切都会正常,但在尝试链接该引用时会产生一个错误,提示“未定义对 kc.o 中函数 sleep() 的引用”。

此外,这些引用在项目的其他地方也可以正常工作......

 #include <stddef.h> 
#include <stdint.h>

...这让我更加困惑为什么 unistd.h 不会链接...但会编译。

最佳答案

包含 unistd.h 只是告诉编译器有关库中定义的内容(函数等)。它描述了库的接口(interface),但没有描述库功能的实现。

这就是你的程序能够编译的原因。 unistd.h 中有一个 sleep() 声明。它可能看起来像这样:

unsigned sleep(unsigned);

你可以看一下,这是一个文本文件。

问题是,当您尝试链接时,没有任何内容定义 sleep()。通常 sleep() 和其他标准函数存在于预编译库中。名称类似于 libc.a 的文件 .a 文件是一个存档,其中包含实现库功能的目标文件,链接器可以将其与您的目标文件链接以解析对 sleep() 等内容的引用。

stddef.h stdint.h 工作的原因是它们主要定义在编译时使用的类型和宏,但不需要在链接时插入任何额外的目标代码。

您的链接行不包含任何库。我怀疑这是因为您的裸机环境没有任何东西。

您有几个选择。您可以尝试移植一个预先存在的库以在您的环境中工作,或者您可以编写自己的 sleep() 函数。

您可以看看ELLCC这是提供库的(几个)交叉开发工具链之一。 ELLCC 的裸机库是一项正在进行的工作,但看看 ELK blog posts可能会给你一些想法。

关于c - 内核编译但不会与 unistd.h 引用链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34184743/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com