我目前正在开发一个操作系统。我是初学者,每个人都必须从某个地方开始。编码了以下文件: kernel.cpp loader.s linker.ld types.h Makefile 即可。我打开终端并稍后运行这些命令:make kernel.o
make loader.o
make mykernel.bin
和make mykernel.iso
运行make mykernel.iso
后,我创建了一个.iso映像,其路径我提供给VirtualBox机器。但是,当我的操作系统启动时,它会在VirtualBox上显示此错误:
致命:无法从启动媒体中读取!系统停滞。 任何人都可以帮我调试代码吗?请我是学生,并对操作系统着迷。
这些是我的文件:
kernel.cpp:
#include "types.h"
void printf(char* str)
{
static uint16_t* VideoMemory = (uint16_t*)0xb8000;
for(int i = 0; str[i] != '\0'; ++i)
VideoMemory[i] = (VideoMemory[i] & 0xFF00) | str[i];
}
typedef void (*constructor)();
extern "C" constructor start_ctors;
extern "C" constructor end_ctors;
extern "C" void callConstructors()
{
for(constructor* i = &start_ctors; i != &end_ctors; i++)
(*i)();
}
extern "C" void kernelMain(const void* multiboot_structure, uint32_t /*multiboot_magic*/)
{
printf("Hello World! --- http://www.AlgorithMan.de");
while(1);
}
以下是一个名为" linker.ld "
的文件linker.ld
ENTRY(loader)
OUTPUT_FORMAT(elf32-i386)
OUTPUT_ARCH(i386:i386)
SECTIONS
{
. = 0x0100000;
.text :
{
*(.multiboot)
*(.text*)
*(.rodata)
}
.data :
{
start_ctors = .;
KEEP(*( .init_array ));
KEEP(*(SORT_BY_INIT_PRIORITY( .init_array.* )));
end_ctors = .;
*(.data)
}
.bss :
{
*(.bss)
}
/DISCARD/ : { *(.fini_array*) *(.comment) }
}
我的" loader.s" :
.set MAGIC, 0x1badb002
.set FLAGS, (1<<0 | 1<<1)
.set CHECKSUM, -(MAGIC + FLAGS)
.section .multiboot
.long MAGIC
.long FLAGS
.long CHECKSUM
.section .text
.extern kernelMain
.extern callConstructors
.global loader
loader:
mov $kernel_stack, %esp
call callConstructors
push %eax
push %ebx
call kernelMain
_stop:
cli
hlt
jmp _stop
.section .bss
.space 2*1024*1024; # 2 MiB
kernel_stack:
生成文件:
GCCPARAMS = -m32 -fno-use-cxa-atexit -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore
ASPARAMS = --32
LDPARAMS = -melf_i386
objects = loader.o kernel.o
%.o: %.cpp
gcc $(GCCPARAMS) -c -o $@ $<
%.o: %.s
as $(ASPARAMS) -o $@ $<
mykernel.bin: linker.ld $(objects)
ld $(LDPARAMS) -T $< -o $@ $(objects)
mykernel.iso: mykernel.bin
mkdir iso
mkdir iso/boot
mkdir iso/boot/grub
cp mykernel.bin iso/boot/mykernel.bin
echo 'set timeout=0' > iso/boot/grub/grub.cfg
echo 'set default=0' >> iso/boot/grub/grub.cfg
echo '' >> iso/boot/grub/grub.cfg
echo 'menuentry "My Operating System" {' >> iso/boot/grub/grub.cfg
echo ' multiboot /boot/mykernel.bin' >> iso/boot/grub/grub.cfg
echo ' boot' >> iso/boot/grub/grub.cfg
echo '}' >> iso/boot/grub/grub.cfg
grub-mkrescue --output=mykernel.iso iso
rm -rf iso
run: mykernel.iso
(killall VirtualBox && sleep 1) || true
VirtualBox --startvm 'My Operating System' &
install: mykernel.bin
sudo cp $< /boot/mykernel.bin
types.h中:
#ifndef __TYPES_H
#define __TYPES_H
typedef char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
typedef long long int int64_t;
typedef unsigned long long int uint64_t;
#endif