add kernel stuff, idt, welcome message
This commit is contained in:
18
README.md
18
README.md
@@ -1,3 +1,5 @@
|
|||||||
|
Call me Terry Davis because... actually please don't. I have visions: aspirations, not hallucinations :p
|
||||||
|
|
||||||
# bootle
|
# bootle
|
||||||
|
|
||||||
hobby kernel written in rust. It's just for playing around... for now :p
|
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 ------+
|
+------ 0x00100000 ------+
|
||||||
| hardware, bios stuff |
|
| hardware, bios stuff |
|
||||||
+------ 0x00080000 ------+
|
+------ 0x00080000 ------+
|
||||||
| free |
|
| |
|
||||||
|
| |
|
||||||
+------ 0x00010200 ------+
|
+------ 0x00010200 ------+
|
||||||
| kernel (kernel.asm) |
|
| x86_64 kernel |
|
||||||
+------ 0x00010000 ------+
|
+------ 0x00010000 ------+
|
||||||
| free |
|
| |
|
||||||
|
| |
|
||||||
|
+------ 0x00009000 ------+
|
||||||
|
| IDT |
|
||||||
|
+------ 0x00008000 ------+
|
||||||
|
| |
|
||||||
|
| |
|
||||||
+------ 0x00007E00 ------+
|
+------ 0x00007E00 ------+
|
||||||
| bootloader (boot.asm) |
|
| bootloader (boot.asm) |
|
||||||
+------ 0x00007C00 ------+
|
+------ 0x00007C00 ------+
|
||||||
@@ -34,7 +43,8 @@ run with `nix run git+https://git.mtgmonkey.net/andromeda/bootler#bootler`
|
|||||||
+------ 0x00002000 ------+
|
+------ 0x00002000 ------+
|
||||||
| PML4T |
|
| PML4T |
|
||||||
+------ 0x00001000 ------+
|
+------ 0x00001000 ------+
|
||||||
| free |
|
| |
|
||||||
|
| |
|
||||||
+------ 0x00000500 ------+
|
+------ 0x00000500 ------+
|
||||||
| bios stuff |
|
| bios stuff |
|
||||||
+------ 0x00000000 ------+
|
+------ 0x00000000 ------+
|
||||||
|
|||||||
108
asm/boot.asm
108
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_LOAD_ADDR equ 0x1000 ; start of page table; 4 * pt size
|
||||||
PAGE_TABLE_SIZE equ 0x1000 ; size of page table in bytes
|
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
|
A20_LINE_ENABLE equ 0x2401 ; magic number in ax to enable a20 line with 0x15
|
||||||
BIOS_INT_DISK_OP equ 0x13
|
BIOS_INT_DISK_OP equ 0x13
|
||||||
BIOS_INT_MEMORY_OP equ 0x15
|
BIOS_INT_MEMORY_OP equ 0x15
|
||||||
@@ -42,7 +49,7 @@ cld
|
|||||||
; activate a20
|
; activate a20
|
||||||
mov ax, A20_LINE_ENABLE
|
mov ax, A20_LINE_ENABLE
|
||||||
int BIOS_INT_MEMORY_OP
|
int BIOS_INT_MEMORY_OP
|
||||||
jc error_a20_line
|
jc error
|
||||||
mov si, msg_a20_line
|
mov si, msg_a20_line
|
||||||
call print
|
call print
|
||||||
|
|
||||||
@@ -59,7 +66,7 @@ xor bx, bx
|
|||||||
; read disk
|
; read disk
|
||||||
mov ah, 0x02
|
mov ah, 0x02
|
||||||
int BIOS_INT_DISK_OP
|
int BIOS_INT_DISK_OP
|
||||||
jc error_disk_read
|
jc error
|
||||||
mov si, msg_disk_read
|
mov si, msg_disk_read
|
||||||
call print
|
call print
|
||||||
|
|
||||||
@@ -143,17 +150,11 @@ lm_load:
|
|||||||
|
|
||||||
jmp 0x08:lm_start
|
jmp 0x08:lm_start
|
||||||
|
|
||||||
error_a20_line:
|
error:
|
||||||
mov si, .msg
|
mov si, .msg
|
||||||
call print
|
call print
|
||||||
jmp done
|
.msg db "err ", 0x00
|
||||||
.msg db "err a20 line", 0x00
|
ret
|
||||||
|
|
||||||
error_disk_read:
|
|
||||||
mov si, .msg
|
|
||||||
call print
|
|
||||||
jmp done
|
|
||||||
.msg db "err disk read", 0x00
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
hlt
|
hlt
|
||||||
@@ -172,11 +173,6 @@ print:
|
|||||||
popad
|
popad
|
||||||
ret
|
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)
|
; TODO make readable (yoinked from https://wiki.osdev.org/Entering_Long_Mode_Directly)
|
||||||
gdt_data:
|
gdt_data:
|
||||||
dq 0x0000000000000000
|
dq 0x0000000000000000
|
||||||
@@ -202,10 +198,88 @@ lm_start:
|
|||||||
; TODO poll and whatnot (in rust??)
|
; TODO poll and whatnot (in rust??)
|
||||||
mov dx, 0x3F8
|
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
|
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_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
|
times 510-($-$$) db 0 ; 2 bytes less now
|
||||||
db 0x55
|
db 0x55
|
||||||
|
|||||||
36
src/lib.rs
36
src/lib.rs
@@ -5,12 +5,11 @@ use core::panic::PanicInfo;
|
|||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
pub extern "C" fn _start() -> ! {
|
pub extern "C" fn _start() -> ! {
|
||||||
// 'k'
|
welcome_serial();
|
||||||
print("kernel\n");
|
halt()
|
||||||
loop {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print(s: &str) {
|
fn print_serial(s: &str) {
|
||||||
let mut bytes = s.bytes();
|
let mut bytes = s.bytes();
|
||||||
while let Some(b) = bytes.next() {
|
while let Some(b) = bytes.next() {
|
||||||
unsafe {core::arch::asm!(
|
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]
|
#[panic_handler]
|
||||||
fn panic(_: &PanicInfo) -> ! {
|
fn panic(_: &PanicInfo) -> ! {
|
||||||
print("panicked");
|
print_serial("panicked");
|
||||||
loop {}
|
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";
|
||||||
|
|||||||
Reference in New Issue
Block a user