PC Screen Fonts *should* parse correctly now, global memory management works. Still having issues with deallocating memory, however.
This commit is contained in:
parent
ff12b11b9f
commit
942478b0e2
6 changed files with 163 additions and 38 deletions
|
@ -3,4 +3,4 @@ target = "i686-unknown-none.json"
|
||||||
rustflags = ["-Clink-arg=--script=link.x"]
|
rustflags = ["-Clink-arg=--script=link.x"]
|
||||||
|
|
||||||
[unstable]
|
[unstable]
|
||||||
build-std = ["core"]
|
build-std = ["core", "alloc"]
|
|
@ -38,7 +38,7 @@
|
||||||
real_target=${!target}
|
real_target=${!target}
|
||||||
real_target=$(basename $real_target)
|
real_target=$(basename $real_target)
|
||||||
echo "Compiling target $target(with rust target of $real_target)"
|
echo "Compiling target $target(with rust target of $real_target)"
|
||||||
cargo build --target "$real_target" --release -Zbuild-std --bin entrypoint_$target
|
cargo build --target "$real_target" --release -Zbuild-std=core,alloc --bin entrypoint_$target
|
||||||
cp "target/$(echo $real_target | sed 's/\.json//')/release/entrypoint_$target" kernel-$target
|
cp "target/$(echo $real_target | sed 's/\.json//')/release/entrypoint_$target" kernel-$target
|
||||||
|
|
||||||
if [[ "$CONFIG_BUILD_GRUB" = "true" ]]; then
|
if [[ "$CONFIG_BUILD_GRUB" = "true" ]]; then
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
//! Provides interrupt-related functions
|
//! Provides interrupt-related functions
|
||||||
#![cfg(any(target_arch = "x86"))]
|
#![cfg(any(target_arch = "x86"))]
|
||||||
|
#![allow(static_mut_refs)]
|
||||||
|
|
||||||
use core::{alloc::{Allocator, Layout}, arch::asm, mem::MaybeUninit};
|
use core::{alloc::{Allocator, Layout}, arch::asm, mem::MaybeUninit};
|
||||||
|
|
||||||
|
@ -76,9 +77,7 @@ fn load_idt(base: *const u8, size: usize) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
unsafe {
|
unsafe {
|
||||||
asm!(
|
asm!("lidt {}", in(reg) IDTR.as_ptr() as usize)
|
||||||
"lidt {}", in(reg) IDTR.as_ptr() as usize
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +89,7 @@ fn activate_idt(idt: Idt, alloc: crate::mem::MemoryMapAlloc) {
|
||||||
let vector = idt.vectors[i];
|
let vector = idt.vectors[i];
|
||||||
let func = unsafe { idt.funcs[i].assume_init() } as usize as u32;
|
let func = unsafe { idt.funcs[i].assume_init() } as usize as u32;
|
||||||
let user_callable = idt.user_callable[i];
|
let user_callable = idt.user_callable[i];
|
||||||
let output: u64 = func & 0b1111111111111111;
|
let output: u64 = (func & 0b1111111111111111) as u64;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,8 @@ impl Iterator for AllocationIter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static mut ALLOCATOR: MaybeUninit<MemoryMapAlloc<'static>> = MaybeUninit::uninit();
|
#[global_allocator]
|
||||||
|
static mut ALLOCATOR: MaybeMemoryMapAlloc<'static> = MaybeMemoryMapAlloc::new(None);
|
||||||
static mut ALLOCATOR_MEMMAP: MaybeUninit<MemoryMap> = MaybeUninit::uninit();
|
static mut ALLOCATOR_MEMMAP: MaybeUninit<MemoryMap> = MaybeUninit::uninit();
|
||||||
static mut ALLOCATOR_INITALIZED: bool = false;
|
static mut ALLOCATOR_INITALIZED: bool = false;
|
||||||
|
|
||||||
|
@ -86,9 +87,9 @@ fn memory_map_alloc_init(memmap: crate::boot::MemoryMap) -> Result<(), crate::Er
|
||||||
#[allow(static_mut_refs)]
|
#[allow(static_mut_refs)]
|
||||||
let alloc = MemoryMapAlloc::new(unsafe { ALLOCATOR_MEMMAP.assume_init_mut() })?;
|
let alloc = MemoryMapAlloc::new(unsafe { ALLOCATOR_MEMMAP.assume_init_mut() })?;
|
||||||
|
|
||||||
#[allow(static_mut_refs)]
|
|
||||||
unsafe {
|
unsafe {
|
||||||
ALLOCATOR.write(alloc);
|
#[allow(static_mut_refs)]
|
||||||
|
ALLOCATOR.add_alloc(alloc);
|
||||||
}
|
}
|
||||||
unsafe {
|
unsafe {
|
||||||
ALLOCATOR_INITALIZED = true;
|
ALLOCATOR_INITALIZED = true;
|
||||||
|
@ -348,6 +349,101 @@ pub const FREE_MEMORY_UNAVAILABLE: i16 = -1;
|
||||||
/// Error returned when memory wasn't allocated.
|
/// Error returned when memory wasn't allocated.
|
||||||
pub const MEMORY_NOT_ALLOCATED: i16 = -7;
|
pub const MEMORY_NOT_ALLOCATED: i16 = -7;
|
||||||
|
|
||||||
|
/// Error returned when the [MaybeMemoryMapAlloc] doesn't have
|
||||||
|
/// an initalized allocator.
|
||||||
|
pub const MAYBE_MEMORY_MAP_ALLOC_UNINITALIZED: i16 = -8;
|
||||||
|
|
||||||
|
struct MaybeMemoryMapAlloc<'a> {
|
||||||
|
alloc: MaybeUninit<MemoryMapAlloc<'a>>,
|
||||||
|
initalized: bool
|
||||||
|
}
|
||||||
|
impl<'a> MaybeMemoryMapAlloc<'a> {
|
||||||
|
const fn new(alloc: Option<MemoryMapAlloc<'a>>) -> Self {
|
||||||
|
if alloc.is_none() {
|
||||||
|
return MaybeMemoryMapAlloc {
|
||||||
|
alloc: MaybeUninit::uninit(),
|
||||||
|
initalized: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MaybeMemoryMapAlloc {
|
||||||
|
alloc: MaybeUninit::new(alloc.unwrap()),
|
||||||
|
initalized: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const unsafe fn assume_init_ref(&self) -> &MemoryMapAlloc<'a> {
|
||||||
|
unsafe { self.alloc.assume_init_ref() }
|
||||||
|
}
|
||||||
|
/// Note that if the allocator isn't initalized then this will do nothing.
|
||||||
|
const fn add_alloc(&mut self, alloc: MemoryMapAlloc<'a>) {
|
||||||
|
if self.initalized {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.alloc.write(alloc);
|
||||||
|
self.initalized = true;
|
||||||
|
}
|
||||||
|
fn remove_alloc(&mut self) {
|
||||||
|
if !self.initalized {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unsafe { self.alloc.assume_init_drop(); }
|
||||||
|
self.initalized = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<'a> GlobalAlloc for MaybeMemoryMapAlloc<'a> {
|
||||||
|
unsafe fn alloc(&self, layout: core::alloc::Layout) -> *mut u8 {
|
||||||
|
if self.initalized {
|
||||||
|
unsafe {
|
||||||
|
LAST_MEMMAP_ERR = Err(crate::Error::new(
|
||||||
|
"MaybeMemoryMapAlloc not initalized",
|
||||||
|
MAYBE_MEMORY_MAP_ALLOC_UNINITALIZED,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
return null_mut();
|
||||||
|
}
|
||||||
|
unsafe { self.alloc.assume_init_ref().alloc(layout) }
|
||||||
|
}
|
||||||
|
unsafe fn dealloc(&self, ptr: *mut u8, layout: core::alloc::Layout) {
|
||||||
|
if self.initalized {
|
||||||
|
unsafe {
|
||||||
|
LAST_MEMMAP_ERR = Err(crate::Error::new(
|
||||||
|
"MaybeMemoryMapAlloc not initalized",
|
||||||
|
MAYBE_MEMORY_MAP_ALLOC_UNINITALIZED,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unsafe { self.alloc.assume_init_ref().dealloc(ptr, layout) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<'a> Allocator for MaybeMemoryMapAlloc<'a> {
|
||||||
|
fn allocate(&self, layout: core::alloc::Layout) -> Result<NonNull<[u8]>, core::alloc::AllocError> {
|
||||||
|
if !self.initalized {
|
||||||
|
unsafe {
|
||||||
|
LAST_MEMMAP_ERR = Err(crate::Error::new(
|
||||||
|
"MaybeMemoryMapAlloc not initalized",
|
||||||
|
MAYBE_MEMORY_MAP_ALLOC_UNINITALIZED,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
return Err(core::alloc::AllocError {});
|
||||||
|
}
|
||||||
|
unsafe { self.alloc.assume_init_ref() }.allocate(layout)
|
||||||
|
}
|
||||||
|
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: core::alloc::Layout) {
|
||||||
|
if !self.initalized {
|
||||||
|
unsafe {
|
||||||
|
LAST_MEMMAP_ERR = Err(crate::Error::new(
|
||||||
|
"MaybeMemoryMapAlloc not initalized",
|
||||||
|
MAYBE_MEMORY_MAP_ALLOC_UNINITALIZED,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unsafe { self.alloc.assume_init_ref().deallocate(ptr, layout) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsafe impl<'a> GlobalAlloc for MemoryMapAlloc<'a> {
|
unsafe impl<'a> GlobalAlloc for MemoryMapAlloc<'a> {
|
||||||
unsafe fn alloc(&self, layout: core::alloc::Layout) -> *mut u8 {
|
unsafe fn alloc(&self, layout: core::alloc::Layout) -> *mut u8 {
|
||||||
let result = self.allocate(layout);
|
let result = self.allocate(layout);
|
||||||
|
|
|
@ -8,19 +8,23 @@
|
||||||
#![feature(ptr_alignment_type)]
|
#![feature(ptr_alignment_type)]
|
||||||
#![feature(allocator_api)]
|
#![feature(allocator_api)]
|
||||||
#![feature(slice_ptr_get)]
|
#![feature(slice_ptr_get)]
|
||||||
|
#![feature(stmt_expr_attributes)]
|
||||||
#![feature(nonnull_provenance)]
|
#![feature(nonnull_provenance)]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
|
#![feature(ptr_as_uninit)]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
|
|
||||||
pub mod indep_boot_entry;
|
extern crate alloc;
|
||||||
|
|
||||||
pub mod arch;
|
pub mod arch;
|
||||||
pub mod boot;
|
pub mod boot;
|
||||||
pub mod cmdline;
|
pub mod cmdline;
|
||||||
mod constants;
|
mod constants;
|
||||||
pub mod display;
|
pub mod display;
|
||||||
mod errors;
|
mod errors;
|
||||||
|
pub mod indep_boot_entry;
|
||||||
pub mod mem;
|
pub mod mem;
|
||||||
pub mod multiboot2;
|
pub mod multiboot2;
|
||||||
pub mod output;
|
pub mod output;
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
//! PC Screen Font stuff
|
//! PC Screen Font stuff
|
||||||
|
|
||||||
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
/// The font selected to be the "main" font. I selected Linux's
|
/// The font selected to be the "main" font. I selected Linux's
|
||||||
/// ISO01-12x22 font.
|
/// ISO01-12x22 font.
|
||||||
pub const FONT1: &[u8; 12107] = include_bytes!("iso01-12x22.psfu");
|
pub const FONT1: &[u8; 12107] = include_bytes!("iso01-12x22.psfu");
|
||||||
|
|
||||||
/// One glyph for [RawPCScreenFont].
|
|
||||||
pub type RawGlyph = [u8];
|
|
||||||
|
|
||||||
/// PC Screen Font magic number.
|
/// PC Screen Font magic number.
|
||||||
pub const PSF_MAGIC: u32 = 0x864ab572;
|
pub const PSF_MAGIC: u32 = 0x864ab572;
|
||||||
|
|
||||||
|
@ -29,7 +28,7 @@ pub struct RawPCScreenFont {
|
||||||
/// The width of each glyph.
|
/// The width of each glyph.
|
||||||
pub width: u32,
|
pub width: u32,
|
||||||
/// The glyphs.
|
/// The glyphs.
|
||||||
pub glyphs: *const RawGlyph,
|
pub glyphs: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The glyph type for [PCScreenFont].
|
/// The glyph type for [PCScreenFont].
|
||||||
|
@ -40,7 +39,7 @@ pub struct Glyph {
|
||||||
pub height: u32,
|
pub height: u32,
|
||||||
/// The width of this glyph.
|
/// The width of this glyph.
|
||||||
pub width: u32,
|
pub width: u32,
|
||||||
/// The raw glyph data.
|
/// The raw glyph data(and unicode translation table).
|
||||||
pub data: &'static [u8],
|
pub data: &'static [u8],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,16 +54,16 @@ pub struct PCScreenFont {
|
||||||
/// The width of each glyph.
|
/// The width of each glyph.
|
||||||
pub width: u32,
|
pub width: u32,
|
||||||
/// The glyphs.
|
/// The glyphs.
|
||||||
pub glyphs: &'static [Glyph],
|
pub glyphs: Vec<Glyph>,
|
||||||
/// The unicode translation table.
|
/// The unicode translation table.
|
||||||
pub unitable: &'static [&'static [u8]]
|
pub unitable: Option<Vec<Vec<u8>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Error code returned when the PSF has an invalid magic number.
|
/// Error code returned when the PSF has an invalid magic number.
|
||||||
pub const ERR_INVALID_MAGIC: i16 = -1;
|
pub const ERR_INVALID_MAGIC: i16 = -1;
|
||||||
|
|
||||||
/// Parses a PC Screen Font into a [RawPCScreenFont].
|
/// Parses a PC Screen Font into a [RawPCScreenFont].
|
||||||
pub fn parse_raw_pc_screen_font(data: &[u8]) -> Result<RawPCScreenFont, crate::Error> {
|
pub fn parse_raw_pc_screen_font(data: Vec<u8>) -> Result<RawPCScreenFont, crate::Error<'static>> {
|
||||||
let out = RawPCScreenFont {
|
let out = RawPCScreenFont {
|
||||||
magic: u32::from_le_bytes(data[0..3].try_into().unwrap()),
|
magic: u32::from_le_bytes(data[0..3].try_into().unwrap()),
|
||||||
version: u32::from_le_bytes(data[4..7].try_into().unwrap()),
|
version: u32::from_le_bytes(data[4..7].try_into().unwrap()),
|
||||||
|
@ -74,7 +73,7 @@ pub fn parse_raw_pc_screen_font(data: &[u8]) -> Result<RawPCScreenFont, crate::E
|
||||||
bytes_per_glyph: u32::from_le_bytes(data[20..23].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()),
|
height: u32::from_le_bytes(data[24..27].try_into().unwrap()),
|
||||||
width: u32::from_le_bytes(data[28..31].try_into().unwrap()),
|
width: u32::from_le_bytes(data[28..31].try_into().unwrap()),
|
||||||
glyphs: &data[32..] as *const [u8]
|
glyphs: data[32..].to_vec(),
|
||||||
};
|
};
|
||||||
if out.magic != PSF_MAGIC {
|
if out.magic != PSF_MAGIC {
|
||||||
return Err(crate::Error::new("Invalid magic", ERR_INVALID_MAGIC));
|
return Err(crate::Error::new("Invalid magic", ERR_INVALID_MAGIC));
|
||||||
|
@ -83,26 +82,45 @@ pub fn parse_raw_pc_screen_font(data: &[u8]) -> Result<RawPCScreenFont, crate::E
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a PC Screen Font into a [PCScreenFont].
|
/// Parses a PC Screen Font into a [PCScreenFont].
|
||||||
pub fn parse_pc_screen_font(data: RawPCScreenFont) -> Result<PCScreenFont, crate::Error<'static>> {
|
pub fn parse_pc_screen_font(
|
||||||
|
data: RawPCScreenFont,
|
||||||
|
) -> Result<PCScreenFont, crate::Error<'static>> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let unitable: &[&[u8]] = &[];
|
if data.flags == 0 {
|
||||||
let unistr = data.glyphs.byte_add(data.bytes_per_glyph as usize*data.num_glyphs as usize);
|
let mut unitable: Vec<Vec<u8>> = Vec::with_capacity(data.num_glyphs as usize * core::mem::size_of::<Vec<u8>>());
|
||||||
|
|
||||||
let mut i = 0usize;
|
let unistr = (data
|
||||||
let mut f = 0usize;
|
.glyphs
|
||||||
loop {
|
.as_slice()
|
||||||
let g = i+f;
|
as *const [u8])
|
||||||
if i>=data.num_glyphs as usize {
|
.byte_add(data.bytes_per_glyph as usize * data.num_glyphs as usize);
|
||||||
break;
|
|
||||||
|
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[i].push(char);
|
||||||
|
f += 1;
|
||||||
}
|
}
|
||||||
let char = (*unistr)[g];
|
|
||||||
if char == 0xFF {
|
let out = PCScreenFont {
|
||||||
i += 1;
|
version: data.version,
|
||||||
f = 0;
|
flags: data.flags,
|
||||||
continue;
|
height: data.height,
|
||||||
}
|
width: data.width,
|
||||||
unitable[g];
|
glyphs: core::mem::transmute(data.glyphs),
|
||||||
f += 1;
|
unitable: Some(unitable),
|
||||||
|
};
|
||||||
|
return Ok(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
let out = PCScreenFont {
|
let out = PCScreenFont {
|
||||||
|
@ -110,9 +128,17 @@ pub fn parse_pc_screen_font(data: RawPCScreenFont) -> Result<PCScreenFont, crate
|
||||||
flags: data.flags,
|
flags: data.flags,
|
||||||
height: data.height,
|
height: data.height,
|
||||||
width: data.width,
|
width: data.width,
|
||||||
glyphs: &*(core::ptr::from_raw_parts(data.glyphs as *const Glyph, data.num_glyphs as usize) as *const [Glyph]),
|
glyphs: core::mem::transmute(data.glyphs),
|
||||||
unitable
|
unitable: None,
|
||||||
};
|
};
|
||||||
Ok(out)
|
Ok(out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parses a Vec<u8> into a [PCScreenFont].
|
||||||
|
pub fn parse_psfu(
|
||||||
|
data: Vec<u8>,
|
||||||
|
) -> Result<PCScreenFont, crate::Error<'static>> {
|
||||||
|
let data = parse_raw_pc_screen_font(data)?;
|
||||||
|
parse_pc_screen_font(data)
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue