mirror of https://gitlab.com/nakst/essence
163 lines
2.7 KiB
ArmAsm
163 lines
2.7 KiB
ArmAsm
; This file is part of the Essence operating system.
|
|
; It is released under the terms of the MIT license -- see LICENSE.md.
|
|
; Written by: nakst.
|
|
|
|
[bits 64]
|
|
[org 0x180000]
|
|
[section .text]
|
|
|
|
; 0x107000 Graphics info
|
|
; 0x107FE8 RSDP address
|
|
; 0x107FF0 Installation ID
|
|
; 0x140000-0x150000 Identity paging tables
|
|
; 0x160000-0x170000 Memory regions
|
|
; 0x180000-0x1C0000 Loader (this)
|
|
; 0x1C0000-0x1E0000 Kernel paging tables
|
|
; 0x1F0000-0x200000 Stack
|
|
; 0x200000-0x300000 Kernel
|
|
|
|
%define memory_map 0x160000
|
|
%define kernel_buffer 0x200000
|
|
|
|
start:
|
|
; Setup the environment.
|
|
lgdt [gdt_data.gdt]
|
|
mov rax,0x140000
|
|
mov cr3,rax
|
|
mov rax,0x200000
|
|
mov rsp,rax
|
|
mov rax,0x50
|
|
mov ds,rax
|
|
mov es,rax
|
|
mov ss,rax
|
|
|
|
; Find the program headers
|
|
; RAX = ELF header, RBX = program headers
|
|
mov rax,kernel_buffer
|
|
mov rbx,[rax + 32]
|
|
add rbx,rax
|
|
|
|
; ECX = entries, EDX = size of entry
|
|
movzx rcx,word [rax + 56]
|
|
movzx rdx,word [rax + 54]
|
|
|
|
; Loop through each program header
|
|
.loop_program_headers:
|
|
push rax
|
|
push rcx
|
|
|
|
; Only deal with load segments
|
|
mov eax,[rbx]
|
|
cmp eax,1
|
|
jne .next_entry
|
|
|
|
; Clear the memory
|
|
mov rcx,[rbx + 40]
|
|
xor rax,rax
|
|
mov rdi,[rbx + 16]
|
|
rep stosb
|
|
|
|
; Copy the memory
|
|
mov rcx,[rbx + 32]
|
|
mov rsi,[rbx + 8]
|
|
add rsi,kernel_buffer
|
|
mov rdi,[rbx + 16]
|
|
rep movsb
|
|
|
|
; Go to the next entry
|
|
.next_entry:
|
|
pop rcx
|
|
pop rax
|
|
|
|
add rbx,rdx
|
|
dec rcx
|
|
or rcx,rcx
|
|
jnz .loop_program_headers
|
|
|
|
jmp run_kernel64
|
|
|
|
run_kernel64:
|
|
; Get the start address of the kernel
|
|
mov rbx,kernel_buffer
|
|
mov rcx,[rbx + 24]
|
|
|
|
; Map the first MB at 0xFFFFFE0000000000 --> 0xFFFFFE0000100000
|
|
mov rdi,0xFFFFFF7FBFDFE000
|
|
mov rax,[rdi]
|
|
mov rdi,0xFFFFFF7FBFDFEFE0
|
|
mov [rdi],rax
|
|
mov rax,cr3
|
|
mov cr3,rax
|
|
|
|
; Use the new linear address of the GDT
|
|
mov rax,0xFFFFFE0000000000
|
|
add qword [gdt_data.gdt2],rax
|
|
lgdt [gdt_data.gdt]
|
|
|
|
call set_cs
|
|
|
|
; Execute the kernel's _start function
|
|
mov rdi,0x100000
|
|
mov rsi,2
|
|
jmp rcx
|
|
|
|
set_cs:
|
|
pop rax
|
|
push 0x48
|
|
push rax
|
|
db 0x48, 0xCB
|
|
|
|
gdt_data:
|
|
.null_entry: dq 0
|
|
.code_entry: dd 0xFFFF ; 0x08
|
|
db 0
|
|
dw 0xCF9A
|
|
db 0
|
|
.data_entry: dd 0xFFFF ; 0x10
|
|
db 0
|
|
dw 0xCF92
|
|
db 0
|
|
.code_entry_16: dd 0xFFFF ; 0x18
|
|
db 0
|
|
dw 0x0F9A
|
|
db 0
|
|
.data_entry_16: dd 0xFFFF ; 0x20
|
|
db 0
|
|
dw 0x0F92
|
|
db 0
|
|
.user_code: dd 0xFFFF ; 0x2B
|
|
db 0
|
|
dw 0xCFFA
|
|
db 0
|
|
.user_data: dd 0xFFFF ; 0x33
|
|
db 0
|
|
dw 0xCFF2
|
|
db 0
|
|
.tss: dd 0x68 ; 0x38
|
|
db 0
|
|
dw 0xE9
|
|
db 0
|
|
dq 0
|
|
.code_entry64: dd 0xFFFF ; 0x48
|
|
db 0
|
|
dw 0xAF9A
|
|
db 0
|
|
.data_entry64: dd 0xFFFF ; 0x50
|
|
db 0
|
|
dw 0xAF92
|
|
db 0
|
|
.user_code64: dd 0xFFFF ; 0x5B
|
|
db 0
|
|
dw 0xAFFA
|
|
db 0
|
|
.user_data64: dd 0xFFFF ; 0x63
|
|
db 0
|
|
dw 0xAFF2
|
|
db 0
|
|
.user_code64c: dd 0xFFFF ; 0x6B
|
|
db 0
|
|
dw 0xAFFA
|
|
db 0
|
|
.gdt: dw (gdt_data.gdt - gdt_data - 1)
|
|
.gdt2: dq gdt_data
|