luajitos

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

loader.s (2377B)


      1 /* 32-bit loader stub that GRUB can load */
      2 /* This sets up 64-bit mode and jumps to the 64-bit kernel */
      3 
      4 /* Multiboot1 header */
      5 .section .multiboot
      6 .align 4
      7     .long 0x1BADB002                /* magic */
      8     .long 0x00000000                /* flags */
      9     .long -(0x1BADB002 + 0x00000000) /* checksum */
     10 
     11 .section .bss
     12 .align 4096
     13 pml4:
     14     .skip 4096
     15 pdpt:
     16     .skip 4096
     17 pd:
     18     .skip 4096
     19 .align 16
     20 stack_bottom:
     21     .skip 16384
     22 stack_top:
     23 
     24 .section .text
     25 .code32
     26 .global _start
     27 _start:
     28     /* Set up stack */
     29     mov $stack_top, %esp
     30 
     31     /* Disable interrupts */
     32     cli
     33 
     34     /* Check for long mode support */
     35     mov $0x80000000, %eax
     36     cpuid
     37     cmp $0x80000001, %eax
     38     jb no_long_mode
     39 
     40     mov $0x80000001, %eax
     41     cpuid
     42     test $(1 << 29), %edx
     43     jz no_long_mode
     44 
     45     /* Set up identity paging for first 2MB */
     46     /* PML4[0] -> PDPT */
     47     mov $pdpt, %eax
     48     or $0x3, %eax
     49     mov %eax, pml4
     50 
     51     /* PDPT[0] -> PD */
     52     mov $pd, %eax
     53     or $0x3, %eax
     54     mov %eax, pdpt
     55 
     56     /* PD[0] -> 2MB huge page at 0x0 */
     57     mov $0x83, %eax
     58     mov %eax, pd
     59 
     60     /* Also map higher half for kernel (identity map first 2GB) */
     61     mov $pd, %edi
     62     mov $0x83, %eax
     63     mov $512, %ecx
     64 1:
     65     mov %eax, (%edi)
     66     add $0x200000, %eax  /* 2MB */
     67     add $8, %edi
     68     loop 1b
     69 
     70     /* Load CR3 with PML4 */
     71     mov $pml4, %eax
     72     mov %eax, %cr3
     73 
     74     /* Enable PAE */
     75     mov %cr4, %eax
     76     or $(1 << 5), %eax
     77     mov %eax, %cr4
     78 
     79     /* Enable long mode in EFER MSR */
     80     mov $0xC0000080, %ecx
     81     rdmsr
     82     or $(1 << 8), %eax
     83     wrmsr
     84 
     85     /* Enable paging */
     86     mov %cr0, %eax
     87     or $(1 << 31), %eax
     88     mov %eax, %cr0
     89 
     90     /* Load GDT */
     91     lgdt gdt64_pointer
     92 
     93     /* Far jump to 64-bit code */
     94     ljmp $0x08, $long_mode_start
     95 
     96 no_long_mode:
     97     /* Hang */
     98     cli
     99 1:  hlt
    100     jmp 1b
    101 
    102 .code64
    103 long_mode_start:
    104     /* Set up segments */
    105     mov $0x10, %ax
    106     mov %ax, %ds
    107     mov %ax, %es
    108     mov %ax, %fs
    109     mov %ax, %gs
    110     mov %ax, %ss
    111 
    112     /* Set up stack */
    113     mov $stack_top, %rsp
    114 
    115     /* Call the external kernel_main */
    116     call kernel_main
    117 
    118     /* Hang */
    119     cli
    120 1:  hlt
    121     jmp 1b
    122 
    123 /* GDT for 64-bit mode */
    124 .align 16
    125 gdt64:
    126     .quad 0x0000000000000000    /* Null */
    127     .quad 0x00AF9A000000FFFF    /* Code segment (64-bit) */
    128     .quad 0x00CF92000000FFFF    /* Data segment */
    129 gdt64_pointer:
    130     .word gdt64_pointer - gdt64 - 1
    131     .quad gdt64