# HG changeset patch # User Taiki TAIRA # Date 1346813355 -32400 # Node ID acdc2c21996a41b7e7ca0233311f6142cb85b1b6 # Parent 812852f41fc06e6fdcb9c680680e20399adf4d88 chage directory structure diff -r 812852f41fc0 -r acdc2c21996a Kernel/bootstrap.S --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Kernel/bootstrap.S Wed Sep 05 11:49:15 2012 +0900 @@ -0,0 +1,15 @@ + +.code16 +.text +.globl start + +.org 0 + +start: + jmp $0x07c0, $start + + mov %cs, %ax + mov %ax, %ds + mov $0xb800, %ax + mov %ax, %es + mov $0x0, %di diff -r 812852f41fc0 -r acdc2c21996a withGRUB2Kernel/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/withGRUB2Kernel/Makefile Wed Sep 05 11:49:15 2012 +0900 @@ -0,0 +1,47 @@ +HOME = /Users/taira +prefix = $(HOME)/cross/COMMON_INSTALL/bin +CBC = $(prefix)/elf-cbc-gcc-4.6.0 +LD = $(prefix)/x86_64-elf-ld + +CBCFLAGS = -ffreestanding \ + -fno-common \ + -fno-builtin \ + -fomit-frame-pointer \ + -nodefaultlibs \ + -g \ + -Wall \ + -O2 \ + -c \ + -o + +LDFLAGS64 = -melf_x86_64 \ + -nostdlib \ + -Ttext 0x100000 \ + --oformat elf64-x86-64 \ + -o + + +LDFLAGS32 = -melf_i386 \ + -nostdlib \ + -Ttext 0x100000 \ + --oformat elf32-i386 \ + -o + +LDFLAGS = $(LDFLAGS32) +BITFLAG = -m32 + +TARGET=cbc_os.elf + +all: $(TARGET) + +kernel.o: kernel.cbc + $(CBC) $(BITFLAG) $(CBCFLAGS) $@ $^ + +bootstrap.o: bootstrap.S + $(CBC) $(BITFLAG) $(CBCFLAGS) $@ $^ + +$(TARGET): bootstrap.o kernel.o + $(LD) $(LDFLAGS) $@ $^ + +clean: + rm -rf *.o *.elf diff -r 812852f41fc0 -r acdc2c21996a withGRUB2Kernel/README.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/withGRUB2Kernel/README.txt Wed Sep 05 11:49:15 2012 +0900 @@ -0,0 +1,56 @@ +TODO +64bit だと、 grub2 から OS を起動するための multiboot header magic が認識されていないので、認識されて起動できるようにする。 + +32bit では動く。 + + +【環境】 +//binutils +configure --target=x86_64-elf --enable-64-bit-bfd + +//newlib +コンパイルして cbc-gcc のディレクトリにシンボリックリンクを貼る + + +//cbc-gcc +configure --target=x86_64-elf --disabble-bootstrap --enable-languages=c \ +--enable-checking=tree,rtl,assert,types --disable-nls --with-newlib --without-headers --disable-libssp --disable-libquadmath + + +【コンパイル】 +//64bit +gcc -m64 \ + --ffreestanding -fno-common \ + -fomit-frame-pointer \ + -g \ + -Wall \ + -O2 \ + +//32bit +gcc -m32 + あとは 64bit と同じ + +ld -m elf_x86_64 \ + -nostdlib \ + -Ttext 0x100000 \ + --oformat elf64-x86-64 or --oformat elf32-i386 + +【実行】 +fd.img をgrub2 の乗っている VM に接続 +grub2 の OS 選択画面で C を押す + +bash like. tab 補完きく +コマンド実行画面で + +>ls +接続されている記憶媒体の表示 + +>set root=(記憶媒体,ファイルシステム) + ex: set root=(fd0,msdos1) + +>multiboot2 /cbc_os.elf +boot 前の下準備。OS のロード。 + +>boot +boot する。 + diff -r 812852f41fc0 -r acdc2c21996a withGRUB2Kernel/boot_header.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/withGRUB2Kernel/boot_header.h Wed Sep 05 11:49:15 2012 +0900 @@ -0,0 +1,7 @@ +#ifndef BOOT_HEADER +#define BOOT_HEADER + +#define MSR_EFER 0xc0000080 +#define EFER_LME 8 + +#endif /* BOOT_HEADER */ diff -r 812852f41fc0 -r acdc2c21996a withGRUB2Kernel/bootstrap.S --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/withGRUB2Kernel/bootstrap.S Wed Sep 05 11:49:15 2012 +0900 @@ -0,0 +1,143 @@ +/* + * This program is boot to kernel. + * Change mode to 64bit mode and go to CbC kernel. */ + +.file "bootstrap.S" + +#include "multiboot2.h" +#include "boot_header.h" + +.code32 +.text + + /* Align 64 bit boundly. */ + .align 8 +multiboot_header: + .long MULTIBOOT2_HEADER_MAGIC + .long MULTIBOOT_ARCHITECTURE_I386 + .long multiboot_header_end - multiboot_header + .long -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + (multiboot_header_end - multiboot_header)) + .short MULTIBOOT_HEADER_TAG_END + .short 0 + .long 8 +multiboot_header_end: + + +/* + * Prepare for entering 64bit-mode. + */ + +.globl _start + +_start: + jmp move_longmode + +move_longmode: + /* load new GDT */ + leal gdt(%ebp), %eax + movl %eax, gdt+2(%ebp) + lgdt gdt(%ebp) + + /* + * PAE mode ON. + * Physical Address Extension + * You can use capacity of memory more than 4GiB on 32 bit CPU. + */ + + movl $0x00000020, %eax + movl %eax, %cr4 + + /* + * create 64bit page table + */ + + /* + * Initialize page tables to 0 + * 6144 = 512*8*6/4 + */ + + movl $0x01fe9000, %ebx + leal pgtable(%ebx), %edi + xorl %eax, %eax + movl $6144, %ecx + rep stosl + + /* Build Level 4 */ + leal pgtable + 0(%ebx), %edi + leal 0x1007(%edi), %eax + movl %eax, 0(%edi) + + /* Build Level 3 */ + leal pgtable + 0x1000(%ebx), %edi + leal 0x1007(%edi), %eax + movl $4, %ecx +1: movl %eax, 0x00(%edi) + addl $0x00001000, %eax + addl $8, %edi + decl %ecx + jnz 1b + + /* Build level 2 */ + leal pgtable + 0x2000(%ebx), %edi + movl $0x00000183, %eax + movl $2048, %ecx +1: movl %eax, 0(%edi) + addl $0x00200000, %eax + addl $8, %edi + decl %ecx + jnz 1b + + /* Enable the boot page talbes */ + leal pgtable(%ebx), %eax + movl %eax, %cr3 + + /* Enable Long mode */ + movl $MSR_EFER, %ecx + rdmsr + btsl $EFER_LME, %eax + wrmsr + + pushl $(12*8) + leal start_kernel(%ebp), %eax + pushl %eax + + /* activating Long Mode */ + movl %eax, %cr0 + + jmp start_kernel + + +/* + * jump to kernel. + * push ebx and eax send argument to kernel. + */ +.code64 +.text + +start_kernel: + pushq %rbx + pushq %rax + call kmain + +.data +gdt: + .word gdt_end - gdt + .long gdt + .word 0 + .quad 0x0000000000000000 /* NULL descriptor */ + .quad 0x00af9a000000ffff /* __KERNEL_CS */ + .quad 0x00cf92000000ffff /* __KERNEL_DS */ + .quad 0x0080890000000000 /* TS descriptor */ + .quad 0x0000000000000000 /* TS continued */ +gdt_end: + + +/* + * Space for page tables. + * a : section is allocatable. + * @nobits : section does not contain data. + */ +.section ".pgtable", "a", @nobits +.balign 4096 +pgtable: + .fill 6*4096, 1, 0 diff -r 812852f41fc0 -r acdc2c21996a withGRUB2Kernel/kernel.cbc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/withGRUB2Kernel/kernel.cbc Wed Sep 05 11:49:15 2012 +0900 @@ -0,0 +1,60 @@ +__code memory(int state); +__code kernel(int state); +void init(int state); + +__code put_to_vmem(unsigned char* str, unsigned short *video) +{ + char c; + if ((c=*(str++))!=0) { + *video++ = (0x0E << 8) | c; + goto put_to_vmem(str, video); + } else { + goto kernel(3); + } +} + + +__code putchar(int state) +{ + unsigned short *video = (unsigned short *)0xb8000; + unsigned char *str = (unsigned char *)"hello,world"; + + goto put_to_vmem(str, video); + + goto kernel(2); +} + +__code kernel(int state) +{ + switch(state) { + case 1: + goto putchar(3); + break; + case 2: + goto memory(state); + break; + } + goto kernel(state); +} + +__code memory(int state) +{ + if (state == 1) { + goto kernel(state); + } + init(state); +} + +void +init(int state) +{ + goto kernel(state); +} + +int +kmain(unsigned long magic, unsigned long addr) +{ + int state = 1; + init(state); + return 0; +} diff -r 812852f41fc0 -r acdc2c21996a withGRUB2Kernel/multiboot2.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/withGRUB2Kernel/multiboot2.h Wed Sep 05 11:49:15 2012 +0900 @@ -0,0 +1,8 @@ +#ifndef MULTIBOOT2_HEADER +#define MULTIBOOT2_HEADER + +#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6 +#define MULTIBOOT_ARCHITECTURE_I386 0 +#define MULTIBOOT_HEADER_TAG_END 0 + +#endif /* MULTIBOOT2_HEADER */