【问题标题】:C++ const char* messes up the multiboot headerC++ const char* 弄乱了多重引导标头
【发布时间】:2021-04-22 00:12:28
【问题描述】:

这很奇怪。

所以我正在尝试制作一个小内核,并决定为此使用 C++。我做了一切,现在我有一个(几乎)工作的 VGA 文本模式驱动程序。为什么差不多?因为每当我通过 write 方法时,const char* 多重引导标头就会消失。

经过一番摆弄后,我意识到任何const char* 的使用都会让它变得疯狂。甚至只是一个变量。

奇怪的是,如果我从不创建const char*,它就可以工作。我也可以打印单个字符。

注意:我基于Bare Bones Tuturial on OSDev

以下是相关代码:

# Main.asm

MBALIGN equ 1 << 0
MEMINFO equ 1 << 1
FLAGS equ MBALIGN | MEMINFO
MAGIC equ 0x1BADB002
CHECKSUM equ -(MAGIC + FLAGS)

section .multiboot
align 4
    dd MAGIC
    dd FLAGS
    dd CHECKSUM

section .bss
align 16
    stack_bottom:
    resb 16384
    stack_top:

section .text
global _start:function (_start.end - _start)
_start:
    mov esp, stack_top

    extern kernel_main
    call kernel_main

    cli

.hang: hlt
    jmp .hang

.end:
// Main.cpp
void init() {
    Drivers::VGA vga;
    vga.putc('h');
    vga.write("hello", 5);
}

extern "C" void kernel_main() {
    init();
}

// Part of VGA.cpp
void VGA::write(const char* data, size_t size) {
        for (size_t i = 0; i < size; i += 1) {
            s_buffer[i] = vga_entry(data[i], _color);
        }
}

[...]

u16 VGA::vga_entry(unsigned char c, u8 color) {
        return (u16)c | (u16)color << 8;
}
# Linker.ld

ENTRY(_start)

SECTIONS {
    . = 1M;

    .text : ALIGN(4K) {
        KEEP(*(.multiboot))
        *(.text)
    }

    .rodata : ALIGN(4K) {
        *(.rodata)
    }

    .data : ALIGN(4K) {
        *(.data)
    }

    .bss : ALIGN(4K) {
        *(COMMON)
        *(.bss)
    }
}

编译器选项:-target i686-pc-elf -c -IKernel -ffreestanding -nostdlib++ -fno-exceptions -fno-rtti -fno-stack-protector -m32 -fno-use-cxa-atexit

工具链:Clang、Nasm 和 ld.lld

【问题讨论】:

  • 原谅我的无知,但是“相关代码”的哪一部分实际上实现了write?调用vga.write("hello", 5) 时会执行什么代码? Drivers::VGA这个类的定义是什么?
  • @IgorTandetnik 我刚刚添加了它。我一开始没有添加它,因为我认为它并不真正相关,因为即使只是创建一个 const char* 类型的变量也会把它搞砸
  • 嗯。字符串文字唯一不寻常的地方是它们进入了.rodata 部分。也许不知何故这部分没有进入最终的二进制文件?似乎它应该虽然。抱歉,这就是我的知识范围。
  • @IgorTandetnik 好的,使用 readelf 我看到 .rodata 会出现在 .text(包含 .multiboot)之前。这不是应该的,对吧?代码中没有任何字符串文字 .rodata 消失
  • @IgorTandetnik 没关系,我发布了答案

标签: c++ operating-system clang


【解决方案1】:

问题是ld.lld 有一个错误(?)或什么。它将 rodata 部分放在文本之前,因此 multiboot 标头将不可见。

这是readelf -S Kernelld.lld 的输出

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .rodata.str1.1    PROGBITS        00100000 001000 000001 01 AMS  0   0  1
  [ 2] .text             PROGBITS        00101000 002000 0002fe 00  AX  0   0 4096
  [ 3] .data             PROGBITS        00102000 003000 000004 00  WA  0   0 4096
  [ 4] .bss              NOBITS          00103000 003004 004000 00  WA  0   0 4096
  [ 5] .comment          PROGBITS        00000000 003004 000029 01  MS  0   0  1
  [ 6] .symtab           SYMTAB          00000000 003030 0001a0 10      8  14  4
  [ 7] .shstrtab         STRTAB          00000000 0031d0 000044 00      0   0  1
  [ 8] .strtab           STRTAB          00000000 003214 00018f 00      0   0  1

这是系统ld (GNU) 的输出

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        00100000 001000 0002fe 00  AX  0   0 4096
  [ 2] .rodata.str1.1    PROGBITS        001002fe 0012fe 000001 01 AMS  0   0  1
  [ 3] .data             PROGBITS        00101000 002000 000004 00  WA  0   0 4096
  [ 4] .bss              NOBITS          00102000 002004 004000 00  WA  0   0 4096
  [ 5] .comment          PROGBITS        00000000 002004 000015 01  MS  0   0  1
  [ 6] .symtab           SYMTAB          00000000 00201c 0001f0 10      7  19  4
  [ 7] .strtab           STRTAB          00000000 00220c 00018f 00      0   0  1
  [ 8] .shstrtab         STRTAB          00000000 00239b 000044 00      0   0  1

【讨论】:

    猜你喜欢
    • 2014-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-01
    相关资源
    最近更新 更多