diff --git a/Makefile b/Makefile index c84ad2c..3eb6bff 100644 --- a/Makefile +++ b/Makefile @@ -25,10 +25,17 @@ ifeq (${ARCH},riscv64) UEFI := true endif +ifeq (${ARCH},aarch64) + LIMINE_BOOT_VARIATION := AA64 + UEFI := true +endif + ifneq (${UEFI},) RUN_OPTS := ovmf-${ARCH} ifeq (${ARCH},riscv64) QEMU_OPTS += -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-riscv64/OVMF.fd -M virt + else ifeq (${ARCH},aarch64) + QEMU_OPTS += -M virt -bios ovmf/ovmf-${ARCH}/OVMF.fd else QEMU_OPTS += -bios ovmf/ovmf-${ARCH}/OVMF.fd endif @@ -148,6 +155,12 @@ ovmf-riscv64: ovmf cd ovmf/ovmf-riscv64 && curl -o OVMF.fd https://retrage.github.io/edk2-nightly/bin/RELEASERISCV64_VIRT_CODE.fd && dd if=/dev/zero of=OVMF.fd bs=1 count=0 seek=33554432; \ fi +ovmf-aarch64: + mkdir -p ovmf/ovmf-aarch64 + @if [ ! -d "ovmf/ovmf-aarch64/OVMF.fd" ]; then \ + cd ovmf/ovmf-aarch64 && curl -o OVMF.fd https://retrage.github.io/edk2-nightly/bin/RELEASEAARCH64_QEMU_EFI.fd; \ + fi + # In debug mode, open a terminal and run this command: # gdb target/x86_64-unknown-none/debug/CappuccinOS.elf -ex "target remote :1234" @@ -157,7 +170,10 @@ run-x86_64: qemu-system-x86_64 ${QEMU_OPTS} run-riscv64: - qemu-system-riscv64 ${QEMU_OPTS} -M virt -cpu rv64 -device ramfb -device qemu-xhci -device usb-kbd -device virtio-scsi-pci,id=scsi -device scsi-hd,drive=hd0 + qemu-system-riscv64 ${QEMU_OPTS} -cpu rv64 -device ramfb -device qemu-xhci -device usb-kbd -device virtio-scsi-pci,id=scsi -device scsi-hd,drive=hd0 + +run-aarch64: + qemu-system-aarch64 ${QEMU_OPTS} -cpu cortex-a72 -device ramfb -device qemu-xhci -device usb-kbd -boot d line-count: cloc --quiet --exclude-dir=bin --csv src/ | tail -n 1 | awk -F, '{print $$5}' diff --git a/src/arch/aarch64/aarch64-unknown-none.json b/src/arch/aarch64/aarch64-unknown-none.json new file mode 100644 index 0000000..5c5893f --- /dev/null +++ b/src/arch/aarch64/aarch64-unknown-none.json @@ -0,0 +1,22 @@ +{ + "data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", + "llvm-target": "aarch64-unknown-none", + "target-endian": "little", + "target-pointer-width": "64", + "target-c-int-width": "32", + "features": "+v8a,+strict-align,+neon,+fp-armv8", + "os": "CappuccinOS", + "arch": "aarch64", + "linker": "rust-lld", + "linker-flavor": "ld.lld", + "pre-link-args": { + "ld.lld": [ + "--fix-cortex-a53-843419", + "-maarch64elf", + "--script=./src/arch/aarch64/linker.ld" + ] + }, + "panic-strategy": "abort", + "exe-suffix": ".elf", + "disable-redzone": true +} \ No newline at end of file diff --git a/src/arch/aarch64/io.rs b/src/arch/aarch64/io.rs new file mode 100644 index 0000000..6af24ab --- /dev/null +++ b/src/arch/aarch64/io.rs @@ -0,0 +1,54 @@ +#[inline(always)] +pub fn outb(port: u16, value: u8) { + return; +} + +#[inline(always)] +pub fn inb(port: u16) -> u8 { + return 0; +} + +#[inline(always)] +pub fn outw(port: u16, value: u16) { + return; +} + +#[inline(always)] +pub fn inw(port: u16) -> u16 { + return 0; +} + +/// Reads `count` 16-bit values from the specified `port` into the `buffer`. +/// +/// # Safety +/// +/// This function panics if the supplied buffer's size is smaller than `count`. +#[inline(always)] +pub unsafe fn insw(port: u16, buffer: *mut u16, count: usize) { + return; +} + +/// Outputs `count` 16-bit values from the specified `port` into the `buffer`. +/// +/// # Safety +/// +/// This function panics if the supplied buffer's size is smaller than `count`. +#[inline(always)] +pub unsafe fn outsw(port: u16, buffer: *mut u16, count: usize) { + return; +} + +#[inline(always)] +pub fn outl(port: u16, value: u32) { + return; +} + +#[inline(always)] +pub fn inl(port: u16) -> u32 { + return 0; +} + +#[inline(always)] +pub fn io_wait() { + return; +} diff --git a/src/arch/aarch64/linker.ld b/src/arch/aarch64/linker.ld new file mode 100644 index 0000000..f8dd817 --- /dev/null +++ b/src/arch/aarch64/linker.ld @@ -0,0 +1,63 @@ +/* Tell the linker that we want an aarch64 ELF64 output file */ +OUTPUT_FORMAT(elf64-littleaarch64) +OUTPUT_ARCH(aarch64) + +/* We want the symbol _start to be our entry point */ +ENTRY(_start) + +/* Define the program headers we want so the bootloader gives us the right */ +/* MMU permissions */ +PHDRS +{ + text PT_LOAD FLAGS((1 << 0) | (1 << 2)) ; /* Execute + Read */ + rodata PT_LOAD FLAGS((1 << 2)) ; /* Read only */ + data PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */ + dynamic PT_DYNAMIC FLAGS((1 << 1) | (1 << 2)) ; /* Dynamic PHDR for relocations */ +} + +SECTIONS +{ + /* We wanna be placed in the topmost 2GiB of the address space, for optimisations */ + /* and because that is what the Limine spec mandates. */ + /* Any address in this region will do, but often 0xffffffff80000000 is chosen as */ + /* that is the beginning of the region. */ + . = 0xffffffff80000000; + + .text : { + *(.text .text.*) + } :text + + /* Move to the next memory page for .rodata */ + . += CONSTANT(MAXPAGESIZE); + + .rodata : { + *(.rodata .rodata.*) + } :rodata + + /* Move to the next memory page for .data */ + . += CONSTANT(MAXPAGESIZE); + + .data : { + *(.data .data.*) + } :data + + /* Dynamic section for relocations, both in its own PHDR and inside data PHDR */ + .dynamic : { + *(.dynamic) + } :data :dynamic + + /* NOTE: .bss needs to be the last thing mapped to :data, otherwise lots of */ + /* unnecessary zeros will be written to the binary. */ + /* If you need, for example, .init_array and .fini_array, those should be placed */ + /* above this. */ + .bss : { + *(.bss .bss.*) + *(COMMON) + } :data + + /* Discard .note.* and .eh_frame since they may cause issues on some hosts. */ + /DISCARD/ : { + *(.eh_frame) + *(.note .note.*) + } +} \ No newline at end of file diff --git a/src/arch/aarch64/mod.rs b/src/arch/aarch64/mod.rs new file mode 100644 index 0000000..af514a1 --- /dev/null +++ b/src/arch/aarch64/mod.rs @@ -0,0 +1 @@ +pub mod io; diff --git a/src/arch/mod.rs b/src/arch/mod.rs index a012068..63a9bb0 100644 --- a/src/arch/mod.rs +++ b/src/arch/mod.rs @@ -15,3 +15,9 @@ mod riscv64; #[cfg(target_arch = "riscv64")] pub use self::riscv64::*; + +#[cfg(target_arch = "aarch64")] +mod aarch64; + +#[cfg(target_arch = "aarch64")] +pub use self::aarch64::*; diff --git a/src/drivers/fs/initramfs/mod.rs b/src/drivers/fs/initramfs/mod.rs index 769e5e9..36183da 100755 --- a/src/drivers/fs/initramfs/mod.rs +++ b/src/drivers/fs/initramfs/mod.rs @@ -228,9 +228,9 @@ impl Squashfs<'_> { }; let table_size = header & 0x7FFF; - if table.len() >= 8192 { - panic!("Inode block is not less than 8KiB!"); - } + // if table.len() >= 8192 { + // panic!("Inode block is not less than 8KiB!"); + // } let mut buffer: Vec = Vec::new(); @@ -485,22 +485,22 @@ impl<'a> VfsFile for BasicFileInode<'a> { // TODO: is this really how you're supposed to do this? let mut block_data: Vec = Vec::with_capacity(self.file_size as usize); - unsafe { - let data_table = self.header.squashfs.get_decompressed_table( - self.header.squashfs.data_table, - ( - false, - Some( - !self - .header - .squashfs - .superblock - .features() - .uncompressed_data_blocks, - ), + let data_table = self.header.squashfs.get_decompressed_table( + self.header.squashfs.data_table, + ( + false, + Some( + !self + .header + .squashfs + .superblock + .features() + .uncompressed_data_blocks, ), - ); + ), + ); + unsafe { core::ptr::copy_nonoverlapping( data_table.as_ptr().add(self.block_offset as usize), block_data.as_mut_ptr(), diff --git a/src/drivers/serial.rs b/src/drivers/serial.rs index 574db13..e3a69dd 100644 --- a/src/drivers/serial.rs +++ b/src/drivers/serial.rs @@ -68,6 +68,4 @@ pub fn write_serial(character: char) { unsafe { *UART = character; }; - - return; } diff --git a/src/drivers/video/font.rs b/src/drivers/video/font.rs index 1e5ae41..bc43728 100755 --- a/src/drivers/video/font.rs +++ b/src/drivers/video/font.rs @@ -1,7 +1,10 @@ -use alloc::vec::Vec; +use alloc::{format, vec::Vec}; use crate::{ - drivers::fs::{initramfs::INITRAMFS, vfs::VfsFileSystem}, + drivers::{ + fs::{initramfs::INITRAMFS, vfs::VfsFileSystem}, + serial::write_serial, + }, libs::lazy::Lazy, }; @@ -48,5 +51,6 @@ pub static FONT: Lazy = Lazy::new(|| { .read() .unwrap() .to_vec(); + PSFFont::from_file_data(file_data).expect("Failed to create terminal font!") });