小编Rot*_*er2的帖子

对_GLOBAL_OFFSET_TABLE_的未定义引用(仅在生成二进制文件时)

这就是问题:
当我用C语言链接我的脚本时,使用ld,当我在ld中生成elf32-i386文件作为输出格式,将它作为OUTPUT_FORMAT()放在ld脚本中时,我没有任何错误,但如果我尝试放入最后一个OUTPUT_FORMAT()"二进制"或尝试输出扩展名为.bin的文件,我得到的错误如下:

kernel.o: In function `k_main':
kernel.c:(.text+0xe): undefined reference to `_GLOBAL_OFFSET_TABLE_'
kernelutils.o: In function `k_clear_screen':
kernelutils.c:(.text+0xc): undefined reference to `_GLOBAL_OFFSET_TABLE_'
kernelutils.o: In function `k_clear_screen_front':
kernelutils.c:(.text+0x56): undefined reference to `_GLOBAL_OFFSET_TABLE_'
kernelutils.o: In function `k_printf':
kernelutils.c:(.text+0xa0): undefined reference to `_GLOBAL_OFFSET_TABLE_'
kernelutils.o: In function `k_sleep_3sec':
kernelutils.c:(.text+0x152): undefined reference to `_GLOBAL_OFFSET_TABLE_'
kernelmalloc.o:kernelmalloc.c:(.text+0xc): more undefined references to `_GLOBAL_OFFSET_TABLE_' follow
Run Code Online (Sandbox Code Playgroud)

这不仅发生在编译特定脚本时,所有尝试使用ld链接的脚本,或gcc,因为这会调用ld,在尝试获取带扩展名为.bin的二进制文件时死掉.
当显示其中一个可执行文件的符号(上面输出中的kernel.o)时,我看到符号_GLOBAL_OFFSET_TABLE_未定义,最可怕的部分,上面错误输出中返回错误的所有函数都删除了它们的符号,这是nm输出:

cristian@mymethodman:~/Desktop/kernel/0.0.3/Archivos$ nm kernel.o
         U _GLOBAL_OFFSET_TABLE_
         U k_clear_screen
         U k_clear_screen_front
00000000 T k_main
         U k_malloc
         U k_printf
         U k_sleep_3sec
00000000 T __x86.get_pc_thunk.bx
Run Code Online (Sandbox Code Playgroud)

我怎么能解决这个问题?我将保留下面的链接器脚本以确保它不是.ld文件的问题,同时具有"获取elf"和"获取二进制"版本.提前致谢!

Ld脚本:
获取二进制文件: …

linker gcc linker-errors ld osdev

6
推荐指数
1
解决办法
3262
查看次数

将带有长度字段的 C 灵活数组成员转换为 Ada

在编写与 C 代码接口的绑定时,我发现将具有灵活数组成员的结构的大量实例转换为 Ada 时存在问题,例如

struct example {
    size_t length;
    int    body[];
};
Run Code Online (Sandbox Code Playgroud)

有人告诉我,Ada 可以使用可区分的类型来复制类似的行为,但我找不到一种方法来使用该字段length作为判别式,同时保持结构的布局,以便记录可以用于与C代码,类似

type Example (Count : Integer := Length) is record
   Length : Unsigned_64;
   Body   : Integer (1 .. Count);
end record;
Run Code Online (Sandbox Code Playgroud)

有什么方法可以用该数组创建类似的类型吗?我现在一直默认获取该位置的地址并自己声明数组以供使用,有没有更好的方法?提前致谢。

ada

4
推荐指数
1
解决办法
217
查看次数

我的内核原型 (x86_64) 的问题

我试图在学习汇编的同时学习内核的工作原理,并且在学习如何成功创建可引导的 x86_64 内核的过程中,我遇到了一个问题:
我试图在“main.c”中成功输出一些带有函数的文本(下面的所有文件)通过使用 VGA 缓冲区0xB8000,与我使用 32 位版本的内核原型相同,但不同的是启动文件不同。
这里的问题是,当我对 32 位版本使用完全相同的功能时,它成功地打印到屏幕上,但是当使用新文件达到长模式(multiboot.Sstart.S)时,这不会发生,屏幕会变黑在 qemu 中测试时,几秒钟后它崩溃并显示错误消息:

warning: TCG doesn't support requested feature: CPUID.01H:ECX.vmx [bit 5]
qemu-system-x86_64: Trying to execute code outside RAM or ROM at 0x00000000000a0000
Run Code Online (Sandbox Code Playgroud)

为什么会发生这种情况?VGA 缓冲区不在0xB8000,*.S 文件有问题?提前致谢!
我将在此处粘贴内核文件:
内核由 4 个文件组成:“main.c”、“start.S”、“multiboot.S”和链接描述文件“linker.ld”。
这3个文件被链接和编译没有任何错误,文件如下:这是main.c(你会看到一个“basiccolors.h”,这个文件只是定义了vga颜色代码)

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

volatile uint16_t* vga_buffer = (uint16_t*)0xB8000; /* memory location of the VGA textmode buffer */
/* Columns and rows of the VGA buffer */
const int …
Run Code Online (Sandbox Code Playgroud)

assembly gcc kernel x86-64 osdev

2
推荐指数
1
解决办法
705
查看次数

在 Ada 中将地址拆分并转换为不同的整数

要与某个硬件(在本例中为 x86 GDT 的 TSS 条目)接口,需要在内存中使用以下结构:

type UInt32 is mod 2 ** 32;
type UInt16 is mod 2 ** 16;
type UInt8  is mod 2 ** 8;

type TSSEntry is record
   Limit       : UInt16;
   BaseLow16   : UInt16;
   BaseMid8    : UInt8;
   Flags1      : UInt8;
   Flags2      : UInt8;
   BaseHigh8   : UInt8;
   BaseUpper32 : UInt32;
   Reserved    : UInt32;
end record;
for TSSEntry use record
   Limit       at 0 range 0  .. 15;
   BaseLow16   at 0 range 16 .. 31;
   BaseMid8    at 0 range 32 …
Run Code Online (Sandbox Code Playgroud)

casting bit-manipulation ada

1
推荐指数
1
解决办法
98
查看次数

根据参数创建一个选择接口的函数

我想创建一个函数来选择C中的另一个,也许这个C伪代码可以帮助澄清我想要的东西:

void set_method(const char *method)
{
    // Check if the method is serial_port
    if (strcmp(method, "serial_port") == 0)
    {
        // assign the alias "print" to serial_print
        // something like defing here a function like this:
        // print(const char *print) { serial_print(print); }

        print(const char *print) = serial_print(const char *message)
    } 
    else if (strcmp(method, "graphical_tty") == 0)
    {
        // The same that serial_port case but with graphical_tty_print
    } 
    else
    {
        // Error
    } 
} 
Run Code Online (Sandbox Code Playgroud)

目标是在满足条件时为函数分配"别名",我该怎么做?

我正在使用一个独立的C实现,用clang编译.

c alias function clang freestanding

0
推荐指数
1
解决办法
62
查看次数

以独立的方式从C调用C++

我有一个用C++编写的内核尝试,我想知道将它移植到x86_64 UEFI,但是使用GNU-efi lib的EFI bootloader必须用C语言编写.

如何从C跳转到主内核函数?一直使用extern C使得C++特性的使用变得不可能,也许可以使用一些汇编代码,或者我可以使引导加载程序调用ELF文件作为ELF加载器的主要内核.这个解决方案可行吗?

c c++

-1
推荐指数
1
解决办法
105
查看次数