2017-04-12 15 views
1

Write your own operating system in 1 hourのチュートリアルに続いて、ちょうど4つのファイル "Hello World"を印刷する基本OSを作成しました。Makefilekernel.cpploader.slinker.ldVirtualBoxでカスタムカーネルを起動できません:

私はmykernel.isoファイルを作成していますが、私がVirtualBoxで起動すると、「ブートメディアから読み込めませんでした:システムが停止しました」というエラーが表示されます。 .isoファイルが自分のマシンインスタンスにリンクされていることを確認しました。おそらくコードに他の問題があるように見えます。ここで

は私のMakefileです:

#we need to tell the compiler to stop assuming that this will be executed inside an OS 
CPPPARAMS = -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 
    g++ $(CPPPARAMS) -o [email protected] -c $< 

%.o: %.s 
    as $(ASPARAMS) -o [email protected] $< 

mykernel.bin: linker.ld $(objects) 
    ld $(LDPARAMS) -T $< -o [email protected] $(objects) 

install: mykernel.bin 
    sudo cp $< /boot/mykernel.bin 

mykernel.iso: mykernel.bin 
    mkdir iso 
    mkdir iso/boot 
    mkdir iso/boot/grub 
    cp $< iso/boot/ 
    echo 'set default=0' > iso/boot/grub/grub.cfg 
    echo 'set timeout=0' >> iso/boot/grub/grub.cfg 
    echo '' >> iso/boot/grub/grub.cfg 
    echo 'menuentry "My Personal OS" {' >> 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 [email protected] iso 
    rm -rf iso 

clean: 
    rm -rf iso 
    rm *.o 
    rm mykernel.iso 
    rm mykernel.bin 

はここでここでkernel.cpp

void printf(char *str) 
{ 
    unsigned short *VideoMemory = (unsigned short*)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(void * multiboot_structure, unsigned int magic_number) 
{ 
    printf("Hello World!"); 

    //we do not want to exit from the kernel 
    while(1); 
} 

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 #AX register has the pointer of multiboot structure stored by bootloader 
    push %ebx #BX register has the magic number 
    call kernelMain 

#double check to not come out of the kernel, creating one more loop 
_stop: 
    cli 
    hlt 
    jmp _stop 


.section .bss 
.space 2*1024*1024 #2MB for stack to grow towards left side 
kernel_stack: 

linker.ldです:

ENTRY(loader) 
OUTPUT_FORMAT(elf32-i386) 
OUTPUT_ARCH(i386:i386) 

SECTIONS 
{ 
    . = 0x100000; 

    .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) 
    } 
} 

私の開発環境はLinux Mintです。18.1 virtualboxがインストールされた64ビット。私のコードは、シリーズのチューターのコードとほぼ一致しますが、まだ私は仮想マシンで起動できません。

EDIT

私はqemu-system-i386 -kernel mykernel.binにしようと、それはVirtualBoxの環境や構成に問題があることを意味し.ThatメッセージHello Worldで正常に動作します。

+0

仮想マシンの起動時に、F12を押してCD-ROMから起動するように指示しましたか? –

+0

私はあなたの問題は多分stack.Youに関連していると思うが、かなり大きい2 MBのスタックを作成します。 BSSセクションにあるので、マルチブートローダーはそれをゼロにします。環境によっては、このような大きなBSSセグメントによって、カーネルのロードと処理中にマルチブートローダーが失敗することがあります。スタックに問題がある場合は、サイズを2mbではなく2k(2048バイト)に設定してみてください。それは動作しますか? '.section .bss'' .space 2 * 1024') –

+0

あなたのカーネルが大丈夫かどうかを確認するには' qemu'を試してください。おそらく最初にバイナリ(.bin)をチェックしてから.isoをチェックしてください。 –

答えて

-1

この回答には正式な情報源がありません。それは実際に経験と私がStackoverflowで見た他の質問と私が作ったいくつかの発見に基づいています。あなたはそれがGRUBは、一部の環境ではなく、他にクラッシュしBSSセグメントにおける大きなカーネルのブートストラップ・スタックを作成する場合

は、それが表示されます。これは、BSSセグメントの合計サイズが約2MBに達すると思われる場合によく発生します。 Virtualboxは、問題が発生しているような特殊なケースのようです。 VirtualBoxの問題は、使用されているバージョンと仮想ハードウェア構成によって異なるようです。

loader.sで作成したスタックで、のC++環境をブートストラップする必要はありません。メモリ管理とアロケータを取得したら、より大きなカーネルスタックの領域を予約し、その時点でSS:ESPを設定することができます。

そのために、あなたは変更することを検討すべきである:

.section .bss 
.space 2*1024*1024 #2MB for stack to grow towards left side 
kernel_stack: 

を何か1メガバイト以下に。私はおそらく64kbのようなものに行くでしょう:

.section .bss 
.space 64*1024 #64KB for stack to grow towards left side 
kernel_stack: 
+0

1台のマシンで2KBを試してみましたが、同じOSが同じマシンで他のマシンで同じサイズがクラッシュしていましたが、64KBがこのマシンで動作します。 VirtualBoxなどの違いがあります。 –

+0

カーネルのブートストラッピング、BSS、スタックなどの入門についての良いチュートリアルをご存知ですか?ありがとう。 –

+0

@InsaneCoder [OS Dev Wiki](http://wiki.osdev.org/Main_Page)はおそらくあなたの最善の策です –

0

私は同じ問題に遭遇しました。 grub-pc-binをインストールしてカーネルを再コンパイルするだけで、仮想ボックスで正常に起動しました。

sudo apt-get install grub-pc-bin 

また、私はBSSセグメントサイズを変更する必要はありませんでした。