我正在编写一个内核,因此我从内核中的 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
完成。我们使用 GRUB 引导加载程序和 qemu 来运行东西。
它以增量方式编写得非常清晰,第一个增量正是“Hello world”操作系统,最后一个增量包含完整 shell、线程和进程以及许多其他内容的所有内容。您可以在那里找到源代码、makefile 和链接器脚本的示例(从简单的示例到相当复杂的示例)
https://github.com/fklepo/osur-labs-fer
我还会链接到增量后的脚本,但不幸的是,不是英文的。
哦,还有,有一个专门用于调试的增量,但这更多的是为了调试为您的操作系统制作的程序,而不是调试整个操作系统(如果我没记错的话,我们使用了两个控制台,一个带有 qemu,另一个带有 qemu) gdb 连接到另一个操作系统中运行的操作系统)。
你尝试过qemu吗?当在大学制作一个小型操作系统时,它被证明是此类东西的最佳程序。
为此,您必须:
loader.asm
中实现多重引导标准并使用GRUB。多重引导文件是具有特殊标头的 ELF 文件。 示例。int 13h
BIOS 调用将代码从磁盘读取到内存中,因为固件仅将 512 字节读取到内存,并且您的代码可能会编译更多。 示例