arch-independent stuff working, x86 renamed to x86_asmp because missile
This commit is contained in:
parent
86a85b8b0d
commit
e39bd7bf6e
16 changed files with 158 additions and 154 deletions
|
@ -15,7 +15,7 @@ panic = "abort"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "entrypoint"
|
name = "entrypoint"
|
||||||
path = "src/internal/arch/x86/entry.rs"
|
path = "src/internal/arch/x86_asmp/entry.rs"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "main"
|
name = "main"
|
||||||
|
|
Binary file not shown.
|
@ -1,8 +1,8 @@
|
||||||
set timeout=15
|
set timeout=15
|
||||||
set default=0
|
set default=0
|
||||||
|
|
||||||
menuentry "Aphrodite" --class aphrodite --class kernel --class os $menuentry_id_option 'aphrodite-basic-devel-6a2a677-out-of-tree' {
|
menuentry "Aphrodite" --class aphrodite --class kernel --class os $menuentry_id_option 'aphrodite-basic-devel-86a85b8-out-of-tree' {
|
||||||
echo 'Loading Aphrodite aphrodite-devel-6a2a677-out-of-tree ...'
|
echo 'Loading Aphrodite aphrodite-devel-86a85b8-out-of-tree ...'
|
||||||
multiboot2 /boot/aphrodite.kernel
|
multiboot2 /boot/aphrodite.kernel
|
||||||
boot
|
boot
|
||||||
}
|
}
|
Binary file not shown.
|
@ -1,5 +1,5 @@
|
||||||
//! Arch-specific code.
|
//! Arch-specific code.
|
||||||
|
|
||||||
mod x86;
|
mod x86_asmp;
|
||||||
|
|
||||||
pub use x86::*;
|
pub use x86_asmp::*;
|
|
@ -9,6 +9,8 @@
|
||||||
pub enum MemoryType {
|
pub enum MemoryType {
|
||||||
/// Free RAM with no use.
|
/// Free RAM with no use.
|
||||||
Free,
|
Free,
|
||||||
|
/// RAM used by the kernel
|
||||||
|
Kernel,
|
||||||
/// Reserved by something.
|
/// Reserved by something.
|
||||||
Reserved,
|
Reserved,
|
||||||
/// Reserved by something on the hardware.
|
/// Reserved by something on the hardware.
|
||||||
|
@ -19,7 +21,9 @@ pub enum MemoryType {
|
||||||
Unknown,
|
Unknown,
|
||||||
/// Hardware-specific use. The boolean argument states
|
/// Hardware-specific use. The boolean argument states
|
||||||
/// whether memory can be allocated in this region.
|
/// whether memory can be allocated in this region.
|
||||||
HardwareSpecific(u32, bool)
|
HardwareSpecific(u32, bool),
|
||||||
|
/// Flash/semi-permanent memory. Generally used in embedded systems.
|
||||||
|
Permanent
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A single memory mapping for [MemoryMap].
|
/// A single memory mapping for [MemoryMap].
|
||||||
|
@ -27,17 +31,20 @@ pub trait MemoryMapping {
|
||||||
/// Returns the type of the memory.
|
/// Returns the type of the memory.
|
||||||
fn get_type(&self) -> MemoryType;
|
fn get_type(&self) -> MemoryType;
|
||||||
/// Returns the beginning of the memory.
|
/// Returns the beginning of the memory.
|
||||||
fn get_start(&self) -> usize;
|
fn get_start(&self) -> u64;
|
||||||
/// Returns the length of the memory.
|
/// Returns the length of the memory.
|
||||||
fn get_length(&self) -> usize;
|
fn get_length(&self) -> u64;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Memory mapping.
|
/// Memory mapping.
|
||||||
pub trait MemoryMap<'a>: core::iter::Iterator<Item = &'a dyn MemoryMapping> + core::ops::Index<usize, Output = &'a dyn MemoryMapping> {
|
pub trait _MemoryMap: core::iter::Iterator<Item = &'static dyn MemoryMapping> + core::ops::Index<usize, Output = dyn MemoryMapping> {
|
||||||
/// Returns the number of [MemoryMapping]s in the MemoryMap. This is total, not remainder.
|
/// Returns the number of [MemoryMapping]s in the MemoryMap. This is total, not remainder.
|
||||||
fn len(&self) -> usize;
|
fn len(&self) -> usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Memory mapping. Used so that we can downcast.
|
||||||
|
pub trait MemoryMap: _MemoryMap + core::any::Any {}
|
||||||
|
|
||||||
/// Bootloader-independent information.
|
/// Bootloader-independent information.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct BootInfo<'a> {
|
pub struct BootInfo<'a> {
|
||||||
|
@ -46,7 +53,7 @@ pub struct BootInfo<'a> {
|
||||||
pub cmdline: Option<&'static str>,
|
pub cmdline: Option<&'static str>,
|
||||||
|
|
||||||
/// The memory map provided by the bootloader. If None, the kernel will attempt to generate it.
|
/// The memory map provided by the bootloader. If None, the kernel will attempt to generate it.
|
||||||
pub memory_map: Option<&'a dyn MemoryMap<'a>>,
|
pub memory_map: Option<&'a dyn MemoryMap>,
|
||||||
|
|
||||||
/// The name of the bootloader(for example, "GRUB 2.12").
|
/// The name of the bootloader(for example, "GRUB 2.12").
|
||||||
pub bootloader_name: Option<&'static str>,
|
pub bootloader_name: Option<&'static str>,
|
||||||
|
|
|
@ -1,38 +1,5 @@
|
||||||
//! Definitions of structs for multiboot2 information. Mostly used during pre-userspace.
|
//! Definitions of structs for multiboot2 information. Mostly used during pre-userspace.
|
||||||
|
|
||||||
/// Used when a CString is passed. Move into separate file?
|
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
pub struct CString {
|
|
||||||
/// The raw pointer to the string.
|
|
||||||
pub ptr: *const u8,
|
|
||||||
/// The length of the string, excluding the null byte(\0) at the end.
|
|
||||||
pub len: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl core::ops::Index<usize> for CString {
|
|
||||||
type Output = u8;
|
|
||||||
fn index(&self, index: usize) -> &Self::Output {
|
|
||||||
unsafe {
|
|
||||||
if index>self.len {
|
|
||||||
panic!("index into CString too large");
|
|
||||||
}
|
|
||||||
let mut ptr = self.ptr as usize;
|
|
||||||
ptr += index * size_of::<u8>();
|
|
||||||
let ptr = ptr as *const u8;
|
|
||||||
&*ptr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Into<&'static str> for CString {
|
|
||||||
fn into(self) -> &'static str {
|
|
||||||
unsafe {
|
|
||||||
let val: *const str = core::ptr::from_raw_parts(self.ptr, self.len);
|
|
||||||
return &*val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Used for Multiboot2 tags. This shouldn't be used after a [BootInfo] struct has been initalized, but it still can be used.
|
/// Used for Multiboot2 tags. This shouldn't be used after a [BootInfo] struct has been initalized, but it still can be used.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -63,7 +30,7 @@ pub struct Module {
|
||||||
pub mod_end: *const u8,
|
pub mod_end: *const u8,
|
||||||
/// A string that should be in the format `module_name (command line arguments)`.
|
/// A string that should be in the format `module_name (command line arguments)`.
|
||||||
/// See https://github.com/AverseABFun/aphrodite/wiki/Plan/#Bootloader-modules (remember to update link later!).
|
/// See https://github.com/AverseABFun/aphrodite/wiki/Plan/#Bootloader-modules (remember to update link later!).
|
||||||
pub mod_str: CString
|
pub mod_str: &'static core::ffi::CStr
|
||||||
}
|
}
|
||||||
|
|
||||||
/// One memory section provided by a Multiboot2 bootloader.
|
/// One memory section provided by a Multiboot2 bootloader.
|
||||||
|
@ -81,6 +48,24 @@ pub struct MemorySection {
|
||||||
reserved: u32,
|
reserved: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl crate::boot::MemoryMapping for MemorySection {
|
||||||
|
fn get_type(&self) -> crate::boot::MemoryType {
|
||||||
|
match self.mem_type {
|
||||||
|
1 => crate::boot::MemoryType::Free,
|
||||||
|
2 => crate::boot::MemoryType::HardwareReserved,
|
||||||
|
3 => crate::boot::MemoryType::HardwareSpecific(3, false),
|
||||||
|
5 => crate::boot::MemoryType::Faulty,
|
||||||
|
_ => crate::boot::MemoryType::Reserved
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn get_start(&self) -> u64 {
|
||||||
|
self.base_addr
|
||||||
|
}
|
||||||
|
fn get_length(&self) -> u64 {
|
||||||
|
self.length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The raw memory map provided by a Multiboot2 bootloader. This is interpreted
|
/// The raw memory map provided by a Multiboot2 bootloader. This is interpreted
|
||||||
/// into a [MemoryMap].
|
/// into a [MemoryMap].
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -106,6 +91,36 @@ pub struct MemoryMap {
|
||||||
pub entry_size: u32,
|
pub entry_size: u32,
|
||||||
/// All sections.
|
/// All sections.
|
||||||
pub sections: &'static [MemorySection],
|
pub sections: &'static [MemorySection],
|
||||||
|
|
||||||
|
/// Iterator's index.
|
||||||
|
pub idx: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl crate::boot::MemoryMap for MemoryMap {}
|
||||||
|
|
||||||
|
impl crate::boot::_MemoryMap for MemoryMap {
|
||||||
|
fn len(&self) -> usize {
|
||||||
|
self.sections.len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl core::ops::Index<usize> for MemoryMap {
|
||||||
|
type Output = dyn crate::boot::MemoryMapping;
|
||||||
|
|
||||||
|
fn index(&self, index: usize) -> &Self::Output {
|
||||||
|
&self.sections[index] as &'static dyn crate::boot::MemoryMapping
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl core::iter::Iterator for MemoryMap {
|
||||||
|
type Item = &'static dyn crate::boot::MemoryMapping;
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.idx += 1;
|
||||||
|
if self.sections.len()<=self.idx-1 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Some(&self.sections[self.idx-1])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A color descriptor for [ColorInfo::Palette].
|
/// A color descriptor for [ColorInfo::Palette].
|
||||||
|
@ -177,7 +192,7 @@ pub struct FramebufferInfo {
|
||||||
|
|
||||||
/// Boot info collected from provided [Tag]s.
|
/// Boot info collected from provided [Tag]s.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct BootInfo {
|
pub struct Multiboot2BootInfo {
|
||||||
/// See https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html#Basic-memory-information.
|
/// See https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html#Basic-memory-information.
|
||||||
/// Tl;dr: mem_lower indicates the amount of "lower memory"
|
/// Tl;dr: mem_lower indicates the amount of "lower memory"
|
||||||
/// and mem_upper the amount of "upper memory".
|
/// and mem_upper the amount of "upper memory".
|
||||||
|
@ -192,7 +207,7 @@ pub struct BootInfo {
|
||||||
/// We're provided with a C-style UTF-8(null-terminated UTF-8) string. This should contain the original pointer provided by
|
/// We're provided with a C-style UTF-8(null-terminated UTF-8) string. This should contain the original pointer provided by
|
||||||
/// the bootloader.
|
/// the bootloader.
|
||||||
/// See https://github.com/AverseABFun/aphrodite/wiki/Plan#bootloader (remember to update link later!) for the format.
|
/// See https://github.com/AverseABFun/aphrodite/wiki/Plan#bootloader (remember to update link later!) for the format.
|
||||||
pub cmdline: Option<CString>,
|
pub cmdline: Option<&'static core::ffi::CStr>,
|
||||||
|
|
||||||
// Due to the way modules work, it's not easily possible to make a struct that contains all the modules.
|
// Due to the way modules work, it's not easily possible to make a struct that contains all the modules.
|
||||||
// Therefore, they are loaded on the fly.
|
// Therefore, they are loaded on the fly.
|
||||||
|
@ -205,7 +220,7 @@ pub struct BootInfo {
|
||||||
|
|
||||||
/// The name of the bootloader(for example, "GRUB 2.12"). C-style UTF-8(null-terminated UTF-8) string.
|
/// The name of the bootloader(for example, "GRUB 2.12"). C-style UTF-8(null-terminated UTF-8) string.
|
||||||
/// This should contain the original pointer provided by the bootloader.
|
/// This should contain the original pointer provided by the bootloader.
|
||||||
pub bootloader_name: Option<CString>,
|
pub bootloader_name: Option<&'static core::ffi::CStr>,
|
||||||
|
|
||||||
// APM table is ignored as APM has been superseded by ACPI. If your system doesn't support ACPI, good luck.
|
// APM table is ignored as APM has been superseded by ACPI. If your system doesn't support ACPI, good luck.
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@ pub type Color = u8;
|
||||||
/// Black-on-black.
|
/// Black-on-black.
|
||||||
pub const COLOR_BLACK: Color = 0;
|
pub const COLOR_BLACK: Color = 0;
|
||||||
|
|
||||||
/// Should be whatever colors commonly used for status messages.
|
/// Should be whatever color commonly used for status messages.
|
||||||
/// Generally should be white-on-black.
|
/// Generally should be white-on-black. Value is one.
|
||||||
pub const COLOR_DEFAULT: Color = 1;
|
pub const COLOR_DEFAULT: Color = 1;
|
||||||
|
|
||||||
/// Some form of display that can be written too with text.
|
/// Some form of display that can be written too with text.
|
||||||
|
|
|
@ -8,10 +8,12 @@
|
||||||
#![feature(cfg_match)]
|
#![feature(cfg_match)]
|
||||||
|
|
||||||
use core::{arch::asm, ffi::CStr, panic::PanicInfo};
|
use core::{arch::asm, ffi::CStr, panic::PanicInfo};
|
||||||
use aphrodite::multiboot2::{BootInfo, CString, ColorInfo, FramebufferInfo, MemoryMap, MemorySection, PaletteColorDescriptor, RawMemoryMap, RootTag, Tag};
|
use aphrodite::boot::BootInfo;
|
||||||
use aphrodite::arch::x86::output::*;
|
use aphrodite::multiboot2::{FramebufferInfo, MemoryMap, MemorySection, RawMemoryMap, RootTag, Tag};
|
||||||
use aphrodite::arch::x86::egatext as egatext;
|
use aphrodite::arch::output::*;
|
||||||
|
use aphrodite::arch::egatext as egatext;
|
||||||
use egatext::*;
|
use egatext::*;
|
||||||
|
use aphrodite::output::*;
|
||||||
|
|
||||||
#[cfg(not(CONFIG_DISABLE_MULTIBOOT2_SUPPORT))]
|
#[cfg(not(CONFIG_DISABLE_MULTIBOOT2_SUPPORT))]
|
||||||
#[unsafe(link_section = ".multiboot2")]
|
#[unsafe(link_section = ".multiboot2")]
|
||||||
|
@ -25,26 +27,39 @@ static MULTIBOOT2_HEADER: [u8; 29] = [
|
||||||
|
|
||||||
// The root tag, provided directly from the multiboot2 bootloader.
|
// The root tag, provided directly from the multiboot2 bootloader.
|
||||||
static mut RT: *const RootTag = core::ptr::null();
|
static mut RT: *const RootTag = core::ptr::null();
|
||||||
// The boot info struct, created from all of the tags.
|
|
||||||
static mut BI: BootInfo = BootInfo {
|
|
||||||
mem_lower: None,
|
|
||||||
mem_upper: None,
|
|
||||||
cmdline: None,
|
|
||||||
memory_map: None,
|
|
||||||
bootloader_name: None,
|
|
||||||
framebuffer_info: None,
|
|
||||||
color_info: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
// The raw pointer to bootloader-specific data.
|
// The raw pointer to bootloader-specific data.
|
||||||
static mut O: *const u8 = core::ptr::null();
|
static mut O: *const u8 = core::ptr::null();
|
||||||
|
|
||||||
|
static mut MM: MemoryMap = MemoryMap {
|
||||||
|
entry_size: 0,
|
||||||
|
version: 0,
|
||||||
|
sections: &[],
|
||||||
|
idx: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static mut FBI: aphrodite::arch::egatext::FramebufferInfo = aphrodite::arch::egatext::FramebufferInfo {
|
||||||
|
address: 0,
|
||||||
|
pitch: 0,
|
||||||
|
width: 0,
|
||||||
|
height: 0,
|
||||||
|
bpp: 0,
|
||||||
|
change_cursor: false,
|
||||||
|
};
|
||||||
|
|
||||||
// The magic number in eax. 0x36D76289 for multiboot2.
|
// The magic number in eax. 0x36D76289 for multiboot2.
|
||||||
static mut MAGIC: u32 = 0xFFFFFFFF;
|
static mut MAGIC: u32 = 0xFFFFFFFF;
|
||||||
|
|
||||||
#[unsafe(link_section = ".start")]
|
#[unsafe(link_section = ".start")]
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
extern "C" fn _start() -> ! {
|
extern "C" fn _start() -> ! {
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
let mut BI: BootInfo<'static> = BootInfo {
|
||||||
|
cmdline: None,
|
||||||
|
memory_map: None,
|
||||||
|
bootloader_name: None,
|
||||||
|
output: None,
|
||||||
|
};
|
||||||
unsafe { // Copy values provided by the bootloader out
|
unsafe { // Copy values provided by the bootloader out
|
||||||
|
|
||||||
// Aphrodite bootloaders pass values in eax and ebx, however rust doesn't know that it can't overwrite those.
|
// Aphrodite bootloaders pass values in eax and ebx, however rust doesn't know that it can't overwrite those.
|
||||||
|
@ -103,10 +118,6 @@ extern "C" fn _start() -> ! {
|
||||||
if current_tag.tag_len != 16 { // Unexpected size, something is probably up
|
if current_tag.tag_len != 16 { // Unexpected size, something is probably up
|
||||||
panic!("size of basic memory information tag != 16");
|
panic!("size of basic memory information tag != 16");
|
||||||
}
|
}
|
||||||
|
|
||||||
BI.mem_lower = Some(*((ptr + 8) as *const u32));
|
|
||||||
BI.mem_upper = Some(*((ptr + 12) as *const u32));
|
|
||||||
// The end result of the above is adding an offset to a pointer and retrieving the value at that pointer
|
|
||||||
},
|
},
|
||||||
5 => { // BIOS boot device, ignore
|
5 => { // BIOS boot device, ignore
|
||||||
if current_tag.tag_len != 20 { // Unexpected size, something is probably up
|
if current_tag.tag_len != 20 { // Unexpected size, something is probably up
|
||||||
|
@ -120,13 +131,7 @@ extern "C" fn _start() -> ! {
|
||||||
let cstring = CStr::from_ptr((ptr + 8) as *const i8);
|
let cstring = CStr::from_ptr((ptr + 8) as *const i8);
|
||||||
// creates a &core::ffi::CStr from the start of the command line...
|
// creates a &core::ffi::CStr from the start of the command line...
|
||||||
|
|
||||||
let cstring = CString {
|
BI.cmdline = Some(cstring.to_str().unwrap());
|
||||||
ptr: cstring.as_ptr() as *const u8,
|
|
||||||
len: cstring.to_bytes().len()
|
|
||||||
};
|
|
||||||
// ...which can then be converted to a aphrodite::multiboot2::CString...
|
|
||||||
|
|
||||||
BI.cmdline = Some(cstring);
|
|
||||||
// ...before the BootInfo's commandline is set.
|
// ...before the BootInfo's commandline is set.
|
||||||
},
|
},
|
||||||
6 => { // Memory map tag
|
6 => { // Memory map tag
|
||||||
|
@ -139,11 +144,13 @@ extern "C" fn _start() -> ! {
|
||||||
// The end result of the above is creating a *const RawMemoryMap that has the same address as current_tag
|
// The end result of the above is creating a *const RawMemoryMap that has the same address as current_tag
|
||||||
// and has all of the [aphrodite::multiboot2::MemorySection]s for the memory map
|
// and has all of the [aphrodite::multiboot2::MemorySection]s for the memory map
|
||||||
|
|
||||||
BI.memory_map = Some(MemoryMap {
|
MM = MemoryMap {
|
||||||
version: (*rawmemorymap).entry_version,
|
version: (*rawmemorymap).entry_version,
|
||||||
entry_size: (*rawmemorymap).entry_size,
|
entry_size: (*rawmemorymap).entry_size,
|
||||||
sections: &*core::ptr::from_raw_parts((&(*rawmemorymap).sections[0]) as &MemorySection, (*rawmemorymap).sections.len()),
|
sections: &*core::ptr::from_raw_parts((&(*rawmemorymap).sections[0]) as &MemorySection, (*rawmemorymap).sections.len()),
|
||||||
});
|
idx: 0
|
||||||
|
};
|
||||||
|
BI.memory_map = Some(&MM);
|
||||||
},
|
},
|
||||||
2 => { // Bootloader name
|
2 => { // Bootloader name
|
||||||
if current_tag.tag_len < 8 { // Unexpected size, something is probably up
|
if current_tag.tag_len < 8 { // Unexpected size, something is probably up
|
||||||
|
@ -152,13 +159,7 @@ extern "C" fn _start() -> ! {
|
||||||
let cstring = CStr::from_ptr((ptr + 8) as *const i8);
|
let cstring = CStr::from_ptr((ptr + 8) as *const i8);
|
||||||
// creates a &core::ffi::CStr from the start of the bootloader name...
|
// creates a &core::ffi::CStr from the start of the bootloader name...
|
||||||
|
|
||||||
let cstring = CString {
|
BI.bootloader_name = Some(cstring.to_str().unwrap());
|
||||||
ptr: cstring.as_ptr() as *const u8,
|
|
||||||
len: cstring.to_bytes().len()
|
|
||||||
};
|
|
||||||
// ...which can then be converted to a aphrodite::multiboot2::CString...
|
|
||||||
|
|
||||||
BI.bootloader_name = Some(cstring);
|
|
||||||
// ...before the BootInfo's bootloader_name is set.
|
// ...before the BootInfo's bootloader_name is set.
|
||||||
},
|
},
|
||||||
8 => { // Framebuffer info
|
8 => { // Framebuffer info
|
||||||
|
@ -166,33 +167,30 @@ extern "C" fn _start() -> ! {
|
||||||
panic!("size of framebuffer info tag < 32");
|
panic!("size of framebuffer info tag < 32");
|
||||||
}
|
}
|
||||||
let framebufferinfo: *const FramebufferInfo = (ptr as usize + size_of::<Tag>()) as *const FramebufferInfo;
|
let framebufferinfo: *const FramebufferInfo = (ptr as usize + size_of::<Tag>()) as *const FramebufferInfo;
|
||||||
let colorinfo: ColorInfo;
|
|
||||||
match (*framebufferinfo).fb_type {
|
match (*framebufferinfo).fb_type {
|
||||||
0 => { // Indexed
|
0 => { // Indexed
|
||||||
colorinfo = ColorInfo::Palette {
|
panic!("Indexed color is unimplemented");
|
||||||
num_colors: *((ptr + 32) as *const u32),
|
|
||||||
palette: (ptr + 36) as *const PaletteColorDescriptor
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
1 => { // RGB
|
1 => { // RGB
|
||||||
colorinfo = ColorInfo::RGBColor {
|
panic!("RGB color is unimplemented");
|
||||||
red_field_position: *((ptr + 32) as *const u8),
|
|
||||||
red_mask_size: *((ptr + 33) as *const u8),
|
|
||||||
green_field_position: *((ptr + 34) as *const u8),
|
|
||||||
green_mask_size: *((ptr + 35) as *const u8),
|
|
||||||
blue_field_position: *((ptr + 36) as *const u8),
|
|
||||||
blue_mask_size: *((ptr + 37) as *const u8)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
2 => { // EGA Text
|
2 => { // EGA Text
|
||||||
colorinfo = ColorInfo::EGAText;
|
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
panic!("unknown color info type")
|
panic!("unknown color info type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BI.framebuffer_info = Some((*framebufferinfo).clone());
|
let framebuffer_info = (*framebufferinfo).clone();
|
||||||
BI.color_info = Some(colorinfo);
|
|
||||||
|
FBI = egatext::FramebufferInfo {
|
||||||
|
address: framebuffer_info.address,
|
||||||
|
pitch: framebuffer_info.pitch,
|
||||||
|
width: framebuffer_info.width,
|
||||||
|
height: framebuffer_info.height,
|
||||||
|
bpp: framebuffer_info.bpp,
|
||||||
|
change_cursor: false,
|
||||||
|
};
|
||||||
|
BI.output = Some(&FBI)
|
||||||
},
|
},
|
||||||
_ => { // Unknown/unimplemented tag type, ignore
|
_ => { // Unknown/unimplemented tag type, ignore
|
||||||
swarnings("Unknown tag type ");
|
swarnings("Unknown tag type ");
|
||||||
|
@ -232,9 +230,8 @@ extern "C" fn _start() -> ! {
|
||||||
sdebugsln("Bootloader information has been successfully loaded");
|
sdebugsln("Bootloader information has been successfully loaded");
|
||||||
soutputu(b'\n');
|
soutputu(b'\n');
|
||||||
unsafe {
|
unsafe {
|
||||||
if BI.framebuffer_info.clone().is_some() {
|
if BI.output.clone().is_some() {
|
||||||
let framebuffer_info = BI.framebuffer_info.clone().unwrap();
|
let framebuffer_info = FBI;
|
||||||
let color_info = BI.color_info.clone().unwrap();
|
|
||||||
|
|
||||||
sdebugs("Framebuffer width: ");
|
sdebugs("Framebuffer width: ");
|
||||||
sdebugbnpln(&aphrodite::u32_as_u8_slice(framebuffer_info.width));
|
sdebugbnpln(&aphrodite::u32_as_u8_slice(framebuffer_info.width));
|
||||||
|
@ -246,68 +243,43 @@ extern "C" fn _start() -> ! {
|
||||||
sdebugbnpln(&aphrodite::usize_as_u8_slice(framebuffer_info.address as usize));
|
sdebugbnpln(&aphrodite::usize_as_u8_slice(framebuffer_info.address as usize));
|
||||||
sdebugs("Framebuffer bpp: ");
|
sdebugs("Framebuffer bpp: ");
|
||||||
sdebugbnpln(&aphrodite::u8_as_u8_slice(framebuffer_info.bpp));
|
sdebugbnpln(&aphrodite::u8_as_u8_slice(framebuffer_info.bpp));
|
||||||
sdebugs("Framebuffer type: ");
|
|
||||||
sdebugbnp(&aphrodite::u8_as_u8_slice(framebuffer_info.fb_type));
|
|
||||||
|
|
||||||
match framebuffer_info.fb_type {
|
|
||||||
0 => { // Indexed
|
|
||||||
sdebugsnpln("(Indexed)");
|
|
||||||
let ColorInfo::Palette{num_colors, palette: _} = color_info else { unreachable!() };
|
|
||||||
sdebugs("Number of palette colors: ");
|
|
||||||
sdebugbnpln(&aphrodite::u32_as_u8_slice(num_colors));
|
|
||||||
|
|
||||||
sfatalsln("Halting CPU; Indexed color unimplemented");
|
|
||||||
asm!("hlt", options(noreturn));
|
|
||||||
},
|
|
||||||
1 => { // RGB
|
|
||||||
sdebugsnpln("(RGB)");
|
|
||||||
|
|
||||||
sfatalsln("Halting CPU; RGB color unimplemented");
|
|
||||||
asm!("hlt", options(noreturn));
|
|
||||||
},
|
|
||||||
2 => { // EGA Text
|
|
||||||
sdebugsnpln("(EGA Text)");
|
|
||||||
sdebugsln("Beginning output to screen...");
|
sdebugsln("Beginning output to screen...");
|
||||||
|
|
||||||
let ega = egatext::FramebufferInfo {
|
let ega: &dyn aphrodite::TextDisplay = &framebuffer_info;
|
||||||
address: framebuffer_info.address,
|
framebuffer_info.disable_cursor();
|
||||||
pitch: framebuffer_info.pitch,
|
|
||||||
width: framebuffer_info.width,
|
|
||||||
height: framebuffer_info.height,
|
|
||||||
bpp: framebuffer_info.bpp,
|
|
||||||
change_cursor: true,
|
|
||||||
};
|
|
||||||
ega.clear_screen(WHITE_ON_BLACK);
|
ega.clear_screen(WHITE_ON_BLACK);
|
||||||
ega.enable_cursor(14, 15);
|
|
||||||
ega.set_cursor_location((0, 0));
|
|
||||||
tdebugsln("Testing EGA Text framebuffer...", ega).unwrap();
|
tdebugsln("Testing EGA Text framebuffer...", ega).unwrap();
|
||||||
tdebugsln("Testing EGA Text framebuffer...", ega).unwrap();
|
tdebugsln("Testing EGA Text framebuffer...", ega).unwrap();
|
||||||
tdebugsln("Testing EGA Text framebuffer...", ega).unwrap();
|
tdebugsln("Testing EGA Text framebuffer...", ega).unwrap();
|
||||||
|
|
||||||
aphrodite::_entry::_entry(Some(ega), &BI);
|
aphrodite::_entry::_entry(Some(ega), &BI);
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
unreachable!();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
|
||||||
aphrodite::_entry::_entry(None, &BI);
|
aphrodite::_entry::_entry(None, &BI);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[unsafe(link_section = ".panic")]
|
#[unsafe(link_section = ".panic")]
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
#[cfg(not(CONFIG_HALT_ON_PANIC = "false"))]
|
#[cfg(not(CONFIG_HALT_ON_PANIC = "false"))]
|
||||||
fn halt_on_panic(info: &PanicInfo) -> ! {
|
fn halt_on_panic(info: &PanicInfo) -> ! {
|
||||||
|
if info.location().is_some() {
|
||||||
|
sfatals("Panic at ");
|
||||||
|
sfatalsnp(info.location().unwrap().file());
|
||||||
|
sfatalsnp(":");
|
||||||
|
sfatalbnp(&aphrodite::u32_as_u8_slice(info.location().unwrap().line()));
|
||||||
|
sfatalsnp(":");
|
||||||
|
sfatalbnp(&aphrodite::u32_as_u8_slice(info.location().unwrap().column()));
|
||||||
|
sfatalsnp(": ");
|
||||||
|
} else {
|
||||||
|
sfatals("Panic: ");
|
||||||
|
}
|
||||||
let message = info.message().as_str().unwrap_or("");
|
let message = info.message().as_str().unwrap_or("");
|
||||||
if message != "" {
|
if message != "" {
|
||||||
sfatals(message);
|
sfatalsnpln(message);
|
||||||
aphrodite::arch::x86::ports::outb(aphrodite::arch::x86::DEBUG_PORT, b'\n');
|
|
||||||
}
|
}
|
||||||
aphrodite::arch::x86::interrupts::disable_interrupts();
|
aphrodite::arch::interrupts::disable_interrupts();
|
||||||
unsafe {
|
unsafe {
|
||||||
asm!("hlt", options(noreturn));
|
asm!("hlt", options(noreturn));
|
||||||
}
|
}
|
||||||
|
@ -317,11 +289,21 @@ fn halt_on_panic(info: &PanicInfo) -> ! {
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
#[cfg(all(CONFIG_SPIN_ON_PANIC = "true", CONFIG_PREUSER_HALT_ON_PANIC = "false"))]
|
#[cfg(all(CONFIG_SPIN_ON_PANIC = "true", CONFIG_PREUSER_HALT_ON_PANIC = "false"))]
|
||||||
fn spin_on_panic(info: &PanicInfo) -> ! {
|
fn spin_on_panic(info: &PanicInfo) -> ! {
|
||||||
|
if info.location().is_some() {
|
||||||
|
sfatals("Panic at ");
|
||||||
|
sfatalsnp(info.location().unwrap().file());
|
||||||
|
sfatalsnp(":");
|
||||||
|
sfatalbnp(&aphrodite::u32_as_u8_slice(info.location().unwrap().line()));
|
||||||
|
sfatalsnp(":");
|
||||||
|
sfatalbnp(&aphrodite::u32_as_u8_slice(info.location().unwrap().column()));
|
||||||
|
sfatalsnp(": ");
|
||||||
|
} else {
|
||||||
|
sfatals("Panic: ");
|
||||||
|
}
|
||||||
let message = info.message().as_str().unwrap_or("");
|
let message = info.message().as_str().unwrap_or("");
|
||||||
if message != "" {
|
if message != "" {
|
||||||
sfatals(message);
|
sfatalsnpln(message);
|
||||||
aphrodite::arch::x86::ports::outb(aphrodite::arch::x86::DEBUG_PORT, b'\n');
|
|
||||||
}
|
}
|
||||||
aphrodite::arch::x86::interrupts::disable_interrupts();
|
aphrodite::arch::interrupts::disable_interrupts();
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue