如何编写hello world内核?

问题描述 投票:0回答:4

我正在编写一个内核,因此我从内核中的 hello world 程序开始。

我用c++编写了一个hello world内核,并且编译成功。

但是当我启动它时,它在屏幕上没有显示任何内容。

这段代码有什么问题?

链接.ld

OUTPUT_FORMAT("binary")
ENTRY(start)
SECTIONS{
. = 0x00100000;

.text :{
    *(.text)
}

.rodata ALIGN (0x1000) : {
    *(.rodata)
}

.data ALIGN (0x1000) : {
    *(.data)
}

.bss : {
    sbss = .;
    *(COMMON)
    *(.bss)
    ebss = .;
}
}

装载机.asm

[BITS 32]

global start
extern _main

start:
    call _main
    cli 
    hlt

视频.h

#ifndef VIDEO_H
#define VIDEO_H

class Video{
    public:
        Video();
        ~Video();
        void clear();
        void write(char *cp);
        void put(char c);
    private:
        unsigned short *videomem;
        unsigned int off;
        unsigned int pos;
};
#endif

视频.cpp

#include "Video.h"

Video::Video(){
pos = 0;
off = 0;
videomem = (unsigned short*)0xb8000;
}

Video::~Video(){}

void Video::clear(){
unsigned int i;
for(i=0;i<(80*25);i++){
    videomem[i] = (unsigned short)' '|0x0700;
}
pos = 0;
off = 0;
}

void Video::write(char *cp){
char *str = cp, *ch;
for(ch=str;*ch;ch++){
    put(*ch);
}
}

void Video::put(char c){
if(pos>=80){
    pos = 0;
    off+=80;
}
if(off>=(80*25)){
    clear();
}

videomem[off+pos] = (unsigned short)c|0x0700;
pos++;
}

内核.cpp

#include "Video.h"
int _main(void){
Video vid;
vid.clear();
vid.write("Hello World!");
}

我正在使用以下命令编译它:

g++ -c video.cpp -ffreestanding -nostdlib -fno-builtin -fno-rtti -fno-exceptions
g++ -c Kernel.cpp -ffreestanding -nostdlib -fno-builtin -fno-rtti -fno-exceptions
nasm -f aout Loader.asm -o Loader.o
ld -T linker.ld -o Kernel.bin Loader.o Video.o Kernel.o

它不会给出任何错误。

如果可以调试,请帮我调试一下。

我正在虚拟盒子中启动它。

任何帮助将不胜感激。

c++ c assembly operating-system kernel
4个回答
12
投票

如果您愿意,您可以查看本学期我的课堂上用作示例的操作系统。已在

c
完成。我们使用 GRUB 引导加载程序和 qemu 来运行东西。

它以增量方式编写得非常清晰,第一个增量正是“Hello world”操作系统,最后一个增量包含完整 shell、线程和进程以及许多其他内容的所有内容。您可以在那里找到源代码、makefile 和链接器脚本的示例(从简单的示例到相当复杂的示例)

https://github.com/fklepo/osur-labs-fer

我还会链接到增量后的脚本,但不幸的是,不是英文的。

哦,还有,有一个专门用于调试的增量,但这更多的是为了调试为您的操作系统制作的程序,而不是调试整个操作系统(如果我没记错的话,我们使用了两个控制台,一个带有 qemu,另一个带有 qemu) gdb 连接到另一个操作系统中运行的操作系统)。


5
投票

当 PC 启动时,BIOS 将加载物理地址 0x7c00 处 MBR 中的所有内容,然后跳转到该地址。所以你应该从 0x7c00 开始链接你的代码,而不是从 0x00100000 开始。

因此,按如下方式更改链接器脚本应该可以解决问题:

...
SECTIONS{
    . = 0x7c00;
    ...
}

编辑:查看您的代码后,我注意到更多问题。如果您不使用引导加载程序,则在开始执行 32 位代码之前必须进行一些设置,最重要的是启用保护模式。 这里有一些教程可以帮助您。


2
投票

你尝试过qemu吗?当在大学制作一个小型操作系统时,它被证明是此类东西的最佳程序。


0
投票

为此,您必须:

© www.soinside.com 2019 - 2024. All rights reserved.