Commit so I can work on my school chromebook
This commit is contained in:
parent
402586b860
commit
9901560753
19 changed files with 273 additions and 125 deletions
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "kernel"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0-devel-0000"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
|
@ -14,7 +14,7 @@ codegen-units = 1
|
|||
panic = "abort"
|
||||
|
||||
[[bin]]
|
||||
name = "entrypoint"
|
||||
name = "entrypoint_x86"
|
||||
path = "src/internal/arch/x86_asmp/entry.rs"
|
||||
|
||||
[[bin]]
|
||||
|
|
15
kernel/build
15
kernel/build
|
@ -8,8 +8,15 @@
|
|||
|
||||
. "$DIR/functions"
|
||||
|
||||
rm config.aphro.tmp
|
||||
cp config.aphro config.aphro.tmp
|
||||
# -f makes it so it won't error out if the file doesn't exist
|
||||
rm -f config.aphro.tmp
|
||||
envsubst < "config.aphro" > "config.aphro.tmp"
|
||||
|
||||
# see above about -f
|
||||
rm -f targets.tmp
|
||||
envsubst < "targets" > "targets.tmp"
|
||||
|
||||
export $(grep -Ev '^#' targets.tmp | xargs)
|
||||
|
||||
export $(grep -Ev '^#' config.aphro.tmp | xargs)
|
||||
|
||||
|
@ -26,7 +33,9 @@
|
|||
|
||||
cd ../kernel
|
||||
|
||||
cargo build --target i686-unknown-none.json --release -Zbuild-std --bin entrypoint
|
||||
for target in $TARGETS; do
|
||||
cargo build --target "$target" --release -Zbuild-std --bin entrypoint
|
||||
done
|
||||
# build the kernel's entrypoint
|
||||
|
||||
cp target/i686-unknown-none/release/entrypoint kernel.flat
|
||||
|
|
BIN
kernel/grub_template/EFI/BOOT/BOOTIA32.EFI
Normal file
BIN
kernel/grub_template/EFI/BOOT/BOOTIA32.EFI
Normal file
Binary file not shown.
BIN
kernel/grub_template/EFI/BOOT/BOOTX64.EFI
Normal file
BIN
kernel/grub_template/EFI/BOOT/BOOTX64.EFI
Normal file
Binary file not shown.
|
@ -1,5 +1,10 @@
|
|||
set timeout=15
|
||||
set timeout=5
|
||||
set default=0
|
||||
set gfxpayload=keep
|
||||
insmod all_video
|
||||
insmod gfxterm
|
||||
insmod efi_uga
|
||||
insmod efi_gop
|
||||
|
||||
menuentry "Aphrodite" --class aphrodite --class kernel --class os $menuentry_id_option 'aphrodite-basic-%{VERSION}' {
|
||||
echo 'Loading Aphrodite aphrodite-%{VERSION} ...'
|
||||
|
|
|
@ -7,6 +7,6 @@ use crate::output::*;
|
|||
|
||||
/// The real entrypoint to the kernel. `internel/arch/*/entry.rs` files eventually call this.
|
||||
#[allow(non_snake_case)]
|
||||
pub fn _entry(display: Option<&dyn crate::TextDisplay>, BI: &crate::boot::BootInfo) -> ! {
|
||||
pub fn _entry(display: Option<&dyn crate::display::TextDisplay>, BI: &crate::boot::BootInfo) -> ! {
|
||||
loop {}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
//! Arch-specific code.
|
||||
//! Arch-specific code. This module re-exports all code from the architecture being used.
|
||||
|
||||
mod x86_asmp;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! Stuff for writing and reading to the EGA text buffer.
|
||||
#![cfg(any(target_arch = "x86"))]
|
||||
|
||||
use crate::Color;
|
||||
use crate::display::Color;
|
||||
|
||||
/// Information about the framebuffer.
|
||||
#[derive(Clone, Copy)]
|
||||
|
@ -25,7 +25,7 @@ pub const ERR_INVALID_X: i16 = -1;
|
|||
/// Returned when the provided position is invalid in the Y direction.
|
||||
pub const ERR_INVALID_Y: i16 = -2;
|
||||
|
||||
impl crate::TextDisplay for FramebufferInfo {
|
||||
impl crate::display::TextDisplay for FramebufferInfo {
|
||||
/// Writes a character to the screen.
|
||||
fn write_char(&self, mut pos: (u32, u32), char: u8, color: Color) -> Result<(), crate::Error<'static>> {
|
||||
let mut clr = color.0;
|
||||
|
|
|
@ -49,7 +49,7 @@ pub trait MemoryMap: _MemoryMap + core::any::Any {}
|
|||
#[derive(Clone)]
|
||||
pub struct BootInfo<'a> {
|
||||
/// The commandline of the kernel.
|
||||
/// See https://github.com/AverseABFun/aphrodite/wiki/Plan#bootloader (remember to update link later!) for the format.
|
||||
/// See <https://aphrodite-os.github.io/book/command-line.html> for the format.
|
||||
pub cmdline: Option<&'static str>,
|
||||
|
||||
/// The memory map provided by the bootloader. If None, the kernel will attempt to generate it.
|
||||
|
@ -59,5 +59,5 @@ pub struct BootInfo<'a> {
|
|||
pub bootloader_name: Option<&'static str>,
|
||||
|
||||
/// Provides a way to display text.
|
||||
pub output: Option<&'a dyn crate::TextDisplay>,
|
||||
pub output: Option<&'a dyn crate::display::TextDisplay>,
|
||||
}
|
70
kernel/src/include/display.rs
Normal file
70
kernel/src/include/display.rs
Normal file
|
@ -0,0 +1,70 @@
|
|||
//! Types, constants and traits for displaying text. Mostly implemented in arch/.
|
||||
|
||||
/// A type used for color in the functions of [TextDisplay].
|
||||
///
|
||||
/// Type alias for (u8, bool). Boolean argument is whether to
|
||||
/// change the value(i.e. for [COLOR_BLACK] and [COLOR_DEFAULT]).
|
||||
pub type Color = (u8, bool);
|
||||
|
||||
/// Black-on-black.
|
||||
pub const COLOR_BLACK: Color = (0, true);
|
||||
|
||||
/// Should be whatever color commonly used for status messages.
|
||||
/// Generally should be white-on-black. Value is one.
|
||||
pub const COLOR_DEFAULT: Color = (1, true);
|
||||
|
||||
/// Some form of display that can be written to with text.
|
||||
pub trait TextDisplay {
|
||||
/// Writes a single character to the specified position.
|
||||
fn write_char(&self, pos: (u32, u32), char: u8, color: Color) -> Result<(), crate::Error<'static>>;
|
||||
/// Gets the size of the screen.
|
||||
fn get_size(&self) -> (u32, u32);
|
||||
}
|
||||
|
||||
impl dyn TextDisplay + '_ {
|
||||
/// Clears the screen.
|
||||
pub fn clear_screen(&self, color: Color) {
|
||||
let (width, height) = self.get_size();
|
||||
for x in 0..width {
|
||||
for y in 0..height {
|
||||
self.write_char((x, y), b' ', color).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Writes a &str to the screen.
|
||||
pub fn write_str(&self, pos: (u32, u32), str: &str, color: Color) -> Result<(u32, u32), crate::Error<'static>> {
|
||||
let (width, _) = self.get_size();
|
||||
let (mut x, mut y) = pos;
|
||||
for char in str.as_bytes() {
|
||||
self.write_char((x, y), *char, color)?;
|
||||
if *char == 0 {
|
||||
continue
|
||||
}
|
||||
x += 1;
|
||||
while x>width {
|
||||
x -= width;
|
||||
y += 1;
|
||||
}
|
||||
}
|
||||
Ok((x, y))
|
||||
}
|
||||
|
||||
/// Writes a &\[u8] to the screen.
|
||||
pub fn write_bytes(&self, pos: (u32, u32), str: &[u8], color: Color) -> Result<(u32, u32), crate::Error<'static>> {
|
||||
let (width, _) = self.get_size();
|
||||
let (mut x, mut y) = pos;
|
||||
for char in str {
|
||||
self.write_char((x, y), *char, color)?;
|
||||
if *char == 0 {
|
||||
continue
|
||||
}
|
||||
x += 1;
|
||||
while x>width {
|
||||
x -= width;
|
||||
y += 1;
|
||||
}
|
||||
}
|
||||
Ok((x, y))
|
||||
}
|
||||
}
|
BIN
kernel/src/include/iso01-12x22.psfu
Normal file
BIN
kernel/src/include/iso01-12x22.psfu
Normal file
Binary file not shown.
|
@ -1,4 +1,4 @@
|
|||
//! This provides syscalls(for userspace programs) and types(for userspace and kernelspace programs) for the Aphrodite kernel.
|
||||
//! This provides raw methods for internal kernel usage for the Aphrodite kernel. See aphrodite_user for userspace.
|
||||
#![no_std]
|
||||
#![warn(missing_docs)]
|
||||
#![feature(ptr_metadata)]
|
||||
|
@ -13,10 +13,14 @@ pub mod _entry;
|
|||
mod traits;
|
||||
pub mod output;
|
||||
pub mod boot;
|
||||
pub mod psfont;
|
||||
pub mod display;
|
||||
|
||||
#[allow(unused_imports)] // if there are no constants, then it gives a warning
|
||||
pub use constants::*;
|
||||
|
||||
pub use errors::*;
|
||||
pub use util::*;
|
||||
|
||||
#[allow(unused_imports)] // if there are no traits, then it gives a warning
|
||||
pub use traits::*;
|
|
@ -1,6 +1,6 @@
|
|||
//! Definitions of structs for multiboot2 information. Mostly used during pre-userspace.
|
||||
|
||||
/// 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 [crate::boot::BootInfo] struct has been initalized, but it still can be used.
|
||||
#[repr(C)]
|
||||
#[derive(Clone)]
|
||||
pub struct Tag {
|
||||
|
@ -21,7 +21,7 @@ pub struct RootTag {
|
|||
reserved: u32,
|
||||
}
|
||||
|
||||
/// A Multiboot2 module. See https://github.com/AverseABFun/aphrodite/wiki/Plan/#Bootloader-modules (remember to update link later!).
|
||||
/// A Multiboot2 module. See <https://aphrodite-os.github.io/book/bootloader-modules.html>.
|
||||
#[derive(Clone)]
|
||||
pub struct Module {
|
||||
/// A pointer to the start of the module
|
||||
|
@ -29,7 +29,7 @@ pub struct Module {
|
|||
/// A pointer to the end of the module
|
||||
pub mod_end: *const u8,
|
||||
/// 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://aphrodite-os.github.io/book/bootloader-modules.html>.
|
||||
pub mod_str: &'static core::ffi::CStr
|
||||
}
|
||||
|
||||
|
@ -193,7 +193,7 @@ pub struct FramebufferInfo {
|
|||
/// Boot info collected from provided [Tag]s.
|
||||
#[derive(Clone)]
|
||||
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"
|
||||
/// and mem_upper the amount of "upper memory".
|
||||
pub mem_lower: Option<u32>,
|
||||
|
@ -206,7 +206,7 @@ pub struct Multiboot2BootInfo {
|
|||
|
||||
/// We're provided with a C-style UTF-8(null-terminated UTF-8) string. This should contain the original pointer provided by
|
||||
/// the bootloader.
|
||||
/// See https://github.com/AverseABFun/aphrodite/wiki/Plan#bootloader (remember to update link later!) for the format.
|
||||
/// See <https://aphrodite-os.github.io/book/command-line.html> for the format.
|
||||
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.
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
//! Architecture-independent output functions.
|
||||
|
||||
use paste::paste;
|
||||
use crate::COLOR_DEFAULT;
|
||||
use crate::display::COLOR_DEFAULT;
|
||||
|
||||
static mut OUTPUT_TERM_POSITION: (u32, u32) = (0, 0);
|
||||
|
||||
macro_rules! message_funcs {
|
||||
($func_name:ident, $prefix:literal, $level:ident) => {
|
||||
paste! {
|
||||
/// Outputs a $func_name message &str to the terminal.
|
||||
pub fn [< t $func_name s >](s: &str, info: &dyn crate::TextDisplay) -> Result<(), crate::Error<'static>> {
|
||||
/// Outputs a message &str to the terminal.
|
||||
pub fn [< t $func_name s >](s: &str, info: &dyn crate::display::TextDisplay) -> Result<(), crate::Error<'static>> {
|
||||
unsafe {
|
||||
if cfg!($level = "false") {
|
||||
return Ok(());
|
||||
|
@ -19,8 +19,8 @@ macro_rules! message_funcs {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
/// Outputs a $func_name message &str and a newline to the terminal.
|
||||
pub fn [< t $func_name sln >](s: &str, info: &dyn crate::TextDisplay) -> Result<(), crate::Error<'static>> {
|
||||
/// Outputs a message &str and a newline to the terminal.
|
||||
pub fn [< t $func_name sln >](s: &str, info: &dyn crate::display::TextDisplay) -> Result<(), crate::Error<'static>> {
|
||||
unsafe {
|
||||
if cfg!($level = "false") {
|
||||
return Ok(());
|
||||
|
@ -33,8 +33,8 @@ macro_rules! message_funcs {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Outputs a $func_name message &\[u8] to the terminal.
|
||||
pub fn [< t $func_name b >](s: &[u8], info: &dyn crate::TextDisplay) -> Result<(), crate::Error<'static>> {
|
||||
/// Outputs a message &\[u8] to the terminal.
|
||||
pub fn [< t $func_name b >](s: &[u8], info: &dyn crate::display::TextDisplay) -> Result<(), crate::Error<'static>> {
|
||||
unsafe {
|
||||
if cfg!($level = "false") {
|
||||
return Ok(());
|
||||
|
@ -44,8 +44,8 @@ macro_rules! message_funcs {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
/// Outputs a $func_name message &\[u8] and a newline to the terminal.
|
||||
pub fn [< t $func_name bln >](s: &[u8], info: &dyn crate::TextDisplay) -> Result<(), crate::Error<'static>> {
|
||||
/// Outputs a message &\[u8] and a newline to the terminal.
|
||||
pub fn [< t $func_name bln >](s: &[u8], info: &dyn crate::display::TextDisplay) -> Result<(), crate::Error<'static>> {
|
||||
unsafe {
|
||||
if cfg!($level = "false") {
|
||||
return Ok(());
|
||||
|
@ -58,8 +58,8 @@ macro_rules! message_funcs {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Outputs a(n) $func_name message u8 to the terminal.
|
||||
pub fn [< t $func_name u >](s: u8, info: &dyn crate::TextDisplay) -> Result<(), crate::Error<'static>> {
|
||||
/// Outputs a message u8 to the terminal.
|
||||
pub fn [< t $func_name u >](s: u8, info: &dyn crate::display::TextDisplay) -> Result<(), crate::Error<'static>> {
|
||||
let (width, _) = info.get_size();
|
||||
unsafe {
|
||||
if cfg!($level = "false") {
|
||||
|
@ -78,8 +78,8 @@ macro_rules! message_funcs {
|
|||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
/// Outputs a $func_name message &str to the terminal without a prefix.
|
||||
pub fn [< t $func_name snp >](s: &str, info: &dyn crate::TextDisplay) -> Result<(), crate::Error<'static>> {
|
||||
/// Outputs a message &str to the terminal without a prefix.
|
||||
pub fn [< t $func_name snp >](s: &str, info: &dyn crate::display::TextDisplay) -> Result<(), crate::Error<'static>> {
|
||||
unsafe {
|
||||
if cfg!($level = "false") {
|
||||
return Ok(());
|
||||
|
@ -88,8 +88,8 @@ macro_rules! message_funcs {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
/// Outputs a $func_name message &str and a newline to the terminal without a prefix.
|
||||
pub fn [< t $func_name snpln >](s: &str, info: &dyn crate::TextDisplay) -> Result<(), crate::Error<'static>> {
|
||||
/// Outputs a message &str and a newline to the terminal without a prefix.
|
||||
pub fn [< t $func_name snpln >](s: &str, info: &dyn crate::display::TextDisplay) -> Result<(), crate::Error<'static>> {
|
||||
unsafe {
|
||||
if cfg!($level = "false") {
|
||||
return Ok(());
|
||||
|
@ -101,8 +101,8 @@ macro_rules! message_funcs {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Outputs a $func_name message &\[u8] to the terminal without a prefix.
|
||||
pub fn [< t $func_name bnp >](s: &[u8], info: &dyn crate::TextDisplay) -> Result<(), crate::Error<'static>> {
|
||||
/// Outputs a message &\[u8] to the terminal without a prefix.
|
||||
pub fn [< t $func_name bnp >](s: &[u8], info: &dyn crate::display::TextDisplay) -> Result<(), crate::Error<'static>> {
|
||||
unsafe {
|
||||
if cfg!($level = "false") {
|
||||
return Ok(());
|
||||
|
@ -111,8 +111,8 @@ macro_rules! message_funcs {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
/// Outputs a $func_name message &\[u8] and a newline to the terminal without a prefix.
|
||||
pub fn [< t $func_name bnpln >](s: &[u8], info: &dyn crate::TextDisplay) -> Result<(), crate::Error<'static>> {
|
||||
/// Outputs a message &\[u8] and a newline to the terminal without a prefix.
|
||||
pub fn [< t $func_name bnpln >](s: &[u8], info: &dyn crate::display::TextDisplay) -> Result<(), crate::Error<'static>> {
|
||||
unsafe {
|
||||
if cfg!($level = "false") {
|
||||
return Ok(());
|
||||
|
@ -124,8 +124,8 @@ macro_rules! message_funcs {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Outputs a(n) $func_name message u8 to the terminal without a prefix.
|
||||
pub fn [< t $func_name unp >](s: u8, info: &dyn crate::TextDisplay) -> Result<(), crate::Error<'static>> {
|
||||
/// Outputs a message u8 to the terminal without a prefix.
|
||||
pub fn [< t $func_name unp >](s: u8, info: &dyn crate::display::TextDisplay) -> Result<(), crate::Error<'static>> {
|
||||
let (width, _) = info.get_size();
|
||||
unsafe {
|
||||
if cfg!($level = "false") {
|
||||
|
|
118
kernel/src/include/psfont.rs
Normal file
118
kernel/src/include/psfont.rs
Normal file
|
@ -0,0 +1,118 @@
|
|||
//! PC Screen Font stuff
|
||||
|
||||
/// The font selected to be the "main" font. I selected Linux's
|
||||
/// ISO01-12x22 font.
|
||||
pub const FONT1: &[u8; 12107] = include_bytes!("iso01-12x22.psfu");
|
||||
|
||||
/// One glyph for [RawPCScreenFont].
|
||||
pub type RawGlyph = [u8];
|
||||
|
||||
/// PC Screen Font magic number.
|
||||
pub const PSF_MAGIC: u32 = 0x864ab572;
|
||||
|
||||
/// A PC Screen font.
|
||||
pub struct RawPCScreenFont {
|
||||
/// The magic number. Should be 0x864ab572.
|
||||
pub magic: u32,
|
||||
/// The version. Should be 0.
|
||||
pub version: u32,
|
||||
/// The size of the header/offset of bitmaps.
|
||||
pub header_size: u32,
|
||||
/// Flags. 0 if there's no unicode table.
|
||||
pub flags: u32,
|
||||
/// The number of glyphs.
|
||||
pub num_glyphs: u32,
|
||||
/// The number of bytes per glyph.
|
||||
pub bytes_per_glyph: u32,
|
||||
/// The height of each glyph.
|
||||
pub height: u32,
|
||||
/// The width of each glyph.
|
||||
pub width: u32,
|
||||
/// The glyphs.
|
||||
pub glyphs: *const RawGlyph,
|
||||
}
|
||||
|
||||
/// The glyph type for [PCScreenFont].
|
||||
pub struct Glyph {
|
||||
/// The size of this glyph.
|
||||
pub len: u32,
|
||||
/// The height of this glyph.
|
||||
pub height: u32,
|
||||
/// The width of this glyph.
|
||||
pub width: u32,
|
||||
/// The raw glyph data.
|
||||
pub data: &'static [u8],
|
||||
}
|
||||
|
||||
/// A more useful form of [RawPCScreenFont].
|
||||
pub struct PCScreenFont {
|
||||
/// The version. Should be 0.
|
||||
pub version: u32,
|
||||
/// Flags. 0 if there's no unicode table.
|
||||
pub flags: u32,
|
||||
/// The height of each glyph.
|
||||
pub height: u32,
|
||||
/// The width of each glyph.
|
||||
pub width: u32,
|
||||
/// The glyphs.
|
||||
pub glyphs: &'static [Glyph],
|
||||
/// The unicode translation table.
|
||||
pub unitable: &'static [&'static [u8]]
|
||||
}
|
||||
|
||||
/// Error code returned when the PSF has an invalid magic number.
|
||||
pub const ERR_INVALID_MAGIC: i16 = -1;
|
||||
|
||||
/// Parses a PC Screen Font into a [RawPCScreenFont].
|
||||
pub fn parse_raw_pc_screen_font(data: &[u8]) -> Result<RawPCScreenFont, crate::Error> {
|
||||
let out = RawPCScreenFont {
|
||||
magic: u32::from_le_bytes(data[0..3].try_into().unwrap()),
|
||||
version: u32::from_le_bytes(data[4..7].try_into().unwrap()),
|
||||
header_size: u32::from_le_bytes(data[8..11].try_into().unwrap()),
|
||||
flags: u32::from_le_bytes(data[12..15].try_into().unwrap()),
|
||||
num_glyphs: u32::from_le_bytes(data[16..20].try_into().unwrap()),
|
||||
bytes_per_glyph: u32::from_le_bytes(data[20..23].try_into().unwrap()),
|
||||
height: u32::from_le_bytes(data[24..27].try_into().unwrap()),
|
||||
width: u32::from_le_bytes(data[28..31].try_into().unwrap()),
|
||||
glyphs: &data[32..] as *const [u8]
|
||||
};
|
||||
if out.magic != PSF_MAGIC {
|
||||
return Err(crate::Error::new("Invalid magic", ERR_INVALID_MAGIC));
|
||||
}
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
/// Parses a PC Screen Font into a [PCScreenFont].
|
||||
pub fn parse_pc_screen_font(data: RawPCScreenFont) -> Result<PCScreenFont, crate::Error<'static>> {
|
||||
unsafe {
|
||||
let unitable: &[&[u8]] = &[];
|
||||
let unistr = data.glyphs.byte_add(data.bytes_per_glyph as usize*data.num_glyphs as usize);
|
||||
|
||||
let mut i = 0usize;
|
||||
let mut f = 0usize;
|
||||
loop {
|
||||
let g = i+f;
|
||||
if i>=data.num_glyphs as usize {
|
||||
break;
|
||||
}
|
||||
let char = (*unistr)[g];
|
||||
if char == 0xFF {
|
||||
i += 1;
|
||||
f = 0;
|
||||
continue;
|
||||
}
|
||||
unitable[g];
|
||||
f += 1;
|
||||
}
|
||||
|
||||
let out = PCScreenFont {
|
||||
version: data.version,
|
||||
flags: data.flags,
|
||||
height: data.height,
|
||||
width: data.width,
|
||||
glyphs: &*(core::ptr::from_raw_parts(data.glyphs as *const Glyph, data.num_glyphs as usize) as *const [Glyph]),
|
||||
unitable
|
||||
};
|
||||
Ok(out)
|
||||
}
|
||||
}
|
|
@ -1,70 +1 @@
|
|||
//! General traits. Mostly implemented in arch/*.
|
||||
|
||||
/// A type used for color in the functions of [TextDisplay].
|
||||
///
|
||||
/// Type alias for (u8, bool). Boolean argument is whether to
|
||||
/// change the value(i.e. for [COLOR_BLACK] and [COLOR_DEFAULT]).
|
||||
pub type Color = (u8, bool);
|
||||
|
||||
/// Black-on-black.
|
||||
pub const COLOR_BLACK: Color = (0, true);
|
||||
|
||||
/// Should be whatever color commonly used for status messages.
|
||||
/// Generally should be white-on-black. Value is one.
|
||||
pub const COLOR_DEFAULT: Color = (1, true);
|
||||
|
||||
/// Some form of display that can be written too with text.
|
||||
pub trait TextDisplay {
|
||||
/// Writes a single character to the specified position.
|
||||
fn write_char(&self, pos: (u32, u32), char: u8, color: Color) -> Result<(), crate::Error<'static>>;
|
||||
/// Gets the size of the screen.
|
||||
fn get_size(&self) -> (u32, u32);
|
||||
}
|
||||
|
||||
impl dyn TextDisplay + '_ {
|
||||
/// Clears the screen.
|
||||
pub fn clear_screen(&self, color: Color) {
|
||||
let (width, height) = self.get_size();
|
||||
for x in 0..width {
|
||||
for y in 0..height {
|
||||
self.write_char((x, y), b' ', color).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Writes a &str to the screen.
|
||||
pub fn write_str(&self, pos: (u32, u32), str: &str, color: Color) -> Result<(u32, u32), crate::Error<'static>> {
|
||||
let (width, _) = self.get_size();
|
||||
let (mut x, mut y) = pos;
|
||||
for char in str.as_bytes() {
|
||||
self.write_char((x, y), *char, color)?;
|
||||
if *char == 0 {
|
||||
continue
|
||||
}
|
||||
x += 1;
|
||||
while x>width {
|
||||
x -= width;
|
||||
y += 1;
|
||||
}
|
||||
}
|
||||
Ok((x, y))
|
||||
}
|
||||
|
||||
/// Writes a &\[u8] to the screen.
|
||||
pub fn write_bytes(&self, pos: (u32, u32), str: &[u8], color: Color) -> Result<(u32, u32), crate::Error<'static>> {
|
||||
let (width, _) = self.get_size();
|
||||
let (mut x, mut y) = pos;
|
||||
for char in str {
|
||||
self.write_char((x, y), *char, color)?;
|
||||
if *char == 0 {
|
||||
continue
|
||||
}
|
||||
x += 1;
|
||||
while x>width {
|
||||
x -= width;
|
||||
y += 1;
|
||||
}
|
||||
}
|
||||
Ok((x, y))
|
||||
}
|
||||
}
|
|
@ -17,11 +17,15 @@ use aphrodite::output::*;
|
|||
#[cfg(not(CONFIG_DISABLE_MULTIBOOT2_SUPPORT))]
|
||||
#[unsafe(link_section = ".multiboot2")]
|
||||
#[unsafe(no_mangle)]
|
||||
static MULTIBOOT2_HEADER: [u8; 29] = [
|
||||
0xd6, 0x50, 0x52, 0xe8, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x00, 0x00, 0x00, 0x12, 0xaf, 0xad, 0x17,
|
||||
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
|
||||
0xe9, 0x55, 0x00, 0x00, 0x00
|
||||
static MULTIBOOT2_HEADER: [u8; 24] = [
|
||||
0xd6, 0x50, 0x52, 0xe8, // Magic number
|
||||
0x00, 0x00, 0x00, 0x00, // Architecture
|
||||
0x18, 0x00, 0x00, 0x00, // Size
|
||||
0x12, 0xaf, 0xad, 0x17, // Checksum
|
||||
|
||||
0x00, 0x00, // End tag
|
||||
0x00, 0x00, // Flags
|
||||
0x08, 0x00, 0x00, 0x00, // Size
|
||||
];
|
||||
|
||||
// The root tag, provided directly from the multiboot2 bootloader.
|
||||
|
@ -52,15 +56,7 @@ static mut MAGIC: u32 = 0xFFFFFFFF;
|
|||
#[unsafe(link_section = ".start")]
|
||||
#[unsafe(no_mangle)]
|
||||
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
|
||||
|
||||
// Aphrodite bootloaders pass values in eax and ebx, however rust doesn't know that it can't overwrite those.
|
||||
// we force using ebx and eax as the output of an empty assembly block to let it know.
|
||||
asm!(
|
||||
|
@ -69,6 +65,13 @@ extern "C" fn _start() -> ! {
|
|||
options(nomem, nostack, preserves_flags, pure)
|
||||
);
|
||||
}
|
||||
#[allow(non_snake_case)]
|
||||
let mut BI: BootInfo<'static> = BootInfo {
|
||||
cmdline: None,
|
||||
memory_map: None,
|
||||
bootloader_name: None,
|
||||
output: None,
|
||||
};
|
||||
unsafe {
|
||||
match MAGIC {
|
||||
#[cfg(not(CONFIG_DISABLE_MULTIBOOT2_SUPPORT))]
|
||||
|
@ -227,7 +230,7 @@ extern "C" fn _start() -> ! {
|
|||
}
|
||||
}
|
||||
sdebugsln("Bootloader information has been successfully loaded");
|
||||
soutputu(b'\n');
|
||||
sdebugunp(b'\n');
|
||||
unsafe {
|
||||
if BI.output.clone().is_some() {
|
||||
let framebuffer_info = FBI;
|
||||
|
@ -248,9 +251,9 @@ extern "C" fn _start() -> ! {
|
|||
let ega: &dyn aphrodite::TextDisplay = &framebuffer_info;
|
||||
framebuffer_info.disable_cursor();
|
||||
ega.clear_screen(aphrodite::COLOR_DEFAULT);
|
||||
tdebugsln("Testing EGA Text framebuffer...", ega).unwrap();
|
||||
tdebugsln("Testing EGA Text framebuffer...", ega).unwrap();
|
||||
tdebugsln("Testing EGA Text framebuffer...", ega).unwrap();
|
||||
toutputsln("Testing EGA Text framebuffer...", ega).unwrap();
|
||||
toutputsln("Testing EGA Text framebuffer...", ega).unwrap();
|
||||
toutputsln("Testing EGA Text framebuffer...", ega).unwrap();
|
||||
|
||||
aphrodite::_entry::_entry(Some(ega), &BI);
|
||||
}
|
||||
|
|
4
kernel/targets
Normal file
4
kernel/targets
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Targets used for documentation.
|
||||
x86=$KERNEL_DIR/i686-unknown-none.json
|
||||
|
||||
TARGETS=$x86
|
4
kernel/targets.tmp
Normal file
4
kernel/targets.tmp
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Targets used for documentation.
|
||||
x86=/i686-unknown-none.json
|
||||
|
||||
TARGETS=
|
Loading…
Add table
Reference in a new issue