view bootstrap.S @ 10:50e4b9ca4867

add bootstrap source. Go to 64bit mode.
author Taiki TAIRA <e095767@ie.u-ryukyu.ac.jp>
date Mon, 27 Aug 2012 23:45:31 +0900
parents bd2f9ba6f5f8
children 26b76ada8c13
line wrap: on
line source

/*
 * This program is boot to kernel.
 * Change mode to 64bit mode and go to CbC kernel.
 */

#include "multiboot2.h"
#include "boot_header.h"

.file "bootstrap.S"

.text
.code32
.globl _start

_start:
    jmp move_longmode
    /* 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.
 */

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

    
    jmp start_kernel


/* jump to kernel.
 * push ebx and eax send argument to kernel.
 */
start_kernel:
    pushl %ebx
    pushl %eax
    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