- added a new libary libm containing procedural macros for the kernel.

these should be used to include external files and resources in the kernel binary
  at compile time.
  - libm currently supports loading psf-1 formatted fonts
- added two fonts that are included in the binary at compile time
- refactored libk to make the crate structure more organised and maintainable in future.
  new structure:
    - drivers   (hardware interaction)
    - resources (consts and statics included either manually or via macros)
    - std       (standard functions for higher level interaction with the os, for example creating windows)
- added geometry.rs
  - provides the Vec2<T> struct for use with dimensions, coordinates etc.
- added window.rs
  - provides the Window struct for rendering the state of an application to the screen
- added application.rs
  - provides the Application trait for custom programs to implement in order to run
This commit is contained in:
2025-02-24 03:26:49 +00:00
parent 7ff33659fe
commit d9bbdff08c
36 changed files with 421 additions and 39 deletions
+1
View File
@@ -19,3 +19,4 @@ futures-util = { version = "0.3.31", default-features = false, features = [
"alloc",
] }
linked_list_allocator = "0.10.5"
libm = { path = "../libm" }
Binary file not shown.
Binary file not shown.
@@ -2,11 +2,9 @@ use core::fmt;
use spin::{Lazy, Mutex};
use x86_64::instructions::interrupts;
pub use super::framebuffer::screensize_px;
use super::framebuffer::{Colour, FRAMEBUFFER_WRITER};
use super::framebuffer::{colour::Colour, display::FRAMEBUFFER_WRITER};
mod font;
use font::FONT;
use crate::resources::font::{FONT_CP850_8X16, Font};
static FONT_WIDTH: u32 = 8;
static FONT_HEIGHT: u32 = 16;
@@ -19,6 +17,7 @@ pub fn screensize_chars() -> (u32, u32) {
}
pub struct Writer {
font: &'static Font,
/// Measured in chars not pixels.
screen_width: u32,
/// Measured in chars not pixels.
@@ -48,6 +47,7 @@ impl Writer {
panic!("Framebuffer writer not initialized.");
},
|writer| Self {
font: &FONT_CP850_8X16,
screen_width: writer.width() / 8,
screen_height: writer.height() / 16,
text_line: 0,
@@ -60,6 +60,10 @@ impl Writer {
)
}
pub fn set_font(&mut self, font: &'static Font) {
self.font = font;
}
pub fn write_glyph(&mut self, c: u16) {
if c as u8 == b'\n' {
self.newline();
@@ -67,7 +71,7 @@ impl Writer {
}
// get the character data from the font array. -- each byte is a row of pixels
let data: &[u8] = &FONT[c as usize * 16..(c as usize + 1) * 16];
let data: &[u8] = &self.font.0[c as usize];
if let Some(writer) = FRAMEBUFFER_WRITER.lock().as_mut() {
for (row, line) in data.iter().enumerate().take(16) {
@@ -190,7 +194,7 @@ macro_rules! println_log {
#[macro_export]
macro_rules! print_log {
($($arg:tt)*) => ($crate::io::ascii::_print_log(format_args!($($arg)*)));
($($arg:tt)*) => ($crate::_print_log(format_args!($($arg)*)));
}
#[macro_export]
@@ -201,7 +205,7 @@ macro_rules! println {
#[macro_export]
macro_rules! print {
($($arg:tt)*) => ($crate::io::ascii::_print(format_args!($($arg)*)));
($($arg:tt)*) => ($crate::_print(format_args!($($arg)*)));
}
#[macro_export]
@@ -4,9 +4,7 @@ use limine::request::FramebufferRequest;
#[unsafe(link_section = ".requests")]
static FRAMEBUFFER_REQUEST: FramebufferRequest = FramebufferRequest::new();
mod colour;
pub use colour::Colour;
use super::colour::Colour;
use core::panic;
use limine::framebuffer::Framebuffer;
+2
View File
@@ -0,0 +1,2 @@
pub mod colour;
pub mod display;
@@ -5,14 +5,14 @@ use core::{
use spin::{Lazy, Mutex};
#[macro_export]
macro_rules! serial_println {
() => ($crate::serial_print!("\n"));
($($arg:tt)*) => ($crate::io::serial_print!("{}\n", format_args!($($arg)*)));
macro_rules! serial_print {
($($arg:tt)*) => ($crate::_serial_write(format_args!($($arg)*)));
}
#[macro_export]
macro_rules! serial_print {
($($arg:tt)*) => ($crate::io::serial::_serial_write(format_args!($($arg)*)));
macro_rules! serial_println {
() => ($crate::serial_print!("\n"));
($($arg:tt)*) => (serial_print!("{}\n", format_args!($($arg)*)));
}
use super::port::{inb, outb};
+1
View File
@@ -0,0 +1 @@
pub mod allocator;
+3
View File
@@ -0,0 +1,3 @@
pub mod io;
pub mod kalloc;
pub mod scheduling;
@@ -1,10 +1,8 @@
use alloc::boxed::Box;
use alloc::collections::{BTreeMap, VecDeque};
use alloc::sync::Arc;
use alloc::task::Wake;
use alloc::{boxed::Box, collections::BTreeMap, sync::Arc, task::Wake};
use core::sync::atomic::AtomicU64;
use core::task::Waker;
use core::task::{Context, Poll};
use core::task::{RawWaker, Waker};
use core::{future::Future, pin::Pin};
use crossbeam::queue::ArrayQueue;
use x86_64::instructions::interrupts::{self, enable_and_hlt};
-3
View File
@@ -1,3 +0,0 @@
pub mod allocator;
pub use self::allocator::init_heap;
+16 -4
View File
@@ -1,4 +1,5 @@
#![no_std]
#![allow(async_fn_in_trait)]
#![warn(tail_expr_drop_order)]
#![warn(clippy::correctness, clippy::perf, clippy::nursery)]
// alloc
@@ -8,11 +9,22 @@
extern crate alloc;
pub mod io;
pub mod kalloc;
pub mod scheduling;
pub mod drivers;
pub mod resources;
pub mod std;
/// Re-exports most of the IO macros.
/// Re-exports most of the IO macros as well as standard allocation stuff
pub mod prelude {
pub use crate::drivers::io::ascii::{_print, _print_log};
pub use crate::{print, print_log, println, println_log, serial_print, serial_println};
pub use alloc::{
boxed::Box,
string::{String, ToString},
vec::Vec,
};
}
pub use crate::drivers::io::{
ascii::{_print, _print_log},
serial::_serial_write,
};
+12
View File
@@ -0,0 +1,12 @@
use libm::include_font;
pub mod ibm_vga_8x16;
pub static FONT_SPLEEN_8X16: Font = Font(include_font!(
"/home/zxq5/Projects/OSDev/FoundryOS/libk/resources/font/spleen-8x16.psf"
));
pub static FONT_CP850_8X16: Font = Font(include_font!(
"/home/zxq5/Projects/OSDev/FoundryOS/libk/resources/font/cp850-8x16.psf"
));
pub struct Font(pub [[u8; 16]; 512]);
+1
View File
@@ -0,0 +1 @@
pub mod font;
+14
View File
@@ -0,0 +1,14 @@
use crate::prelude::*;
pub trait Application {
type Output;
async fn run(&mut self, args: Vec<String>) -> Result<Self::Output, Error>;
}
#[derive(Debug)]
pub enum Error {
UnknownCommand(String),
ApplicationFailed(String),
KernelError(String),
}
+2
View File
@@ -0,0 +1,2 @@
pub mod application;
pub mod window;
+74
View File
@@ -0,0 +1,74 @@
use crate::{prelude::*, std::maths::geometry::Vec2};
pub struct Window {
dimensions: Vec2<usize>,
position: Vec2<usize>,
bordered: bool,
opened: bool,
title: String,
}
impl Window {
pub const fn new() -> Window {
Window {
dimensions: Vec2::new(0, 0),
position: Vec2::new(0, 0),
bordered: true,
opened: false,
title: String::new(),
}
}
pub fn is_bordered(&self) -> bool {
self.bordered
}
pub fn is_open(&self) -> bool {
self.opened
}
pub fn open(&mut self) {
self.opened = true;
}
pub fn close(&mut self) {
self.opened = false;
}
// some basic getters and setters for utility.
pub fn title(&self) -> &str {
&self.title
}
pub fn dimensions(&self) -> Vec2<usize> {
self.dimensions
}
pub fn position(&self) -> Vec2<usize> {
self.position
}
pub fn set_title(&mut self, title: String) {
self.title = title;
}
pub fn move_window(&mut self, offset: Vec2<usize>) {
self.position += offset;
}
pub fn set_position(&mut self, position: Vec2<usize>) {
self.position = position;
}
pub fn set_dimensions(&mut self, dimensions: Vec2<usize>) {
self.dimensions = dimensions;
}
}
impl Drop for Window {
fn drop(&mut self) {
if self.opened {
self.close();
}
}
}
+73
View File
@@ -0,0 +1,73 @@
use core::ops::{AddAssign, DivAssign, MulAssign, SubAssign};
pub trait Coordinate:
Copy + Clone + PartialEq + AddAssign + MulAssign + SubAssign + DivAssign
{
}
impl Coordinate for usize {}
impl Coordinate for isize {}
impl Coordinate for u8 {}
impl Coordinate for i8 {}
impl Coordinate for u16 {}
impl Coordinate for i16 {}
impl Coordinate for u32 {}
impl Coordinate for i32 {}
impl Coordinate for u64 {}
impl Coordinate for i64 {}
impl Coordinate for u128 {}
impl Coordinate for i128 {}
impl Coordinate for f32 {}
impl Coordinate for f64 {}
#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)]
pub struct Vec2<T: Coordinate> {
x: T,
y: T,
}
impl<T: Coordinate> Vec2<T> {
pub const fn new(x: T, y: T) -> Self {
Self { x, y }
}
pub fn into<S: Coordinate + From<T>>(&self) -> Vec2<S> {
Vec2::new(self.x.clone().into(), self.y.clone().into())
}
pub fn x(&self) -> T {
self.x
}
pub fn y(&self) -> T {
self.y
}
}
impl<T: Coordinate> AddAssign for Vec2<T> {
fn add_assign(&mut self, rhs: Self) {
self.x += rhs.x;
self.y += rhs.y;
}
}
impl<T: Coordinate> SubAssign for Vec2<T> {
fn sub_assign(&mut self, rhs: Self) {
self.x -= rhs.x;
self.y -= rhs.y;
}
}
impl<T: Coordinate> MulAssign<T> for Vec2<T> {
fn mul_assign(&mut self, rhs: T) {
self.x *= rhs;
self.y *= rhs;
}
}
impl<T: Coordinate> DivAssign<T> for Vec2<T> {
fn div_assign(&mut self, rhs: T) {
self.x /= rhs;
self.y /= rhs;
}
}
+1
View File
@@ -0,0 +1 @@
pub mod geometry;
+2
View File
@@ -0,0 +1,2 @@
pub mod application;
pub mod maths;