【发布时间】: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