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"]
|
||||
|
||||
[unstable]
|
||||
build-std = ["core"]
|
||||
build-std = ["core", "alloc"]
|
|
@ -38,7 +38,7 @@
|
|||
real_target=${!target}
|
||||
real_target=$(basename $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
|
||||
|
||||
if [[ "$CONFIG_BUILD_GRUB" = "true" ]]; then
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
//! Provides interrupt-related functions
|
||||
#![cfg(any(target_arch = "x86"))]
|
||||
#![allow(static_mut_refs)]
|
||||
|
||||
use core::{alloc::{Allocator, Layout}, arch::asm, mem::MaybeUninit};
|
||||
|
||||
|
@ -76,9 +77,7 @@ fn load_idt(base: *const u8, size: usize) {
|
|||
});
|
||||
}
|
||||
unsafe {
|
||||
asm!(
|
||||
"lidt {}", in(reg) IDTR.as_ptr() as usize
|
||||
)
|
||||
asm!("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 func = unsafe { idt.funcs[i].assume_init() } as usize as u32;
|
||||
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_INITALIZED: bool = false;
|
||||
|
||||
|
@ -86,9 +87,9 @@ fn memory_map_alloc_init(memmap: crate::boot::MemoryMap) -> Result<(), crate::Er
|
|||
#[allow(static_mut_refs)]
|
||||
let alloc = MemoryMapAlloc::new(unsafe { ALLOCATOR_MEMMAP.assume_init_mut() })?;
|
||||
|
||||
#[allow(static_mut_refs)]
|
||||
unsafe {
|
||||
ALLOCATOR.write(alloc);
|
||||
#[allow(static_mut_refs)]
|
||||
ALLOCATOR.add_alloc(alloc);
|
||||
}
|
||||
unsafe {
|
||||
ALLOCATOR_INITALIZED = true;
|
||||
|
@ -348,6 +349,101 @@ pub const FREE_MEMORY_UNAVAILABLE: i16 = -1;
|
|||
/// Error returned when memory wasn't allocated.
|
||||
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 fn alloc(&self, layout: core::alloc::Layout) -> *mut u8 {
|
||||
let result = self.allocate(layout);
|
||||
|
|
|
@ -8,19 +8,23 @@
|
|||
#![feature(ptr_alignment_type)]
|
||||
#![feature(allocator_api)]
|
||||
#![feature(slice_ptr_get)]
|
||||
#![feature(stmt_expr_attributes)]
|
||||
#![feature(nonnull_provenance)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(ptr_as_uninit)]
|
||||
#![allow(internal_features)]
|
||||
#![feature(core_intrinsics)]
|
||||
// tidy-alphabetical-end
|
||||
|
||||
pub mod indep_boot_entry;
|
||||
extern crate alloc;
|
||||
|
||||
pub mod arch;
|
||||
pub mod boot;
|
||||
pub mod cmdline;
|
||||
mod constants;
|
||||
pub mod display;
|
||||
mod errors;
|
||||
pub mod indep_boot_entry;
|
||||
pub mod mem;
|
||||
pub mod multiboot2;
|
||||
pub mod output;
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
//! PC Screen Font stuff
|
||||
|
||||
use alloc::vec::Vec;
|
||||
|
||||
/// 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;
|
||||
|
||||
|
@ -29,7 +28,7 @@ pub struct RawPCScreenFont {
|
|||
/// The width of each glyph.
|
||||
pub width: u32,
|
||||
/// The glyphs.
|
||||
pub glyphs: *const RawGlyph,
|
||||
pub glyphs: Vec<u8>,
|
||||
}
|
||||
|
||||
/// The glyph type for [PCScreenFont].
|
||||
|
@ -40,7 +39,7 @@ pub struct Glyph {
|
|||
pub height: u32,
|
||||
/// The width of this glyph.
|
||||
pub width: u32,
|
||||
/// The raw glyph data.
|
||||
/// The raw glyph data(and unicode translation table).
|
||||
pub data: &'static [u8],
|
||||
}
|
||||
|
||||
|
@ -55,16 +54,16 @@ pub struct PCScreenFont {
|
|||
/// The width of each glyph.
|
||||
pub width: u32,
|
||||
/// The glyphs.
|
||||
pub glyphs: &'static [Glyph],
|
||||
pub glyphs: Vec<Glyph>,
|
||||
/// 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.
|
||||
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> {
|
||||
pub fn parse_raw_pc_screen_font(data: Vec<u8>) -> Result<RawPCScreenFont, crate::Error<'static>> {
|
||||
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()),
|
||||
|
@ -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()),
|
||||
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]
|
||||
glyphs: data[32..].to_vec(),
|
||||
};
|
||||
if out.magic != PSF_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].
|
||||
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 {
|
||||
let unitable: &[&[u8]] = &[];
|
||||
let unistr = data.glyphs.byte_add(data.bytes_per_glyph as usize*data.num_glyphs as usize);
|
||||
if data.flags == 0 {
|
||||
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 mut f = 0usize;
|
||||
loop {
|
||||
let g = i+f;
|
||||
if i>=data.num_glyphs as usize {
|
||||
break;
|
||||
let unistr = (data
|
||||
.glyphs
|
||||
.as_slice()
|
||||
as *const [u8])
|
||||
.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[i].push(char);
|
||||
f += 1;
|
||||
}
|
||||
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::mem::transmute(data.glyphs),
|
||||
unitable: Some(unitable),
|
||||
};
|
||||
return Ok(out);
|
||||
}
|
||||
|
||||
let out = PCScreenFont {
|
||||
|
@ -110,9 +128,17 @@ pub fn parse_pc_screen_font(data: RawPCScreenFont) -> Result<PCScreenFont, crate
|
|||
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
|
||||
glyphs: core::mem::transmute(data.glyphs),
|
||||
unitable: None,
|
||||
};
|
||||
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