couple of bits on the x86_64 boot code
[newos.git] / boot / pc / x86_64 / stage1_entry.S
blob820672762c57856ac70cb39e4ce0c60321007d72
1 .code32
3 #define LOAD_ADDRESS 0x100000 // 1MB
4 #define PGTABLE_BASE 0x8000
6 .global _start
7 _start:
8         jmp             _enter64
10 #define MB_MAGIC        0x1BADB002
11 #define MB_FLAGS        (1<<0 | 1<<1 | 1<<16)                           // page align, meminfo, rest of header
12 #define MB_CHECKSUM (-(MB_MAGIC + MB_FLAGS))
14 .align 4
15 multiboot:
16 .long   MB_MAGIC                // magic
17 .long   MB_FLAGS                // flags
18 .long   MB_CHECKSUM             // checksum
19         // address part of the header
20 .long   multiboot               // address of header
21 .long   LOAD_ADDRESS    // load address of the binary
22 .long   _end                    // end of all the text + data
23 .long   0                               // no bss, linker script combines with data
24 .long   _start                  // entry point
26 _enter64:
27         // zero out 3 pages of ram where we're going to build some page tables
28         xor     %eax, %eax
29         mov     $PGTABLE_BASE, %edi
30         mov     $0x3000, %ecx
31         rep     stosb
33         // top level page table
34         mov     $((PGTABLE_BASE + 0x1000) | 0x3), %eax
35         mov     %eax, PGTABLE_BASE
36         mov     $((PGTABLE_BASE + 0x2000) | 0x3), %eax
37         mov     %eax, (PGTABLE_BASE + 0x1000)
39         // 2MB pages to identity map the first 16MB ram
40         mov     $(0 | (1<<7) | 3), %eax
41         mov     %eax, (PGTABLE_BASE + 0x2000)
42         add     $0x200000, %eax
43         mov     %eax, (PGTABLE_BASE + 0x2008)
44         add     $0x200000, %eax        
45         mov     %eax, (PGTABLE_BASE + 0x2010)
46         add     $0x200000, %eax        
47         mov     %eax, (PGTABLE_BASE + 0x2018)
48         add     $0x200000, %eax        
49         mov     %eax, (PGTABLE_BASE + 0x2020)
50         add     $0x200000, %eax        
51         mov     %eax, (PGTABLE_BASE + 0x2028)
52         add     $0x200000, %eax        
53         mov     %eax, (PGTABLE_BASE + 0x2030)
54         add     $0x200000, %eax        
55         mov     %eax, (PGTABLE_BASE + 0x2038)
57         // set the page table base
58         mov     $PGTABLE_BASE, %eax
59         mov     %eax, %cr3
61         // load the 64bit gdt
62         lgdt    gdt64
64         // set CR4.PAE
65         mov     %cr4, %eax          
66         bts     $5, %eax
67         mov     %eax, %cr4        
69         // enable long mode      
70         // EFER.LME=1            
71         mov     $0xc0000080, %ecx
72         rdmsr   
73         bts     $8, %eax             
74         wrmsr  
76         // enable paging, which will really enable long mode (CR0.PG)
77         mov     %cr0, %eax
78         bts     $31, %eax
79         mov     %eax, %cr0
81         ljmp    $0x08,$(long_64_mode)
83 .code64
84 long_64_mode:
85         // print an a
86         mov             $0xb8000, %rax
87         movw    $0x0f61, 0(%rax)
89         // set up the stack
90         mov             $stack_end, %rsp
92         // print a b
93         mov             $0xb8000, %rax
94         movw    $0x0f62, 2(%rax)
96         // ebx should contain a pointer to the multiboot info structure
97         mov             %rbx,%rdi
99         jmp             stage1_main
101 .align 4
102 gdt64:
103         // first entry, also the gdt descriptor
104         .word 0xffff
105         .long gdt64
106         .word 0
107         // entry 64bit code segment
108     .long 0x00000000  // base & limit are ignored
109     .long 0x00af9a00  // type: 64 bit, code, <present>, priviledge 0
112 .data
113 .align 8
114 stack:
115         .skip 0x4000
116 stack_end: