compressor bug fixes & externalize terminal font
This commit is contained in:
31
Makefile
31
Makefile
@@ -28,17 +28,17 @@ endif
|
||||
ifneq (${UEFI},)
|
||||
RUN_OPTS := ovmf-${ARCH}
|
||||
ifeq (${ARCH},riscv64)
|
||||
QEMU_OPTS += -drive if=pflash,unit=0,format=raw,file=bin/ovmf-riscv64/OVMF.fd -M virt
|
||||
QEMU_OPTS += -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-riscv64/OVMF.fd -M virt
|
||||
else
|
||||
QEMU_OPTS += -bios ovmf/ovmf-${ARCH}/OVMF.fd
|
||||
endif
|
||||
endif
|
||||
|
||||
.PHONY: all check prepare-bin-files copy-initramfs-files compile-initramfs copy-iso-files build-iso compile-bootloader compile-binaries ovmf clean run build line-count
|
||||
.PHONY: all check run-scripts prepare-bin-files copy-initramfs-files compile-initramfs copy-iso-files build-iso compile-bootloader compile-binaries ovmf clean run build line-count
|
||||
|
||||
all: build
|
||||
|
||||
build: prepare-bin-files compile-bootloader compile-binaries compile-initramfs build-iso
|
||||
build: prepare-bin-files compile-bootloader compile-binaries run-scripts compile-initramfs build-iso
|
||||
|
||||
check:
|
||||
cargo check
|
||||
@@ -63,6 +63,20 @@ compile-initramfs: copy-initramfs-files
|
||||
# Make squashfs without compression temporaily so I can get it working before I have to write a gzip driver
|
||||
mksquashfs ${INITRAMFS_PATH} ${ARTIFACTS_PATH}/initramfs.img ${MKSQUASHFS_OPTS}
|
||||
|
||||
run-scripts:
|
||||
nm target/${ARCH}-unknown-none/${MODE}/CappuccinOS.elf > scripts/symbols.table
|
||||
@if [ ! -d "scripts/rustc_demangle" ]; then \
|
||||
echo "Cloning rustc_demangle.py into scripts/rustc_demangle/..."; \
|
||||
git clone "https://github.com/juls0730/rustc_demangle.py" "scripts/rustc_demangle"; \
|
||||
else \
|
||||
echo "Folder scripts/rustc_demangle already exists. Skipping clone."; \
|
||||
fi
|
||||
python scripts/demangle-symbols.py
|
||||
mv scripts/symbols.table ${INITRAMFS_PATH}/
|
||||
|
||||
python scripts/font.py
|
||||
mv scripts/font.psf ${INITRAMFS_PATH}/
|
||||
|
||||
copy-iso-files:
|
||||
# Limine files
|
||||
mkdir -p ${ISO_PATH}/boot/limine
|
||||
@@ -99,16 +113,7 @@ else
|
||||
parted -a none ${IMAGE_PATH} set 1 boot on
|
||||
endif
|
||||
|
||||
build-iso: partition-iso
|
||||
nm target/${ARCH}-unknown-none/${MODE}/CappuccinOS.elf > scripts/symbols.table
|
||||
@if [ ! -d "scripts/rustc_demangle" ]; then \
|
||||
echo "Cloning rustc_demangle.py into scripts/rustc_demangle/..."; \
|
||||
git clone "https://github.com/juls0730/rustc_demangle.py" "scripts/rustc_demangle"; \
|
||||
else \
|
||||
echo "Folder scripts/rustc_demangle already exists. Skipping clone."; \
|
||||
fi
|
||||
python scripts/demangle-symbols.py
|
||||
mv scripts/symbols.table ${ISO_PATH}/boot
|
||||
build-iso: partition-iso copy-initramfs-files
|
||||
ifeq (${ARCH},x86_64)
|
||||
# Install the Limine bootloader for bios installs
|
||||
./limine/limine bios-install ${IMAGE_PATH}
|
||||
|
||||
28
scripts/font.py
Normal file
28
scripts/font.py
Normal file
File diff suppressed because one or more lines are too long
@@ -1,5 +1,7 @@
|
||||
use alloc::{borrow::ToOwned, string::String, vec::Vec};
|
||||
|
||||
use crate::drivers::fs::vfs::VfsFileSystem;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
struct StackFrame {
|
||||
@@ -35,17 +37,7 @@ pub fn print_stack_trace(max_frames: usize, rbp: u64) {
|
||||
}
|
||||
|
||||
fn get_function_name(function_address: u64) -> Result<(String, u64), ()> {
|
||||
if crate::drivers::fs::vfs::VFS_INSTANCES
|
||||
.lock()
|
||||
.read()
|
||||
.is_empty()
|
||||
{
|
||||
return Err(());
|
||||
}
|
||||
|
||||
let vfs_lock = crate::drivers::fs::vfs::VFS_INSTANCES.lock();
|
||||
|
||||
let symbols_fd = vfs_lock.read()[0].open("/boot/symbols.table")?;
|
||||
let symbols_fd = (*crate::drivers::fs::initramfs::INITRAMFS).open("/symbols.table")?;
|
||||
|
||||
let symbols_table_bytes = symbols_fd.read()?;
|
||||
let symbols_table = core::str::from_utf8(&symbols_table_bytes).ok().ok_or(())?;
|
||||
|
||||
@@ -23,48 +23,63 @@ impl From<u8> for ZlibCompressionLevel {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[repr(u8)]
|
||||
pub enum CompressionErrors {
|
||||
NotDeflate = 0,
|
||||
UnsupportedWindowSize,
|
||||
FCheckFailed,
|
||||
UnsupportedDictionary,
|
||||
FailedChecksum,
|
||||
FailedCompression,
|
||||
}
|
||||
|
||||
// RFC 1950: "ZLIB Compressed Data Format Specification"
|
||||
// RFC 1951: "DEFLATE Compressed Data Format Specification"
|
||||
pub fn uncompress_data(bytes: &[u8]) -> Result<Arc<[u8]>, ()> {
|
||||
pub fn uncompress_data(bytes: &[u8]) -> Result<Arc<[u8]>, CompressionErrors> {
|
||||
assert!(bytes.len() > 2);
|
||||
|
||||
// Compression Method and flags
|
||||
let cmf = bytes[0];
|
||||
|
||||
if (cmf & 0x0F) != 0x08 {
|
||||
panic!("Compression method is not deflate!");
|
||||
return Err(CompressionErrors::NotDeflate);
|
||||
}
|
||||
|
||||
let window_log2 = cmf >> 4 & 0x0F;
|
||||
|
||||
if window_log2 > 0x07 {
|
||||
panic!("Unsupported window size {window_log2:X}!");
|
||||
return Err(CompressionErrors::UnsupportedWindowSize);
|
||||
}
|
||||
|
||||
let flags = bytes[1];
|
||||
if (cmf as u32 * 256 + flags as u32) % 31 != 0 {
|
||||
return Err(());
|
||||
return Err(CompressionErrors::FCheckFailed);
|
||||
}
|
||||
|
||||
// TODO: Check if FCheck is valid
|
||||
|
||||
let present_dictionary = flags >> 5 & 0x01 != 0;
|
||||
let _compression_level: ZlibCompressionLevel = (flags >> 6 & 0x03).into();
|
||||
|
||||
if present_dictionary {
|
||||
// cry
|
||||
return Err(());
|
||||
return Err(CompressionErrors::UnsupportedDictionary);
|
||||
}
|
||||
|
||||
let mut inflate_context = InflateContext::new(&bytes[2..bytes.len() - 4]);
|
||||
|
||||
let data = inflate_context.decompress()?;
|
||||
let data = inflate_context.decompress();
|
||||
|
||||
// last 4 bytes
|
||||
if data.is_err() {
|
||||
return Err(CompressionErrors::FailedCompression);
|
||||
}
|
||||
|
||||
let data = data.unwrap();
|
||||
|
||||
// last 4 bytes of zlib data
|
||||
let checksum = u32::from_le_bytes(bytes[bytes.len() - 4..].try_into().unwrap());
|
||||
|
||||
if adler32(&data) != checksum {
|
||||
return Err(());
|
||||
return Err(CompressionErrors::FailedChecksum);
|
||||
}
|
||||
|
||||
return Ok(data.into());
|
||||
|
||||
@@ -5,17 +5,19 @@ use core::fmt::{self, Debug};
|
||||
use alloc::{boxed::Box, sync::Arc, vec::Vec};
|
||||
use limine::ModuleRequest;
|
||||
|
||||
use crate::libs::math::ceil;
|
||||
use crate::libs::{lazy::Lazy, math::ceil};
|
||||
|
||||
use super::vfs::{VfsDirectory, VfsFile, VfsFileSystem};
|
||||
|
||||
pub static MODULE_REQUEST: ModuleRequest = ModuleRequest::new(0);
|
||||
|
||||
pub fn init() {
|
||||
// TODO: do something better than this shite
|
||||
pub static INITRAMFS: Lazy<Squashfs> = Lazy::new(init);
|
||||
|
||||
fn init() -> Squashfs<'static> {
|
||||
// TODO: Put the module request stuff in another file?
|
||||
if MODULE_REQUEST.get_response().get().is_none() {
|
||||
crate::log_error!("Module request in none!");
|
||||
return;
|
||||
panic!("Module request in none!");
|
||||
}
|
||||
let module_response = MODULE_REQUEST.get_response().get().unwrap();
|
||||
|
||||
@@ -38,35 +40,24 @@ pub fn init() {
|
||||
// End TODO
|
||||
|
||||
if initramfs.is_none() {
|
||||
crate::log_error!("Initramfs was not found!");
|
||||
return;
|
||||
panic!("Initramfs was not found!");
|
||||
}
|
||||
let initramfs = initramfs.unwrap();
|
||||
|
||||
let squashfs = Squashfs::new(initramfs.base.as_ptr().unwrap());
|
||||
|
||||
if squashfs.is_err() {
|
||||
crate::log_error!("Initramfs in corrupt!");
|
||||
return;
|
||||
panic!("Initramfs in corrupt!");
|
||||
}
|
||||
|
||||
let squashfs = squashfs.unwrap();
|
||||
|
||||
crate::println!(
|
||||
"\033[92m{:?}",
|
||||
core::str::from_utf8(
|
||||
&squashfs
|
||||
.open("/firstdir/seconddirbutlonger/yeah.txt")
|
||||
.unwrap()
|
||||
.read()
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
return squashfs;
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
struct Squashfs<'a> {
|
||||
pub struct Squashfs<'a> {
|
||||
superblock: SquashfsSuperblock,
|
||||
data_table: &'a [u8],
|
||||
inode_table: &'a [u8],
|
||||
@@ -79,7 +70,7 @@ struct Squashfs<'a> {
|
||||
|
||||
impl Squashfs<'_> {
|
||||
fn new(ptr: *mut u8) -> Result<Squashfs<'static>, ()> {
|
||||
crate::log_info!("Parsing initramfs at {:p}", ptr);
|
||||
// crate::log_info!("Parsing initramfs at {:p}", ptr);
|
||||
|
||||
// 40 is the offset for bytes used by the archive in the superblock
|
||||
let length = unsafe { u64::from_le(*(ptr.add(40) as *const u64)) as usize };
|
||||
@@ -241,7 +232,7 @@ impl Squashfs<'_> {
|
||||
panic!("Inode block is not less than 8KiB!");
|
||||
}
|
||||
|
||||
let mut buffer: Vec<u8> = Vec::with_capacity(8192);
|
||||
let mut buffer: Vec<u8> = Vec::new();
|
||||
|
||||
if table_is_compressed {
|
||||
let bytes = if metadata_block.0 { &table[2..] } else { table };
|
||||
@@ -492,7 +483,7 @@ impl<'a> VfsFile for BasicFileInode<'a> {
|
||||
as usize;
|
||||
|
||||
// TODO: is this really how you're supposed to do this?
|
||||
let mut block_data: Vec<u8> = Vec::with_capacity(8192 * block_count);
|
||||
let mut block_data: Vec<u8> = Vec::with_capacity(self.file_size as usize);
|
||||
|
||||
unsafe {
|
||||
let data_table = self.header.squashfs.get_decompressed_table(
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -35,16 +35,16 @@ pub fn put_char(
|
||||
bg: u32,
|
||||
mirror_buffer: Option<Framebuffer>,
|
||||
) {
|
||||
let font = font::G_8X16_FONT;
|
||||
let font_width = 8;
|
||||
let font_height = 16;
|
||||
let font = &font::FONT;
|
||||
let font_width = font.header.width;
|
||||
let font_height = font.header.height;
|
||||
|
||||
if character as usize > u8::MAX as usize {
|
||||
character = '\x00'; // rounded question mark
|
||||
fg = 0xFF0000;
|
||||
}
|
||||
|
||||
let character_array = font[character as usize];
|
||||
let character_array = &font.data[character as usize];
|
||||
|
||||
let framebuffer =
|
||||
get_framebuffer().expect("Tried to use framebuffer, but framebuffer was not found");
|
||||
@@ -53,9 +53,10 @@ pub fn put_char(
|
||||
let start_y = cy * font_height as u16;
|
||||
|
||||
for (row_idx, &character_byte) in character_array.iter().enumerate() {
|
||||
let mut byte = vec![bg; font_width];
|
||||
let mut byte = vec![bg; font_width as usize];
|
||||
for (i, bit) in byte.iter_mut().enumerate() {
|
||||
*bit = [bg, fg][((character_byte >> ((font_width - 1) - i)) & 0b00000001) as usize]
|
||||
*bit = [bg, fg]
|
||||
[((character_byte >> ((font_width as usize - 1) - i)) & 0b00000001) as usize]
|
||||
}
|
||||
|
||||
let row_start_offset = (start_y as usize + row_idx) * framebuffer.pitch
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#![feature(abi_x86_interrupt, naked_functions)]
|
||||
#![feature(abi_x86_interrupt, allocator_api, naked_functions)]
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
@@ -30,8 +30,6 @@ pub extern "C" fn _start() -> ! {
|
||||
|
||||
mem::log_info();
|
||||
|
||||
drivers::fs::initramfs::init();
|
||||
|
||||
// drivers::acpi::init_acpi();
|
||||
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
@@ -118,6 +116,7 @@ fn parse_kernel_cmdline() -> KernelFeatures {
|
||||
#[panic_handler]
|
||||
fn panic(info: &core::panic::PanicInfo) -> ! {
|
||||
crate::log_error!("{}", info);
|
||||
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
{
|
||||
let rbp: u64;
|
||||
|
||||
@@ -36,6 +36,32 @@ pub static HHDM_OFFSET: Lazy<usize> = Lazy::new(|| {
|
||||
pub static PHYSICAL_MEMORY_MANAGER: Lazy<PhysicalMemoryManager> =
|
||||
Lazy::new(PhysicalMemoryManager::new);
|
||||
|
||||
pub struct PageAllocator;
|
||||
|
||||
unsafe impl core::alloc::Allocator for PageAllocator {
|
||||
fn allocate(
|
||||
&self,
|
||||
layout: core::alloc::Layout,
|
||||
) -> Result<core::ptr::NonNull<[u8]>, core::alloc::AllocError> {
|
||||
let pages = layout.size() / 4096 + 1;
|
||||
let ptr = PHYSICAL_MEMORY_MANAGER.alloc(pages);
|
||||
|
||||
if ptr.is_err() {
|
||||
return Err(core::alloc::AllocError);
|
||||
}
|
||||
|
||||
let ptr = ptr.unwrap();
|
||||
let slice: &mut [u8] = unsafe { core::slice::from_raw_parts_mut(ptr, pages) };
|
||||
|
||||
unsafe { Ok(core::ptr::NonNull::new_unchecked(slice)) }
|
||||
}
|
||||
|
||||
unsafe fn deallocate(&self, ptr: core::ptr::NonNull<u8>, layout: core::alloc::Layout) {
|
||||
let pages = layout.size() / 4096 + 1;
|
||||
|
||||
PHYSICAL_MEMORY_MANAGER.dealloc(ptr.as_ptr(), pages);
|
||||
}
|
||||
}
|
||||
pub struct Allocator {
|
||||
pub inner: Lazy<BuddyAllocator>,
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ impl Console {
|
||||
color_code_buffer.push(character);
|
||||
} else {
|
||||
if character == '[' {
|
||||
// official start of the escape sequence
|
||||
// official start of the color sequence
|
||||
color_code_buffer.clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user