如何编写hello world内核?

Dny*_*ate 16 c c++ assembly operating-system kernel

我正在编写一个内核,所以我开始在内核中使用hello world程序.

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

但是,当我启动它时,它不会在屏幕上显示任何内容.

这段代码出了什么问题?

link.ld

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

.text :{
    *(.text)
}

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

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

.bss : {
    sbss = .;
    *(COMMON)
    *(.bss)
    ebss = .;
}
}
Run Code Online (Sandbox Code Playgroud)

loader.asm

[BITS 32]

global start
extern _main

start:
    call _main
    cli 
    hlt
Run Code Online (Sandbox Code Playgroud)

video.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
Run Code Online (Sandbox Code Playgroud)

video.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++;
}
Run Code Online (Sandbox Code Playgroud)

Kernel.cpp

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

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

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
Run Code Online (Sandbox Code Playgroud)

它没有任何错误.

如果可以调试,那么请帮我调试一下.

我在虚拟框中启动它.

任何帮助将不胜感激.

pen*_*ope 12

如果您愿意,可以查看本学期我班上用作示例的操作系统.它完成了c.我们使用GRUB bootloader和qemu来运行东西.

它的编写非常干净,第一个增量正是"Hello world"操作系统,最后一个增量包含完整的shell,线程和进程以及许多其他内容.你可以在那里找到源代码,makefile和链接描述文件的例子(从简单的例子到相当复杂的例子)

http://sourceforge.net/projects/oszur11/

我还会按照增量链接到脚本,但不幸的是,不是英文.

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


Job*_*Job 5

当PC启动时,BIOS将加载无论是在MBR物理地址0x7c00,然后跳转到该地址.因此,您应该从0x7c00而不是0x00100000开始链接代码.

因此,如下更改链接描述文件应该可以解决问题:

...
SECTIONS{
    . = 0x7c00;
    ...
}
Run Code Online (Sandbox Code Playgroud)

编辑:看了你的代码后,我注意到了一些问题.如果您没有使用引导加载程序,则必须先设置一些内容才能开始执行32位代码,最重要的是启用保护模式.这里有一些教程可以帮助您.


Ale*_*der 2

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