summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md18
-rw-r--r--asm/boot.asm108
-rw-r--r--src/lib.rs36
3 files changed, 135 insertions, 27 deletions
diff --git a/README.md b/README.md
index 52a1395..fabc1d9 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,5 @@
+Call me Terry Davis because... actually please don't. I have visions: aspirations, not hallucinations :p
+
# bootle
hobby kernel written in rust. It's just for playing around... for now :p
@@ -16,11 +18,18 @@ run with `nix run git+https://git.mtgmonkey.net/andromeda/bootler#bootler`
+------ 0x00100000 ------+
| hardware, bios stuff |
+------ 0x00080000 ------+
-| free |
+| |
+| |
+------ 0x00010200 ------+
-| kernel (kernel.asm) |
+| x86_64 kernel |
+------ 0x00010000 ------+
-| free |
+| |
+| |
++------ 0x00009000 ------+
+| IDT |
++------ 0x00008000 ------+
+| |
+| |
+------ 0x00007E00 ------+
| bootloader (boot.asm) |
+------ 0x00007C00 ------+
@@ -34,7 +43,8 @@ run with `nix run git+https://git.mtgmonkey.net/andromeda/bootler#bootler`
+------ 0x00002000 ------+
| PML4T |
+------ 0x00001000 ------+
-| free |
+| |
+| |
+------ 0x00000500 ------+
| bios stuff |
+------ 0x00000000 ------+
diff --git a/asm/boot.asm b/asm/boot.asm
index 29e807c..5291d58 100644
--- a/asm/boot.asm
+++ b/asm/boot.asm
@@ -12,6 +12,13 @@ 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
+; 64 bit IDT stuff
+IDT_ADDR equ 0x8000 ; bottom of IDT
+IDT_SIZE equ 0x1000 ; size of IDT
+
+IDT_SEGMENT equ 0x0008 ; gdt code segment to jump to for idt calls
+
+; magic numbers and things
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
@@ -42,7 +49,7 @@ cld
; activate a20
mov ax, A20_LINE_ENABLE
int BIOS_INT_MEMORY_OP
-jc error_a20_line
+jc error
mov si, msg_a20_line
call print
@@ -59,7 +66,7 @@ xor bx, bx
; read disk
mov ah, 0x02
int BIOS_INT_DISK_OP
-jc error_disk_read
+jc error
mov si, msg_disk_read
call print
@@ -143,17 +150,11 @@ lm_load:
jmp 0x08:lm_start
-error_a20_line:
- mov si, .msg
- call print
- jmp done
- .msg db "err a20 line", 0x00
-
-error_disk_read:
+error:
mov si, .msg
call print
- jmp done
- .msg db "err disk read", 0x00
+ .msg db "err ", 0x00
+ ret
done:
hlt
@@ -172,11 +173,6 @@ print:
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:
dq 0x0000000000000000
@@ -201,11 +197,89 @@ lm_start:
; set up serial device
; TODO poll and whatnot (in rust??)
mov dx, 0x3F8
+
+ ; qemu -no-graphic overlaps serial and bios output without this
+ mov al, 0x0D
+ out dx, al
+ mov al, 0x0A
+ out dx, al
+
+ ; initialize IDT at IDT_ADDR
+ call idt_init
+
+ int3 ; silly test
jmp KERNEL_LOAD_ADDR_ES * 0x10
+idt_init:
+ ; clear space for idt
+ mov rdi, IDT_ADDR
+ push di
+ mov rcx, IDT_SIZE / 4
+ xor rax, rax
+ cld
+ rep stosd ; clear double word for each rcx
+ pop di
+
+ push rdx ; dx contains the output device
+ ; nothing between here and the `pop rdx` will be able to print
+
+ ; breakpoint
+ mov rdi, 0x8E ; present, no dpl, interrupt
+ mov rsi, 0x03 ; breakpoint interrupt
+ lea rdx, [int_hdl_dummy]
+ call mk_idt_entry
+
+ pop rdx ; get back dx output device
+
+ lidt [idt_descriptor]
+
+ ret
+
+int_hdl_dummy:
+ mov rsi, .msg
+ call lm_print
+ iretq
+ .msg db "INTdummy", 0x0D, 0x0A, 0x00
+
+; rdi = flags
+; rsi = entry number
+; rdx -> handler
+mk_idt_entry:
+ mov rax, rdx
+ mov rcx, rsi
+
+ shl rcx, 4 ; offset = entry number * 16
+ add rcx, IDT_ADDR
+
+ mov word [rcx + 0], ax ; offset
+ mov word [rcx + 2], IDT_SEGMENT ; code segment
+ mov word [rcx + 5], di
+ mov byte [rcx + 4], 0 ; IST (0 = none)
+ shr rax, 16
+ mov word [rcx + 6], ax ; offset
+ shr rax, 16
+ mov dword [rcx + 8], eax ; offset
+ mov dword [rcx + 12], 0 ; reserved
+ ret
+
+lm_print:
+ .loop
+ mov al, [rsi]
+ test al, al
+ jz .done
+ out dx, al
+ inc si
+ jmp .loop
+ .done:
+ ret
+
+idt_descriptor:
+ dw IDT_SIZE - 1 ; size
+ dq IDT_ADDR ; start
+
msg_a20_line db "a20 line", 0x0D, 0x0A, 0x00
-msg_disk_read db "disk read", 0x0D, 0x0A, 0x00
+msg_disk_read db "disk", 0x0D, 0x0A, 0x00
times 510-($-$$) db 0 ; 2 bytes less now
db 0x55
diff --git a/src/lib.rs b/src/lib.rs
index f942513..18bb65c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -5,12 +5,11 @@ use core::panic::PanicInfo;
#[unsafe(no_mangle)]
pub extern "C" fn _start() -> ! {
- // 'k'
- print("kernel\n");
- loop {}
+ welcome_serial();
+ halt()
}
-fn print(s: &str) {
+fn print_serial(s: &str) {
let mut bytes = s.bytes();
while let Some(b) = bytes.next() {
unsafe {core::arch::asm!(
@@ -20,8 +19,33 @@ fn print(s: &str) {
};
}
+fn println_serial(s: &str) {
+ print_serial(s);
+ print_serial("\n");
+}
+
+fn welcome_serial() {
+ print_serial(ANSI_PINK);
+ println_serial("\nWelcome to Bootle OS");
+ println_serial("All code GPL licensed and freely available on git.mtgmonkey.net");
+ print_serial("Enjoy your time! Press "); print_serial(ANSI_RED); print_serial("ctrl+a x"); print_serial(ANSI_PINK); println_serial(" to escape Qemu");
+ print_serial(ANSI_CLEAR);
+}
+
#[panic_handler]
fn panic(_: &PanicInfo) -> ! {
- print("panicked");
- loop {}
+ print_serial("panicked");
+ halt()
}
+
+fn halt() -> ! {
+ unsafe {core::arch::asm!(
+ "hlt"
+ )};
+ halt()
+}
+
+const ANSI_CLEAR: &str = "\x1b[0m";
+const ANSI_RED: &str = "\x1b[31m";
+const ANSI_PINK: &str = "\x1b[35m";
+const ANSI_GREEN: &str = "\x1b[32m";