diff --git a/Kernel/Core/logging.rs b/Kernel/Core/logging.rs index 6d282479d2606dad13bed3f2bd325f843bfee8fe..d6fbee21cd4f19b8157e1d3af74031b36b7f2e3e 100644 --- a/Kernel/Core/logging.rs +++ b/Kernel/Core/logging.rs @@ -88,6 +88,7 @@ macro_rules! log( ($lvl:expr, $modname:expr, $($arg:tt)*) => ( )) macro_rules! log_notice( ($($arg:tt)*) => (log!(::logging::LevelLog, "TODO", $($arg)*)) ) macro_rules! log_log( ($($arg:tt)*) => (log!(::logging::LevelNotice, "TODO", $($arg)*)) ) +macro_rules! log_debug( ($($arg:tt)*) => (log!(::logging::LevelLog, "TODO", $($arg)*)) ) // vim: ft=rust diff --git a/Kernel/Core/main.rs b/Kernel/Core/main.rs index f6eee368c85b1162c651080fafe12cd8180e2bb7..6a02151efac0765f280df2cb2a64bc0509d45f84 100644 --- a/Kernel/Core/main.rs +++ b/Kernel/Core/main.rs @@ -1,13 +1,18 @@ +// "Tifflin" Kernel +// - By John Hodge (thePowersGang) // -// -// +// Core/main.rs +// - Kernel main #![no_std] #![feature(phase)] #![feature(macro_rules)] #[phase(plugin, link)] extern crate core; +extern crate common; extern crate arch; +use core::option::{Some,None}; + // Evil Hack: For some reason, write! (and friends) will expand pointing to std instead of core mod std { pub use core::fmt; } @@ -26,7 +31,13 @@ pub extern "C" fn kmain() ::memory::virt::init(); ::memory::heap::init(); + log_log!("Command line = '{}'", ::arch::boot::get_boot_string()); //::devices::display::init(); + let vidmode = ::arch::boot::get_video_mode(); + match vidmode { + Some(m) => log_debug!("Video mode : {}x{}", m.width, m.height), + None => log_debug!("No video mode present") + } } // Evil fail when doing unwind diff --git a/Kernel/Makefile b/Kernel/Makefile index a46e1d43a1535972f73d1e7c6b79e85252106f52..b5978955c414573eb20221eb952ac3dc81a19f6a 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -4,6 +4,8 @@ ARCH = amd64 OBJS := start.o kcore.o libarch.rlib libcore.rlib +V ?= @ + nop := space := $(nop) $(nop) comma := , @@ -48,17 +50,22 @@ kernel-$(ARCH).bin: $(OBJS) arch/$(ARCH)/link.ld Makefile $(OBJDIR)start.o: arch/$(ARCH)/start.asm Makefile @echo [AS] -o $@ @mkdir -p $(dir $@) - @nasm -o $@ $< -f elf64 + @nasm -o $@ $< -f elf64 -MD $@.dep -MP $(OBJDIR)kcore.o: Core/main.rs $(OBJDIR)libarch.rlib $(OBJDIR)libcore.rlib Makefile @echo [RUSTC] -o $@ @mkdir -p $(dir $@) - @$(ENV) rustc -O $(RUSTFLAGS) --emit obj -o $@ $< --dep-info $@.dep $(call LocalLib,core) $(call LocalLib,arch) + $V$(ENV) rustc -O $(RUSTFLAGS) --emit obj -o $@ $< --dep-info $@.dep $(call LocalLib,core) $(call LocalLib,arch) $(call LocalLib,common) + +$(OBJDIR)libarch.rlib: arch/$(ARCH)/crate.rs $(OBJDIR)libcommon.rlib $(OBJDIR)libcore.rlib Makefile + @echo [RUSTC] -o $@ + mkdir -p $(dir $@) + @$(ENV) rustc -O $(RUSTFLAGS) --crate-name arch -o $@ $< --dep-info $@.dep $(call LocalLib,core) $(call LocalLib,common) -$(OBJDIR)libarch.rlib: arch/$(ARCH)/crate.rs $(OBJDIR)libcore.rlib Makefile +$(OBJDIR)libcommon.rlib: common/lib.rs $(OBJDIR)libcore.rlib Makefile @echo [RUSTC] -o $@ mkdir -p $(dir $@) - @$(ENV) rustc -O $(RUSTFLAGS) --crate-name arch -o $@ $< --dep-info $@.dep $(call LocalLib,core) + @$(ENV) rustc -O $(RUSTFLAGS) --crate-name common -o $@ $< --dep-info $@.dep $(call LocalLib,core) # - Locally compiled libcore, needs to not use SSE $(OBJDIR)libcore.rlib: $(LIBCORESRC)lib.rs diff --git a/Kernel/RunQemuPXE b/Kernel/RunQemuPXE new file mode 100755 index 0000000000000000000000000000000000000000..24166c2bc9accc307ab13ad468165e1715d91d50 --- /dev/null +++ b/Kernel/RunQemuPXE @@ -0,0 +1,14 @@ +#!/bin/sh + +IMAGE=$1 +ARGS=$2 + +rm -rf .pxe/ +mkdir -p .pxe/pxelinux.cfg +cp /home/tftpboot/boot/pxelinux.0 /home/tftpboot/boot/mboot.c32 .pxe/ +cp $IMAGE .pxe +echo "default testkern" >> .pxe/pxelinux.cfg/default +echo "label testkern" >> .pxe/pxelinux.cfg/default +echo " kernel mboot.c32" >> .pxe/pxelinux.cfg/default +echo " append $IMAGE $ARGS" >> .pxe/pxelinux.cfg/default +qemu-system-x86_64 -net nic -net user,tftp=.pxe/,bootfile=pxelinux.0 -boot n -nographic diff --git a/Kernel/arch/amd64/boot.rs b/Kernel/arch/amd64/boot.rs new file mode 100644 index 0000000000000000000000000000000000000000..ba3961e3bf1a83519a13edcde19ce72211c72393 --- /dev/null +++ b/Kernel/arch/amd64/boot.rs @@ -0,0 +1,129 @@ +// "Tifflin" Kernel +// - By John Hodge (thePowersGang) +// +// arch/amd64/boot.rs +// - Boot information + +use core::option::{Option,None,Some}; +use memory::addresses::{ident_start, ident_end}; + +#[repr(C)] +struct MultibootInfo +{ + flags: u32, + // flags[0] + himem: u32, lomem: u32, + // flags[1] + bootdev: u32, + // flags[2] + cmdline: u32, + // flags[3] + module_count: u32, module_first: u32, + // flags[4] or flags[5] + syminfo: [u32,..4], + // flags[6] + memmap_len: u32, + memmap_ptr: u32, + // flags[7] + drives_length: u32, + drives_addr: u32, + // flags[8] + configtable_ptr: u32, // result of BIOS 'GET CONFIGURATION' + // flags[9] + boot_loader_name: u32, // C string, booting loader + // flags[10] + apm_table_ptr: u32, + // flags[11] + vbe_control_info: u32, + vbe_mode_info: u32, + vbe_mode: u32, + vbe_interface_seg: u32, + vbe_interface_off: u32, + vbe_interface_len: u32, +} + +#[repr(C)] +struct VbeModeInfo +{ + attributes: u16, + window_attrs: [u8,..2], + granuality: u16, + window_size: u16, + window_segments: [u16, ..2], + win_pos_fcn_fptr: [u16, ..2], // Pointer to INT 10h, AX=4F05h + + pitch: u16, + x_res: u16, y_res: u16, + char_w: u8, char_h: u8, + n_planes: u8, + bpp: u8, + n_banks: u8, + memory_model: u8, + bank_size: u8, + n_pages: u8, + _resvd: u8, // reserved + + // VBE 1.2+ + +} + +extern "C" +{ + static s_multiboot_signature : u32; + static s_multiboot_pointer : &'static MultibootInfo; +} + +// Retreive the multiboot "command line" string +pub fn get_boot_string() -> &'static str +{ + //::puts("Multiboot signature: "); ::puth(s_multiboot_signature as uint); ::puts("\n"); + //::puts("Multiboot pointer: "); ::puth(s_multiboot_pointer as uint); ::puts("\n"); + if s_multiboot_signature != 0x2BADB002 { + return ""; + } + //::puts("> Flags = "); ::puth(s_multiboot_pointer.flags as uint); ::puts("\n"); + if (s_multiboot_pointer.flags & 1 << 2) == 0 { + return ""; + } + //::puts("> cmdline = "); ::puth(s_multiboot_pointer.cmdline as uint); ::puts("\n"); + + let cmdline_paddr = s_multiboot_pointer.cmdline as uint; + if cmdline_paddr + ident_start >= ident_end { + return ""; + } + + unsafe { + let charptr : *const i8 = ::core::mem::transmute( cmdline_paddr + ident_start ); + ::core::str::raw::c_str_to_static_slice( charptr ) + } +} + +pub fn get_video_mode() -> Option<::common::archapi::VideoMode> +{ + if s_multiboot_signature != 0x2BADB002 { + ::puts("arch::boot::get_video_mode - Multiboot signature not valid\n"); + return None; + } + if (s_multiboot_pointer.flags & 1 << 11) == 0 { + ::puts("arch::boot::get_video_mode - Video mode information not present\n"); + return None; + } + + let vbeinfo_vaddr = s_multiboot_pointer.vbe_mode_info as uint + ident_start; + if vbeinfo_vaddr + ::core::mem::size_of::<VbeModeInfo>() > ident_end { + return None; + } + + let info: &VbeModeInfo = unsafe { + ::core::mem::transmute(vbeinfo_vaddr as *const VbeModeInfo) + }; + + Some( ::common::archapi::VideoMode { + width: info.x_res, + height: info.y_res, + fmt: ::common::archapi::VideoX8R8G8B8, + }) +} + +// vim: ft=rust + diff --git a/Kernel/arch/amd64/common.inc.asm b/Kernel/arch/amd64/common.inc.asm new file mode 100644 index 0000000000000000000000000000000000000000..4da5c8bf69e0f7b582f369c047b754439436cf9a --- /dev/null +++ b/Kernel/arch/amd64/common.inc.asm @@ -0,0 +1,57 @@ + +%define MAX_CPUS 1 +%define KSTACK_BASE 0xFFFFA00000000000 +%define INITIAL_KSTACK_SIZE 16 +%define KERNEL_BASE 0xFFFFFFFF80000000 +%macro SAVE_GPR 1 + mov [%1-0x08], r15 + mov [%1-0x10], r14 + mov [%1-0x18], r13 + mov [%1-0x20], r12 + mov [%1-0x28], r11 + mov [%1-0x30], r10 + mov [%1-0x38], r9 + mov [%1-0x40], r8 + mov [%1-0x48], rdi + mov [%1-0x50], rsi + mov [%1-0x58], rbp + mov [%1-0x60], rsp + mov [%1-0x68], rbx + mov [%1-0x70], rdx + mov [%1-0x78], rcx + mov [%1-0x80], rax +%endmacro + +%macro PUSH_GPR 0 + SAVE_GPR rsp + sub rsp, 0x80 +%endmacro + +%macro RESTORE_GPR 1 + mov r15, [%1-0x08] + mov r14, [%1-0x10] + mov r13, [%1-0x18] + mov r12, [%1-0x20] + mov r11, [%1-0x28] + mov r10, [%1-0x30] + mov r9, [%1-0x38] + mov r8, [%1-0x40] + mov rdi, [%1-0x48] + mov rsi, [%1-0x50] + mov rbp, [%1-0x58] + ;mov rsp, [%1-0x60] + mov rbx, [%1-0x68] + mov rdx, [%1-0x70] + mov rcx, [%1-0x78] + mov rax, [%1-0x80] +%endmacro + +%macro POP_GPR 0 + add rsp, 0x80 + RESTORE_GPR rsp +%endmacro + +%macro EXPORT 1 +[global %1] +%1: +%endmacro diff --git a/Kernel/arch/amd64/crate.rs b/Kernel/arch/amd64/crate.rs index 0072f2f004ce185cecfdbaf292fb61ca1b6c5eb9..6b04c872dd271d6c5c713fb510bd601cab765c97 100644 --- a/Kernel/arch/amd64/crate.rs +++ b/Kernel/arch/amd64/crate.rs @@ -1,59 +1,23 @@ +// "Tifflin" Kernel +// - By John Hodge (thePowersGang) // -// -// +// arch/amd64/crate.rs +// - AMD64/x86_64 architecture support #![feature(asm)] #![crate_type="lib"] #![no_std] extern crate core; +extern crate common; -use core::str::StrSlice; +pub use log::{puts, puth}; pub mod float; pub mod interrupts; pub mod memory; +pub mod boot; -pub fn puts(text: &str) -{ - for c in text.bytes() - { - putc(c); - } -} -pub fn puth(val: uint) -{ - puts("0"); - let nibbles = { - let mut v = 1u; - while (val >> v*4) > 0 && v < 64/4 { v += 1 } - v - }; - //let nibbles = 16u; - puts("x"); - for i in ::core::iter::range(0, nibbles) - { - let nibble : u8 = ((val >> (nibbles-i-1)*4) & 15) as u8; - putc( if nibble <= 9 { '0' as u8 + nibble } else { 'a' as u8 + nibble-10 } ); - } -} -fn putc(c: u8) -{ - unsafe - { - while (inb(0x3F8+5) & 0x20) == 0 - { - } - outb(0x3F8, c as u8); - } -} - -unsafe fn inb(port: u16) -> u8 { - let ret : u8; - asm!("inb %dx, %al" : "={ax}"(ret) : "{dx}"(port)); - return ret; -} -unsafe fn outb(port: u16, val: u8) { - asm!("outb %al, %dx" : : "{dx}"(port), "{al}"(val)); -} +mod log; +mod x86_io; // vim: ft=rust diff --git a/Kernel/arch/amd64/link.ld b/Kernel/arch/amd64/link.ld index 4d7faaf9822d46160880850ed2aceb156679b1ba..a145ed9dfe92359ac8e7deb703f43b9470878e58 100644 --- a/Kernel/arch/amd64/link.ld +++ b/Kernel/arch/amd64/link.ld @@ -17,8 +17,6 @@ SECTIONS { *(.initdata) } - low_GDT = GDT - _kernel_base; - low_GDTPtr = GDTPtr - _kernel_base; low_InitialPML4 = InitialPML4 - _kernel_base; . += _kernel_base; diff --git a/Kernel/arch/amd64/log.rs b/Kernel/arch/amd64/log.rs new file mode 100644 index 0000000000000000000000000000000000000000..0546b80e490f1c3133265080b5f1e4044601a572 --- /dev/null +++ b/Kernel/arch/amd64/log.rs @@ -0,0 +1,44 @@ +// "Tifflin" Kernel +// - By John Hodge (thePowersGang) +// +// arch/amd64/log.rs +// - RS232 logging output + +use core::str::StrSlice; + +pub fn puts(text: &str) +{ + for c in text.bytes() + { + putc(c); + } +} +pub fn puth(val: uint) +{ + puts("0"); + let nibbles = { + let mut v = 1u; + while (val >> v*4) > 0 && v < 64/4 { v += 1 } + v + }; + //let nibbles = 16u; + puts("x"); + for i in ::core::iter::range(0, nibbles) + { + let nibble : u8 = ((val >> (nibbles-i-1)*4) & 15) as u8; + putc( if nibble <= 9 { '0' as u8 + nibble } else { 'a' as u8 + nibble-10 } ); + } +} +fn putc(c: u8) +{ + unsafe + { + while (::x86_io::inb(0x3F8+5) & 0x20) == 0 + { + } + ::x86_io::outb(0x3F8, c as u8); + } +} + +// vim: ft=rust + diff --git a/Kernel/arch/amd64/memory.rs b/Kernel/arch/amd64/memory.rs index 3c4d14c5de641e050fcd618bc63767fd421abd5c..ed3080fe5e3ef813bfc33928d5bb12c43ea27cd4 100644 --- a/Kernel/arch/amd64/memory.rs +++ b/Kernel/arch/amd64/memory.rs @@ -10,6 +10,8 @@ pub mod addresses pub static modules_end: uint = 0xFFFFA000_00000000; pub static physinfo_start: uint = 0xFFFFA000_00000000; pub static physinfo_end: uint = 0xFFFFB000_00000000; // TODO: Needed? + pub static ident_start: uint = 0xFFFFFFFF_80000000; + pub static ident_end: uint = 0xFFFFFFFF_80200000; } // vim: ft=rust diff --git a/Kernel/arch/amd64/start.asm b/Kernel/arch/amd64/start.asm index 96b16027a9751f2de487f0ce9dd547b6560df13d..22068b8eae1a68968cec3c1b4e1943ec795f31e4 100644 --- a/Kernel/arch/amd64/start.asm +++ b/Kernel/arch/amd64/start.asm @@ -1,85 +1,45 @@ ; ; ; -%define MAX_CPUS 1 -%define KSTACK_BASE 0xFFFFA00000000000 -%define INITIAL_KSTACK_SIZE 16 -%define KERNEL_BASE 0xFFFFFFFF80000000 -%macro SAVE_GPR 1 - mov [%1-0x08], r15 - mov [%1-0x10], r14 - mov [%1-0x18], r13 - mov [%1-0x20], r12 - mov [%1-0x28], r11 - mov [%1-0x30], r10 - mov [%1-0x38], r9 - mov [%1-0x40], r8 - mov [%1-0x48], rdi - mov [%1-0x50], rsi - mov [%1-0x58], rbp - mov [%1-0x60], rsp - mov [%1-0x68], rbx - mov [%1-0x70], rdx - mov [%1-0x78], rcx - mov [%1-0x80], rax -%endmacro - -%macro PUSH_GPR 0 - SAVE_GPR rsp - sub rsp, 0x80 -%endmacro - -%macro RESTORE_GPR 1 - mov r15, [%1-0x08] - mov r14, [%1-0x10] - mov r13, [%1-0x18] - mov r12, [%1-0x20] - mov r11, [%1-0x28] - mov r10, [%1-0x30] - mov r9, [%1-0x38] - mov r8, [%1-0x40] - mov rdi, [%1-0x48] - mov rsi, [%1-0x50] - mov rbp, [%1-0x58] - ;mov rsp, [%1-0x60] - mov rbx, [%1-0x68] - mov rdx, [%1-0x70] - mov rcx, [%1-0x78] - mov rax, [%1-0x80] -%endmacro - -%macro POP_GPR 0 - add rsp, 0x80 - RESTORE_GPR rsp -%endmacro - -%macro EXPORT 1 -[global %1] -%1: -%endmacro +%include "arch/amd64/common.inc.asm" ; WTF Nasm [extern low_InitialPML4] -[extern low_GDTPtr] -[extern low_GDT] [section .multiboot] [global mboot] mboot: MULTIBOOT_PAGE_ALIGN equ 1<<0 MULTIBOOT_MEMORY_INFO equ 1<<1 + MULTIBOOT_REQVIDMODE equ 1<<2 MULTIBOOT_HEADER_MAGIC equ 0x1BADB002 - MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO + MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_REQVIDMODE MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) ; This is the GRUB Multiboot header. A boot signature dd MULTIBOOT_HEADER_MAGIC dd MULTIBOOT_HEADER_FLAGS dd MULTIBOOT_CHECKSUM + dd mboot + ; a.out kludge + dd 0 ; load_addr + dd 0 ; load_end_addr + dd 0 ; bss_end_addr + dd 0 ; entry_addr + ; Video mode + dd 0 ; Mode type (0: LFB) + dd 0 ; Width (no preference) + dd 0 ; Height (no preference) + dd 32 ; Depth (32-bit preferred) [section .inittext] [BITS 32] [global start] start: + ; 0. Save multboot state + mov [s_multiboot_signature - KERNEL_BASE], eax + or ebx, 0x80000000 + mov [s_multiboot_pointer - KERNEL_BASE], ebx + ; 1. Ensure that CPU is compatible mov eax, 0x80000000 cpuid @@ -131,7 +91,7 @@ start: mov eax, cr0 or eax, 0x80010000 ; PG & WP mov cr0, eax - lgdt [low_GDTPtr] + lgdt [GDTPtr - KERNEL_BASE] jmp 0x08:start64 ;; ;; @@ -448,9 +408,12 @@ InitialKernelStack: times 0x1000*(INITIAL_KSTACK_SIZE-1) db 0 ; 8 Pages [section .data] -[global GDT] -[global GDTPtr] -GDT: +EXPORT s_multiboot_pointer + dd 0 + dd 0xFFFFFFFF +EXPORT s_multiboot_signature + dd 0 +EXPORT GDT dd 0, 0 dd 0x00000000, 0x00209A00 ; 0x08: 64-bit Code dd 0x00000000, 0x00009200 ; 0x10: 64-bit Data @@ -461,22 +424,19 @@ GDT: times MAX_CPUS dd 0, 0x00008900, 0, 0 ; 0x38+16*n: TSS 0 GDTPtr: dw $-GDT-1 - dd low_GDT + dd GDT - KERNEL_BASE dd 0 GDTPtr2: dw GDTPtr-GDT-1 dq GDT -[global IDT] -[global IDTPtr] -IDT: +EXPORT IDT ; 64-bit Interrupt Gate, CS = 0x8, IST0 (Disabled) times 256 dd 0x00080000, 0x00000E00, 0, 0 IDTPtr: dw 256*16-1 dq IDT -[global TID0TLS] -TID0TLS: +EXPORT TID0TLS times 0x70 db 0 dq KSTACK_BASE+0x1000 diff --git a/Kernel/arch/amd64/x86_io.rs b/Kernel/arch/amd64/x86_io.rs new file mode 100644 index 0000000000000000000000000000000000000000..54470c318ea10924511c0c9f80fc68433bc85734 --- /dev/null +++ b/Kernel/arch/amd64/x86_io.rs @@ -0,0 +1,17 @@ +// "Tifflin" Kernel +// - By John Hodge (thePowersGang) +// +// arch/amd64/x86_io.rs +// - Support for x86's IO bus + +pub unsafe fn inb(port: u16) -> u8 { + let ret : u8; + asm!("inb %dx, %al" : "={ax}"(ret) : "{dx}"(port)); + return ret; +} +pub unsafe fn outb(port: u16, val: u8) { + asm!("outb %al, %dx" : : "{dx}"(port), "{al}"(val)); +} + +// vim: ft=rust + diff --git a/Kernel/common/lib.rs b/Kernel/common/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..07bab15720e4d6f98ac0773e2782786b16f0dc13 --- /dev/null +++ b/Kernel/common/lib.rs @@ -0,0 +1,26 @@ +#![crate_type="lib"] +#![no_std] + +pub mod archapi +{ + +pub enum VideoFormat +{ + VideoX8R8G8B8, + VideoB8G8R8X8, + VideoR8G8B8, + VideoB8G8R8, + VideoR5G6B5, +} + +pub struct VideoMode +{ + pub width: u16, + pub height: u16, + pub fmt: VideoFormat, +} + +} + +// vim: ft=rust +