compressor bug fixes & externalize terminal font
This commit is contained in:
31
Makefile
31
Makefile
@@ -28,17 +28,17 @@ endif
|
|||||||
ifneq (${UEFI},)
|
ifneq (${UEFI},)
|
||||||
RUN_OPTS := ovmf-${ARCH}
|
RUN_OPTS := ovmf-${ARCH}
|
||||||
ifeq (${ARCH},riscv64)
|
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
|
else
|
||||||
QEMU_OPTS += -bios ovmf/ovmf-${ARCH}/OVMF.fd
|
QEMU_OPTS += -bios ovmf/ovmf-${ARCH}/OVMF.fd
|
||||||
endif
|
endif
|
||||||
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
|
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:
|
check:
|
||||||
cargo 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
|
# 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}
|
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:
|
copy-iso-files:
|
||||||
# Limine files
|
# Limine files
|
||||||
mkdir -p ${ISO_PATH}/boot/limine
|
mkdir -p ${ISO_PATH}/boot/limine
|
||||||
@@ -99,16 +113,7 @@ else
|
|||||||
parted -a none ${IMAGE_PATH} set 1 boot on
|
parted -a none ${IMAGE_PATH} set 1 boot on
|
||||||
endif
|
endif
|
||||||
|
|
||||||
build-iso: partition-iso
|
build-iso: partition-iso copy-initramfs-files
|
||||||
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
|
|
||||||
ifeq (${ARCH},x86_64)
|
ifeq (${ARCH},x86_64)
|
||||||
# Install the Limine bootloader for bios installs
|
# Install the Limine bootloader for bios installs
|
||||||
./limine/limine bios-install ${IMAGE_PATH}
|
./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 alloc::{borrow::ToOwned, string::String, vec::Vec};
|
||||||
|
|
||||||
|
use crate::drivers::fs::vfs::VfsFileSystem;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
struct StackFrame {
|
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), ()> {
|
fn get_function_name(function_address: u64) -> Result<(String, u64), ()> {
|
||||||
if crate::drivers::fs::vfs::VFS_INSTANCES
|
let symbols_fd = (*crate::drivers::fs::initramfs::INITRAMFS).open("/symbols.table")?;
|
||||||
.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_table_bytes = symbols_fd.read()?;
|
let symbols_table_bytes = symbols_fd.read()?;
|
||||||
let symbols_table = core::str::from_utf8(&symbols_table_bytes).ok().ok_or(())?;
|
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 1950: "ZLIB Compressed Data Format Specification"
|
||||||
// RFC 1951: "DEFLATE 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);
|
assert!(bytes.len() > 2);
|
||||||
|
|
||||||
// Compression Method and flags
|
// Compression Method and flags
|
||||||
let cmf = bytes[0];
|
let cmf = bytes[0];
|
||||||
|
|
||||||
if (cmf & 0x0F) != 0x08 {
|
if (cmf & 0x0F) != 0x08 {
|
||||||
panic!("Compression method is not deflate!");
|
return Err(CompressionErrors::NotDeflate);
|
||||||
}
|
}
|
||||||
|
|
||||||
let window_log2 = cmf >> 4 & 0x0F;
|
let window_log2 = cmf >> 4 & 0x0F;
|
||||||
|
|
||||||
if window_log2 > 0x07 {
|
if window_log2 > 0x07 {
|
||||||
panic!("Unsupported window size {window_log2:X}!");
|
return Err(CompressionErrors::UnsupportedWindowSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
let flags = bytes[1];
|
let flags = bytes[1];
|
||||||
if (cmf as u32 * 256 + flags as u32) % 31 != 0 {
|
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 present_dictionary = flags >> 5 & 0x01 != 0;
|
||||||
let _compression_level: ZlibCompressionLevel = (flags >> 6 & 0x03).into();
|
let _compression_level: ZlibCompressionLevel = (flags >> 6 & 0x03).into();
|
||||||
|
|
||||||
if present_dictionary {
|
if present_dictionary {
|
||||||
// cry
|
// cry
|
||||||
return Err(());
|
return Err(CompressionErrors::UnsupportedDictionary);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut inflate_context = InflateContext::new(&bytes[2..bytes.len() - 4]);
|
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());
|
let checksum = u32::from_le_bytes(bytes[bytes.len() - 4..].try_into().unwrap());
|
||||||
|
|
||||||
if adler32(&data) != checksum {
|
if adler32(&data) != checksum {
|
||||||
return Err(());
|
return Err(CompressionErrors::FailedChecksum);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(data.into());
|
return Ok(data.into());
|
||||||
|
|||||||
@@ -5,17 +5,19 @@ use core::fmt::{self, Debug};
|
|||||||
use alloc::{boxed::Box, sync::Arc, vec::Vec};
|
use alloc::{boxed::Box, sync::Arc, vec::Vec};
|
||||||
use limine::ModuleRequest;
|
use limine::ModuleRequest;
|
||||||
|
|
||||||
use crate::libs::math::ceil;
|
use crate::libs::{lazy::Lazy, math::ceil};
|
||||||
|
|
||||||
use super::vfs::{VfsDirectory, VfsFile, VfsFileSystem};
|
use super::vfs::{VfsDirectory, VfsFile, VfsFileSystem};
|
||||||
|
|
||||||
pub static MODULE_REQUEST: ModuleRequest = ModuleRequest::new(0);
|
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?
|
// TODO: Put the module request stuff in another file?
|
||||||
if MODULE_REQUEST.get_response().get().is_none() {
|
if MODULE_REQUEST.get_response().get().is_none() {
|
||||||
crate::log_error!("Module request in none!");
|
panic!("Module request in none!");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
let module_response = MODULE_REQUEST.get_response().get().unwrap();
|
let module_response = MODULE_REQUEST.get_response().get().unwrap();
|
||||||
|
|
||||||
@@ -38,35 +40,24 @@ pub fn init() {
|
|||||||
// End TODO
|
// End TODO
|
||||||
|
|
||||||
if initramfs.is_none() {
|
if initramfs.is_none() {
|
||||||
crate::log_error!("Initramfs was not found!");
|
panic!("Initramfs was not found!");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
let initramfs = initramfs.unwrap();
|
let initramfs = initramfs.unwrap();
|
||||||
|
|
||||||
let squashfs = Squashfs::new(initramfs.base.as_ptr().unwrap());
|
let squashfs = Squashfs::new(initramfs.base.as_ptr().unwrap());
|
||||||
|
|
||||||
if squashfs.is_err() {
|
if squashfs.is_err() {
|
||||||
crate::log_error!("Initramfs in corrupt!");
|
panic!("Initramfs in corrupt!");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let squashfs = squashfs.unwrap();
|
let squashfs = squashfs.unwrap();
|
||||||
|
|
||||||
crate::println!(
|
return squashfs;
|
||||||
"\033[92m{:?}",
|
|
||||||
core::str::from_utf8(
|
|
||||||
&squashfs
|
|
||||||
.open("/firstdir/seconddirbutlonger/yeah.txt")
|
|
||||||
.unwrap()
|
|
||||||
.read()
|
|
||||||
.unwrap()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Squashfs<'a> {
|
pub struct Squashfs<'a> {
|
||||||
superblock: SquashfsSuperblock,
|
superblock: SquashfsSuperblock,
|
||||||
data_table: &'a [u8],
|
data_table: &'a [u8],
|
||||||
inode_table: &'a [u8],
|
inode_table: &'a [u8],
|
||||||
@@ -79,7 +70,7 @@ struct Squashfs<'a> {
|
|||||||
|
|
||||||
impl Squashfs<'_> {
|
impl Squashfs<'_> {
|
||||||
fn new(ptr: *mut u8) -> Result<Squashfs<'static>, ()> {
|
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
|
// 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 };
|
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!");
|
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 {
|
if table_is_compressed {
|
||||||
let bytes = if metadata_block.0 { &table[2..] } else { table };
|
let bytes = if metadata_block.0 { &table[2..] } else { table };
|
||||||
@@ -492,7 +483,7 @@ impl<'a> VfsFile for BasicFileInode<'a> {
|
|||||||
as usize;
|
as usize;
|
||||||
|
|
||||||
// TODO: is this really how you're supposed to do this?
|
// 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 {
|
unsafe {
|
||||||
let data_table = self.header.squashfs.get_decompressed_table(
|
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,
|
bg: u32,
|
||||||
mirror_buffer: Option<Framebuffer>,
|
mirror_buffer: Option<Framebuffer>,
|
||||||
) {
|
) {
|
||||||
let font = font::G_8X16_FONT;
|
let font = &font::FONT;
|
||||||
let font_width = 8;
|
let font_width = font.header.width;
|
||||||
let font_height = 16;
|
let font_height = font.header.height;
|
||||||
|
|
||||||
if character as usize > u8::MAX as usize {
|
if character as usize > u8::MAX as usize {
|
||||||
character = '\x00'; // rounded question mark
|
character = '\x00'; // rounded question mark
|
||||||
fg = 0xFF0000;
|
fg = 0xFF0000;
|
||||||
}
|
}
|
||||||
|
|
||||||
let character_array = font[character as usize];
|
let character_array = &font.data[character as usize];
|
||||||
|
|
||||||
let framebuffer =
|
let framebuffer =
|
||||||
get_framebuffer().expect("Tried to use framebuffer, but framebuffer was not found");
|
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;
|
let start_y = cy * font_height as u16;
|
||||||
|
|
||||||
for (row_idx, &character_byte) in character_array.iter().enumerate() {
|
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() {
|
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
|
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_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
@@ -30,8 +30,6 @@ pub extern "C" fn _start() -> ! {
|
|||||||
|
|
||||||
mem::log_info();
|
mem::log_info();
|
||||||
|
|
||||||
drivers::fs::initramfs::init();
|
|
||||||
|
|
||||||
// drivers::acpi::init_acpi();
|
// drivers::acpi::init_acpi();
|
||||||
|
|
||||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||||
@@ -118,6 +116,7 @@ fn parse_kernel_cmdline() -> KernelFeatures {
|
|||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
fn panic(info: &core::panic::PanicInfo) -> ! {
|
fn panic(info: &core::panic::PanicInfo) -> ! {
|
||||||
crate::log_error!("{}", info);
|
crate::log_error!("{}", info);
|
||||||
|
|
||||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||||
{
|
{
|
||||||
let rbp: u64;
|
let rbp: u64;
|
||||||
|
|||||||
@@ -36,6 +36,32 @@ pub static HHDM_OFFSET: Lazy<usize> = Lazy::new(|| {
|
|||||||
pub static PHYSICAL_MEMORY_MANAGER: Lazy<PhysicalMemoryManager> =
|
pub static PHYSICAL_MEMORY_MANAGER: Lazy<PhysicalMemoryManager> =
|
||||||
Lazy::new(PhysicalMemoryManager::new);
|
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 struct Allocator {
|
||||||
pub inner: Lazy<BuddyAllocator>,
|
pub inner: Lazy<BuddyAllocator>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ impl Console {
|
|||||||
color_code_buffer.push(character);
|
color_code_buffer.push(character);
|
||||||
} else {
|
} else {
|
||||||
if character == '[' {
|
if character == '[' {
|
||||||
// official start of the escape sequence
|
// official start of the color sequence
|
||||||
color_code_buffer.clear();
|
color_code_buffer.clear();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user