]> pd.if.org Git - zos/blob - bootz.s
add a readme with a public domain note
[zos] / bootz.s
1 USE64
2
3 section .text
4
5 ; TODO if this were aligned to a page, the kernel
6 ; could reclaim the memory below it from 0x100000 to the start of this section
7
8 ; import some symbols from boot32.s
9 extern GDT64
10 extern GDT_load
11 extern multiboot_infoptr
12 extern multiboot_magic
13
14 ; export so that boot32.s can find it
15 global kernel_bootstrap:function
16
17 ; export for the kernel
18 global _asm_physmap:data
19
20 ; I think from here the code expects to be using the high memory addresses
21 kernel_bootstrap:
22         ; zero the other segment registers, we aren't going to use them
23         xor rax, rax
24         mov fs, ax
25         mov gs, ax
26
27         ; enable the floating point unit
28         mov rax, cr0
29         and ax, 0xFFFD
30         or ax, 0x10
31         mov cr0, rax
32         fninit
33
34         ; Enable Streaming SIMD Extensions
35         mov rax, cr0
36         and ax, 0xFFFB
37         or ax, 0x2
38         mov cr0, rax
39         mov rax, cr4
40         or rax, 0x600
41         mov cr4, rax
42
43         ; TODO might as well just enable syscall/sysret here
44
45         jmp beginkernel
46 .end:
47 size kernel_bootstrap (kernel_bootstrap.end - kernel_bootstrap)
48
49 section .text
50
51 extern stack
52 extern kernel_main
53
54 global beginkernel
55 type beginkernel function
56 beginkernel:
57         ; initialize the stack pointer
58         ; hard coded kernel stack.  could be freed later with
59         ; a dynamic stack, but 64 KB should be enough, and I'd
60         ; like to not page fault the kernel, especially for
61         ; a stack issue
62         ; TODO this stack pretty much leaks once tasking is set
63         ; up.  the initial task should probably be freed, and
64         ; the 64 KB handed over to the pmm, or used for DMA or
65         ; something
66         mov rsp, qword stack
67         add rsp, 65536 ; 64 KB, see kernel.c
68
69         ; sets up the 1 GB page maps for the first 512 GB
70         ; doing this early makes the pmm's job easier
71         call mapphys
72
73         ; reload GDT to high memory
74         mov rax, [ qword _asm_physmap ]
75         add rax, GDT64
76         mov qword [GDT_load + 2], rax
77         lgdt [GDT_load]
78
79         ; SysV ABI args for kernel_main, which is written in C
80         mov edi, [multiboot_infoptr]
81         mov esi, [multiboot_magic]
82         call kernel_main
83 .end
84 size beginkernel beginkernel.end - beginkernel
85
86 mapphys:
87         ; rdi, rsi, rdx, rcx, r8, r9
88         ; scratch rax, rdi, rsi, rdx, rcx, r8, r9, r10, r11
89
90         ; now that we're in 64 bit mode, map in the physical memory to
91         ; the high addreses
92         ; set up 1GB PDPT for physical map at 0xFFFFC00000000000
93         ;   1 GB = 0x    4000 0000
94         ; 512 GB = 0x 80 0000 0000
95
96         ; rax = physical address and bits
97         mov eax, 0x183 ; Global, 1 GB PS, RW, and Present bits
98         ; rdi = pdpt slot address, i.e. pdpe address
99         mov rdi, 0x19000
100         ; rsi = (1<<30) i.e. 1 GB
101         mov rsi, 0x40000000 ; 1 GB
102         ; ecx = GB count
103         xor ecx, ecx
104
105         .nextgb
106         stosq
107         add rax, rsi ; next physical address
108         inc ecx
109         cmp ecx, 512 ; could not use ecx and just cmp rdi to 0x2B000
110         jl .nextgb ; I think I can just do a loop .nextgb and skip the inc and cmp
111
112         ; calculate the pml4t offset
113         mov rax, [qword _asm_physmap]
114         mov rdx, rax
115         shr rdx, 39
116         and edx, 0x1ff ; edx is now 384 if the physmap offset is still 0xffffc000000000
117         mov rax, 0x19003 ; physical address of pdpt + ReadWrite and Present
118         mov rdi, cr3
119         ; now, set the pml4e
120         mov [rdi + rdx*8], rax
121
122         ret
123
124 global allstop:function
125 allstop:
126         mov rax, [rsp]
127         mov dr0, rax
128         cli
129         hlt
130         jmp allstop
131 .end
132 size allstop, allstop.end - allstop
133
134 global halt:function
135 halt:
136         sti ; ensure that we can receive interrupts
137         hlt
138         ret
139
140 section .data
141
142 align 8
143 _asm_physmap:
144 dq 0xFFFFC00000000000