首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >内核编译但不会链接到unistd.h引用

内核编译但不会链接到unistd.h引用
EN

Stack Overflow用户
提问于 2015-12-09 17:06:05
回答 1查看 795关注 0票数 0

我正在编写一个具有键盘/光标支持的小型内核。在我从unistd.h添加一个函数之前,一切都很好

kernel.c

代码语言:javascript
复制
#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

代码语言:javascript
复制
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

代码语言:javascript
复制
OUTPUT_FORMAT(elf32-i386)

ENTRY(start)

SECTIONS

 {

   . = 0x100000;

   .text : { *(.text) }

   .data : { *(.data) }

   .bss  : { *(.bss)  }

 }

我正在用gcc交叉编译器通过终端编译它,并在qemu上运行它。

代码语言:javascript
复制
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中函数睡眠()的未定义引用”。

此外,这些参考资料在项目的其他地方也很有用.

代码语言:javascript
复制
 #include <stddef.h> 
 #include <stdint.h>  

...which进一步迷惑了我为什么Unist.h不链接..。但会编译。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-09 19:53:49

包含unistd.h只是告诉编译器一些事情(函数等)。在库中定义的。它描述了库的接口,而不是库功能的实现。

这就是为什么你的程序编译。H中有一个睡眠()声明。它看起来可能是这样的:

代码语言:javascript
复制
unsigned sleep(unsigned);

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

问题是,当您尝试链接时,没有什么定义睡眠()。通常,预编译库中存在睡眠()和其他标准函数。名为libc.a的.a文件是包含实现库功能的对象文件的存档,链接器可以将其链接到您的对象文件,以解析对睡眠()之类事物的引用。

Hstdint.h之所以工作,是因为它们主要定义在编译时使用的类型和宏,但不需要在链接时使用任何额外的对象代码。

您的链接线不包括任何库。我怀疑那是因为你的裸金属环境没有。

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

您可以看看ELLCC,它是提供库的(几个)交叉开发工具链之一。ELLCC的裸金属库是一项正在进行的工作,但看看麋鹿博客帖子可能会给你一些想法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34184743

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档