use long mode, x86_64-unknown-none works now
This commit is contained in:
@@ -1,2 +1,5 @@
|
|||||||
[build]
|
[build]
|
||||||
target = "x86_64-unknown-none"
|
target = "x86_64-unknown-none"
|
||||||
|
rustflags = [
|
||||||
|
"-Crelocation-model=static"
|
||||||
|
]
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -16,7 +16,7 @@ run with `nix run git+https://git.mtgmonkey.net/andromeda/bootler#bootler`
|
|||||||
+------ 0x00100000 ------+
|
+------ 0x00100000 ------+
|
||||||
| hardware, bios stuff |
|
| hardware, bios stuff |
|
||||||
+------ 0x00080000 ------+
|
+------ 0x00080000 ------+
|
||||||
| pm stack (esp) | from boot.asm
|
| free |
|
||||||
+------ 0x00010200 ------+
|
+------ 0x00010200 ------+
|
||||||
| kernel (kernel.asm) |
|
| kernel (kernel.asm) |
|
||||||
+------ 0x00010000 ------+
|
+------ 0x00010000 ------+
|
||||||
@@ -24,7 +24,17 @@ run with `nix run git+https://git.mtgmonkey.net/andromeda/bootler#bootler`
|
|||||||
+------ 0x00007E00 ------+
|
+------ 0x00007E00 ------+
|
||||||
| bootloader (boot.asm) |
|
| bootloader (boot.asm) |
|
||||||
+------ 0x00007C00 ------+
|
+------ 0x00007C00 ------+
|
||||||
| real mode stack (sp) | from boot.asm
|
| stack | TODO get real stack
|
||||||
|
+------ 0x00005000 ------+
|
||||||
|
| PT |
|
||||||
|
+------ 0x00004000 ------+
|
||||||
|
| PDT |
|
||||||
|
+------ 0x00003000 ------+
|
||||||
|
| PDPT |
|
||||||
|
+------ 0x00002000 ------+
|
||||||
|
| PML4T |
|
||||||
|
+------ 0x00001000 ------+
|
||||||
|
| free |
|
||||||
+------ 0x00000500 ------+
|
+------ 0x00000500 ------+
|
||||||
| bios stuff |
|
| bios stuff |
|
||||||
+------ 0x00000000 ------+
|
+------ 0x00000000 ------+
|
||||||
|
|||||||
290
asm/boot.asm
290
asm/boot.asm
@@ -3,155 +3,209 @@
|
|||||||
; 2026 Andromeda
|
; 2026 Andromeda
|
||||||
; GPL licensed
|
; GPL licensed
|
||||||
|
|
||||||
|
LOAD_ADDR equ 0x7C00
|
||||||
|
|
||||||
|
KERNEL_START equ 2 ; first sector on disk to load kernel from; 1 indexed
|
||||||
|
KERNEL_SIZE equ 1 ; length of kernel in sectors
|
||||||
|
KERNEL_LOAD_ADDR_ES equ 0x1000 ; kernel to be loaded at es * 0x10 + 0x0000
|
||||||
|
|
||||||
|
PAGE_TABLE_LOAD_ADDR equ 0x1000 ; start of page table; 4 * pt size
|
||||||
|
PAGE_TABLE_SIZE equ 0x1000 ; size of page table in bytes
|
||||||
|
|
||||||
|
A20_LINE_ENABLE equ 0x2401 ; magic number in ax to enable a20 line with 0x15
|
||||||
|
BIOS_INT_DISK_OP equ 0x13
|
||||||
|
BIOS_INT_MEMORY_OP equ 0x15
|
||||||
|
|
||||||
|
CR0_PE equ 1 << 0 ; Protected Mode Enabled
|
||||||
|
CR0_PG equ 1 << 31 ; Paging
|
||||||
|
|
||||||
|
CR4_PAE equ 1 << 5 ; Physical Address Extension
|
||||||
|
CR4_PGE equ 1 << 7 ; Page Global Enabled
|
||||||
|
|
||||||
|
MSR_IA32_EFER equ 0xC0000080 ; Extended Feature Enable model-specific Register
|
||||||
|
|
||||||
[bits 16]
|
[bits 16]
|
||||||
[org 0x7C00] ; address where bootloader is loaded
|
[org LOAD_ADDR]
|
||||||
|
|
||||||
|
jmp 0x0000:.cs_reset ; in case it loads us at 0x7C00:0x0000
|
||||||
|
.cs_reset:
|
||||||
|
|
||||||
xor ax, ax
|
xor ax, ax
|
||||||
|
mov ss, ax
|
||||||
|
mov sp, LOAD_ADDR ; stack builds down, loader faces up
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov ss, ax
|
mov fs, ax
|
||||||
mov sp, 0x7C00
|
mov gs, ax
|
||||||
|
cld
|
||||||
mov ah, 0x0E
|
|
||||||
mov al, 'R'
|
|
||||||
int 0x10
|
|
||||||
mov al, 'e'
|
|
||||||
int 0x10
|
|
||||||
mov al, 'a'
|
|
||||||
int 0x10
|
|
||||||
mov al, 'l'
|
|
||||||
int 0x10
|
|
||||||
mov al, 0x0D
|
|
||||||
int 0x10
|
|
||||||
mov al, 0x0A
|
|
||||||
int 0x10
|
|
||||||
mov al, 0x00 ; stops serial and bios output from overlapping in qemu -nographic
|
|
||||||
int 0x10 ; output
|
|
||||||
|
|
||||||
; activate a20
|
; activate a20
|
||||||
mov ax, 0x2401
|
mov ax, A20_LINE_ENABLE
|
||||||
int 0x15
|
int BIOS_INT_MEMORY_OP
|
||||||
jc error
|
jc error_a20_line
|
||||||
|
mov si, msg_a20_line
|
||||||
|
call print
|
||||||
|
|
||||||
; load kernel
|
; prep to read disk
|
||||||
; 'docs' from https://www.ctyme.com/intr/rb-0607.htm
|
mov al, KERNEL_SIZE ; size in sectors, min. 1
|
||||||
mov ah, 0x02
|
mov ch, 0 ; cylinder
|
||||||
mov al, 1 ; number of sectors to read (must be nonzero)
|
mov cl, KERNEL_START ; start sector, 1-indexed
|
||||||
mov ch, 0 ; low eight bits of cylinder number
|
mov dh, 0 ; head
|
||||||
mov cl, 2 ; sector number 1-63 (bits 0-5); high two bits of cylinder (bits 6-7,
|
; dl set by bios
|
||||||
; hard disk only)
|
mov bx, KERNEL_LOAD_ADDR_ES ; load addr es:bx
|
||||||
mov dh, 0 ; head number
|
|
||||||
; dl is already set by bios
|
|
||||||
mov bx, 0x1000 ; data buffer
|
|
||||||
mov es, bx
|
mov es, bx
|
||||||
xor bx, bx
|
xor bx, bx
|
||||||
int 0x13 ; read disk
|
|
||||||
jc error
|
|
||||||
|
|
||||||
; load gdt
|
; read disk
|
||||||
lgdt [gdt_descriptor]
|
mov ah, 0x02
|
||||||
|
int BIOS_INT_DISK_OP
|
||||||
|
jc error_disk_read
|
||||||
|
mov si, msg_disk_read
|
||||||
|
call print
|
||||||
|
|
||||||
; jump to pm
|
; zero es
|
||||||
cli
|
push ax
|
||||||
mov eax, cr0
|
xor ax, ax
|
||||||
or eax, 1
|
mov es, ax
|
||||||
mov cr0, eax
|
pop ax
|
||||||
jmp 0x08:pm_start
|
|
||||||
|
|
||||||
error:
|
mov edi, PAGE_TABLE_LOAD_ADDR
|
||||||
mov al, 'e'
|
jmp lm_load
|
||||||
int 0x10
|
|
||||||
mov al, 'r'
|
|
||||||
int 0x10
|
|
||||||
mov al, 'r'
|
|
||||||
int 0x10
|
|
||||||
mov al, 'o'
|
|
||||||
int 0x10
|
|
||||||
mov al, 'r'
|
|
||||||
int 0x10
|
|
||||||
jmp $
|
|
||||||
|
|
||||||
|
; expects:
|
||||||
|
; es:edi -> 16kb for page table
|
||||||
|
; ss:esp -> stack
|
||||||
|
; heavily based on https://wiki.osdev.org/Entering_Long_Mode_Directly
|
||||||
|
lm_load:
|
||||||
|
; clear page table
|
||||||
|
push di
|
||||||
|
mov ecx, PAGE_TABLE_SIZE
|
||||||
|
xor eax, eax
|
||||||
|
cld
|
||||||
|
rep stosd ; clear space for all 4 tables
|
||||||
|
pop di
|
||||||
|
|
||||||
|
; PML4TE0
|
||||||
|
lea eax, [es:di + PAGE_TABLE_SIZE]
|
||||||
|
or eax, 11b
|
||||||
|
mov [es:di], eax
|
||||||
|
|
||||||
|
; PDPT0E0
|
||||||
|
lea eax, [es:di + 2 * PAGE_TABLE_SIZE]
|
||||||
|
or eax, 11b
|
||||||
|
mov [es:di + PAGE_TABLE_SIZE], eax
|
||||||
|
|
||||||
|
; PDT0E0
|
||||||
|
lea eax, [es:di + 3 * PAGE_TABLE_SIZE]
|
||||||
|
or eax, 11b
|
||||||
|
mov [es:di + 2 * PAGE_TABLE_SIZE], eax
|
||||||
|
|
||||||
|
; PT0
|
||||||
|
push di
|
||||||
|
lea di, [di + 3 * PAGE_TABLE_SIZE]
|
||||||
|
mov eax, 0x11
|
||||||
|
|
||||||
|
.set_pt_entry
|
||||||
|
mov [es:di], eax
|
||||||
|
add eax, 0x1000
|
||||||
|
add di, 8
|
||||||
|
cmp eax, 0x200000 ; size of page
|
||||||
|
jb .set_pt_entry
|
||||||
|
|
||||||
|
pop di
|
||||||
|
|
||||||
|
; disable interrupts from PIC by masking all interrupts
|
||||||
|
mov al, 0xFF ; mask
|
||||||
|
out 0xA1, al
|
||||||
|
out 0x21, al
|
||||||
|
|
||||||
|
; PAE, PGE
|
||||||
|
mov eax, CR4_PAE | CR4_PGE
|
||||||
|
mov cr4, eax
|
||||||
|
|
||||||
|
; cr3 -> PML4TE0
|
||||||
|
mov edx, edi
|
||||||
|
mov cr3, edx
|
||||||
|
|
||||||
|
; highs LME bit in EFER
|
||||||
|
mov ecx, MSR_IA32_EFER
|
||||||
|
rdmsr
|
||||||
|
or eax, 0x00000100
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
; activate long mode
|
||||||
|
mov ebx, cr0
|
||||||
|
or ebx, CR0_PG | CR0_PE
|
||||||
|
mov cr0, ebx
|
||||||
|
|
||||||
|
cli
|
||||||
|
lgdt [gdt_descriptor]
|
||||||
|
|
||||||
|
jmp 0x08:lm_start
|
||||||
|
|
||||||
|
error_a20_line:
|
||||||
|
mov si, .msg
|
||||||
|
call print
|
||||||
|
jmp done
|
||||||
|
.msg db "err a20 line", 0x00
|
||||||
|
|
||||||
|
error_disk_read:
|
||||||
|
mov si, .msg
|
||||||
|
call print
|
||||||
|
jmp done
|
||||||
|
.msg db "err disk read", 0x00
|
||||||
|
|
||||||
|
done:
|
||||||
|
hlt
|
||||||
|
jmp done
|
||||||
|
|
||||||
|
print:
|
||||||
|
pushad
|
||||||
|
.loop
|
||||||
|
lodsb
|
||||||
|
test al, al
|
||||||
|
je .done
|
||||||
|
mov ah, 0x0E
|
||||||
|
int 0x10
|
||||||
|
jmp .loop
|
||||||
|
.done
|
||||||
|
popad
|
||||||
|
ret
|
||||||
|
|
||||||
|
; TODO make real idt
|
||||||
|
empty_idt:
|
||||||
|
dw 0 ; length
|
||||||
|
dd 0 ; base
|
||||||
|
|
||||||
|
; TODO make readable (yoinked from https://wiki.osdev.org/Entering_Long_Mode_Directly)
|
||||||
gdt_data:
|
gdt_data:
|
||||||
; null segment
|
|
||||||
dq 0x0000000000000000
|
dq 0x0000000000000000
|
||||||
; code segment
|
dq 0x00209A0000000000
|
||||||
dw 0xFFFF
|
dq 0x0000920000000000
|
||||||
dw 0x0000
|
|
||||||
|
|
||||||
db 0x00
|
|
||||||
db 10011010b ; 32-bit code segment, present, ring 0
|
|
||||||
db 11001111b ; limit bits 16-19
|
|
||||||
db 0x00
|
|
||||||
|
|
||||||
; data segment
|
|
||||||
dw 0xFFFF
|
|
||||||
dw 0x0000
|
|
||||||
|
|
||||||
db 0x00
|
|
||||||
db 10010010b ; 32-bit data segment, present, ring 0
|
|
||||||
db 11001111b ; limit bits 16-19
|
|
||||||
db 0x00
|
|
||||||
|
|
||||||
gdt_descriptor:
|
gdt_descriptor:
|
||||||
dw $ - gdt_data - 1 ; size
|
dw $ - gdt_data - 1 ; size
|
||||||
dd gdt_data ; start
|
dd gdt_data ; start
|
||||||
|
|
||||||
[bits 32]
|
[bits 64]
|
||||||
|
|
||||||
; entry point
|
; long mode entry
|
||||||
pm_start:
|
lm_start:
|
||||||
; data segment registers
|
|
||||||
mov ax, 0x10
|
mov ax, 0x10
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
mov ss, ax
|
mov ss, ax
|
||||||
mov esp, 0x80000
|
|
||||||
|
|
||||||
; TODO actually configure COM1
|
; set up serial device
|
||||||
mov dx, 0x3F8 ; COM1
|
; TODO poll and whatnot (in rust??)
|
||||||
mov al, 'P'
|
mov dx, 0x3F8
|
||||||
out dx, al
|
|
||||||
mov al, 'r'
|
|
||||||
out dx, al
|
|
||||||
mov al, 'o'
|
|
||||||
out dx, al
|
|
||||||
mov al, 't'
|
|
||||||
out dx, al
|
|
||||||
mov al, 'e'
|
|
||||||
out dx, al
|
|
||||||
mov al, 'c'
|
|
||||||
out dx, al
|
|
||||||
mov al, 't'
|
|
||||||
out dx, al
|
|
||||||
mov al, 'e'
|
|
||||||
out dx, al
|
|
||||||
mov al, 'd'
|
|
||||||
out dx, al
|
|
||||||
mov al, 0x0D
|
|
||||||
out dx, al
|
|
||||||
mov al, 0x0A
|
|
||||||
out dx, al
|
|
||||||
|
|
||||||
jmp 0x08:0x10000
|
jmp KERNEL_LOAD_ADDR_ES * 0x10
|
||||||
|
|
||||||
pm_error:
|
msg_a20_line db "a20 line", 0x0D, 0x0A, 0x00
|
||||||
mov al, 'p'
|
msg_disk_read db "disk read", 0x0D, 0x0A, 0x00
|
||||||
out dx, al
|
|
||||||
mov al, 'm'
|
|
||||||
out dx, al
|
|
||||||
mov al, 'e'
|
|
||||||
out dx, al
|
|
||||||
mov al, 'r'
|
|
||||||
out dx, al
|
|
||||||
mov al, 'r'
|
|
||||||
out dx, al
|
|
||||||
mov al, 'o'
|
|
||||||
out dx, al
|
|
||||||
mov al, 'r'
|
|
||||||
out dx, al
|
|
||||||
jmp $
|
|
||||||
|
|
||||||
times 510-($-$$) db 0 ; 2 bytes less now
|
times 510-($-$$) db 0 ; 2 bytes less now
|
||||||
db 0x55
|
db 0x55
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
[bits 32]
|
[bits 64]
|
||||||
|
|
||||||
mov al, 'K'
|
mov al, 'K'
|
||||||
out dx, al
|
out dx, al
|
||||||
@@ -18,6 +18,6 @@ mov al, 0x0A
|
|||||||
out dx, al
|
out dx, al
|
||||||
mov al, 0x00
|
mov al, 0x00
|
||||||
out dx, al
|
out dx, al
|
||||||
jmp $
|
.done
|
||||||
|
hlt
|
||||||
times 512-($-$$) db 0
|
jmp .done
|
||||||
|
|||||||
@@ -23,7 +23,11 @@ in (naersk'.buildPackage {
|
|||||||
release = true;
|
release = true;
|
||||||
|
|
||||||
# build std
|
# build std
|
||||||
cargoBuildOptions = x: x ++ ["-Zbuild-std=core,compiler_builtins,alloc" "-Zbuild-std-features=compiler-builtins-mem"];
|
cargoBuildOptions = x:
|
||||||
|
x
|
||||||
|
++ [
|
||||||
|
"-Zbuild-std=core,compiler_builtins"
|
||||||
|
];
|
||||||
|
|
||||||
postInstall = ''
|
postInstall = ''
|
||||||
ld --oformat binary \
|
ld --oformat binary \
|
||||||
|
|||||||
21
src/lib.rs
21
src/lib.rs
@@ -6,15 +6,22 @@ use core::panic::PanicInfo;
|
|||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
pub extern "C" fn _start() -> ! {
|
pub extern "C" fn _start() -> ! {
|
||||||
// 'k'
|
// 'k'
|
||||||
loop{unsafe {core::arch::asm!(
|
print("kernel\n");
|
||||||
"out dx, al", in("al") 0x6Bu8
|
loop {}
|
||||||
)}}
|
}
|
||||||
|
|
||||||
|
fn print(s: &str) {
|
||||||
|
let mut bytes = s.bytes();
|
||||||
|
while let Some(b) = bytes.next() {
|
||||||
|
unsafe {core::arch::asm!(
|
||||||
|
"out dx, al"
|
||||||
|
, in("al") b
|
||||||
|
)};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
fn panic(_: &PanicInfo) -> ! {
|
fn panic(_: &PanicInfo) -> ! {
|
||||||
// 'p'
|
print("panicked");
|
||||||
loop{unsafe {core::arch::asm!(
|
loop {}
|
||||||
"out dx, al", in("al") 0x70u8
|
|
||||||
)}}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user