summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcpplover0 <osdev555@yandex.com>2026-03-28 20:53:13 +0300
committercpplover0 <osdev555@yandex.com>2026-03-28 20:53:13 +0300
commitbe997311c240f49db247ccce05ecb8ea5d3bfc31 (patch)
treee5a7e4e97d58eae7417fb71c68f99d81d1ee630c
parenta66cd5681ab96d66259275f04bbdd2b44fc1d7c4 (diff)
evdev support, vfs, tmpfs
-rw-r--r--GNUmakefile5
-rw-r--r--baseiso/boot/OLI-D-T8.F16bin0 -> 4096 bytes
-rw-r--r--baseiso/boot/image.pngbin0 -> 1608260 bytes
-rwxr-xr-xkernel/get-deps2
-rw-r--r--kernel/src/arch/x86_64/cpu/gdt.cpp2
-rw-r--r--kernel/src/arch/x86_64/cpu/idt.cpp2
-rw-r--r--kernel/src/arch/x86_64/cpu/lapic.cpp4
-rw-r--r--kernel/src/arch/x86_64/cpu/sse.cpp4
-rw-r--r--kernel/src/arch/x86_64/cpu_local.hpp22
-rw-r--r--kernel/src/arch/x86_64/drivers/hpet.cpp4
-rw-r--r--kernel/src/arch/x86_64/drivers/ioapic.cpp4
-rw-r--r--kernel/src/arch/x86_64/drivers/pvclock.cpp40
-rw-r--r--kernel/src/arch/x86_64/drivers/tsc.cpp4
-rw-r--r--kernel/src/arch/x86_64/schedule_timer.cpp4
-rw-r--r--kernel/src/bg.bmpbin2851038 -> 0 bytes
-rw-r--r--kernel/src/drivers/disk.cpp2
-rw-r--r--kernel/src/drivers/ext2.cpp74
-rw-r--r--kernel/src/drivers/ext2.hpp4
-rw-r--r--kernel/src/drivers/mbr.hpp2
-rw-r--r--kernel/src/drivers/nvme.cpp6
-rw-r--r--kernel/src/drivers/powerbutton.cpp2
-rw-r--r--kernel/src/drivers/uacpi_kernel_api.cpp2
-rw-r--r--kernel/src/generic/bootloader/bootloader.hpp1
-rw-r--r--kernel/src/generic/bootloader/limine.cpp8
-rw-r--r--kernel/src/generic/bootloader/limine.hpp1
-rw-r--r--kernel/src/generic/devfs.cpp0
-rw-r--r--kernel/src/generic/devfs.hpp13
-rw-r--r--kernel/src/generic/evdev.cpp185
-rw-r--r--kernel/src/generic/evdev.hpp150
-rw-r--r--kernel/src/generic/poweroff.cpp8
-rw-r--r--kernel/src/generic/tmpfs.cpp306
-rw-r--r--kernel/src/generic/tmpfs.hpp21
-rw-r--r--kernel/src/generic/vfs.cpp147
-rw-r--r--kernel/src/generic/vfs.hpp423
-rw-r--r--kernel/src/klibc/stdio.hpp4
-rw-r--r--kernel/src/main.cpp12
-rw-r--r--kernel/src/utils/bitmap.hpp4
-rw-r--r--kernel/src/utils/flanterm.cpp270
-rw-r--r--kernel/src/utils/ringbuffer.hpp91
-rw-r--r--limine.conf3
40 files changed, 1517 insertions, 319 deletions
diff --git a/GNUmakefile b/GNUmakefile
index 276807d..7748f12 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -144,7 +144,7 @@ edk2-ovmf:
limine/limine:
rm -rf limine
- git clone https://codeberg.org/Limine/Limine.git limine --branch=v10.x-binary --depth=1
+ git clone https://codeberg.org/Limine/Limine.git limine --branch=v11.x-binary --depth=1
$(MAKE) -C limine \
CC="$(HOST_CC)" \
CFLAGS="$(HOST_CFLAGS)" \
@@ -162,6 +162,7 @@ kernel: kernel/.deps-obtained
$(IMAGE_NAME).iso: limine/limine kernel
rm -rf iso_root
mkdir -p iso_root/boot
+ cp -rf baseiso/* iso_root
cp -v kernel/bin-$(ARCH)/kernel iso_root/boot/
mkdir -p iso_root/boot/limine
cp -v limine.conf iso_root/boot/limine/
@@ -242,4 +243,4 @@ clean:
.PHONY: distclean
distclean:
$(MAKE) -C kernel distclean
- rm -rf iso_root *.iso *.hdd limine edk2-ovmf
+ rm -rf iso_root *.iso *.hdd limine edk2-ovmf \ No newline at end of file
diff --git a/baseiso/boot/OLI-D-T8.F16 b/baseiso/boot/OLI-D-T8.F16
new file mode 100644
index 0000000..2a00ea6
--- /dev/null
+++ b/baseiso/boot/OLI-D-T8.F16
Binary files differ
diff --git a/baseiso/boot/image.png b/baseiso/boot/image.png
new file mode 100644
index 0000000..5821ed5
--- /dev/null
+++ b/baseiso/boot/image.png
Binary files differ
diff --git a/kernel/get-deps b/kernel/get-deps
index 503a9a6..4399ce3 100755
--- a/kernel/get-deps
+++ b/kernel/get-deps
@@ -49,7 +49,7 @@ clone_repo_commit \
clone_repo_commit \
https://codeberg.org/Limine/limine-protocol.git \
limine-protocol \
- 068b6481557db836e41bf644382367f8dee76d21
+ 26519f1b598564db409e50d1d84eb30642d58ba3
clone_repo_commit \
https://codeberg.org/Mintsuki/Flanterm.git \
diff --git a/kernel/src/arch/x86_64/cpu/gdt.cpp b/kernel/src/arch/x86_64/cpu/gdt.cpp
index 0498c21..f2adea1 100644
--- a/kernel/src/arch/x86_64/cpu/gdt.cpp
+++ b/kernel/src/arch/x86_64/cpu/gdt.cpp
@@ -47,6 +47,6 @@ void x86_64::gdt::init() {
cpudata->timer_ist_stack = (std::uint64_t)(pmm::buddy::alloc(KERNEL_STACK_SIZE).phys + etc::hhdm());
static bool is_print = 0;
- if(!is_print) { klibc::printf("GDT: tss->rsp0 0x%p tss->ist0 0x%p\r\n",tss->rsp[0],tss->ist[0],tss->ist[1],tss->ist[2],tss->ist[3],cpudata->timer_ist_stack); is_print = 1; }
+ if(!is_print) { log("gdt", "tss->rsp0 0x%p tss->ist0 0x%p",tss->rsp[0],tss->ist[0],tss->ist[1],tss->ist[2],tss->ist[3],cpudata->timer_ist_stack); is_print = 1; }
} \ No newline at end of file
diff --git a/kernel/src/arch/x86_64/cpu/idt.cpp b/kernel/src/arch/x86_64/cpu/idt.cpp
index c62b1e6..def3341 100644
--- a/kernel/src/arch/x86_64/cpu/idt.cpp
+++ b/kernel/src/arch/x86_64/cpu/idt.cpp
@@ -43,7 +43,7 @@ void x86_64::idt::init() {
load();
- if(!is_print) {klibc::printf("IDT: IDTR is 0x%p\r\n",&idtr); is_print = 1;}
+ if(!is_print) {log("idt", "idtr is 0x%p",&idtr); is_print = 1;}
}
void x86_64::idt::load() {
diff --git a/kernel/src/arch/x86_64/cpu/lapic.cpp b/kernel/src/arch/x86_64/cpu/lapic.cpp
index 3bea37c..da98bfd 100644
--- a/kernel/src/arch/x86_64/cpu/lapic.cpp
+++ b/kernel/src/arch/x86_64/cpu/lapic.cpp
@@ -32,7 +32,7 @@ std::uint64_t x86_64::lapic::init(std::uint32_t us) {
if(c & (1 << 21)) {
// x2apic present
- if(!is_print) klibc::printf("X2APIC: Enabling x2apic (base is 0x%p)\r\n",0x800);
+ if(!is_print) log("x2apic", "enabling x2apic (base is 0x%p)",0x800);
assembly::wrmsr(0x1B,assembly::rdmsr(0x1B) | (1 << 10) | (1 << 11));
is_x2apic = 1;
} else {
@@ -52,7 +52,7 @@ std::uint64_t x86_64::lapic::init(std::uint32_t us) {
write(0x380,ticks);
if(!is_lapic_init) {
- if(!is_print) klibc::printf("LAPIC: Calibration time is %lli, ticks %lli\r\n",us,ticks);
+ if(!is_print) log("lapic", "calibration time is %lli, ticks %lli",us,ticks);
is_print = 1;
is_lapic_init = 1;
}
diff --git a/kernel/src/arch/x86_64/cpu/sse.cpp b/kernel/src/arch/x86_64/cpu/sse.cpp
index 73d53ae..b71ed10 100644
--- a/kernel/src/arch/x86_64/cpu/sse.cpp
+++ b/kernel/src/arch/x86_64/cpu/sse.cpp
@@ -120,8 +120,8 @@ void x86_64::sse::print_sse_features() {
std::uint32_t a,b,c,d;
assembly::cpuid(1,0,&a,&b,&c,&d);
- klibc::printf(
- "SSE: Supported features:" "%s%s%s%s%s%s\n",
+ log( "sse",
+ "supported features:" "%s%s%s%s%s%s",
(d & (1 << 25)) ? " SSE" : "\0",
(d & (1 << 26)) ? " SSE2" : "\0",
(c & (1 << 0)) ? " SSE3\0" : "\0",
diff --git a/kernel/src/arch/x86_64/cpu_local.hpp b/kernel/src/arch/x86_64/cpu_local.hpp
index d5add64..152e6fc 100644
--- a/kernel/src/arch/x86_64/cpu_local.hpp
+++ b/kernel/src/arch/x86_64/cpu_local.hpp
@@ -7,9 +7,11 @@
#include <generic/scheduling.hpp>
#include <klibc/string.hpp>
#include <klibc/stdio.hpp>
+#include <cstddef>
+#include <type_traits>
#include <generic/arch.hpp>
-typedef struct {
+struct cpudata_t {
std::uint64_t user_stack;
std::uint64_t kernel_stack;
std::uint64_t timer_ist_stack;
@@ -17,7 +19,7 @@ typedef struct {
std::uint64_t tsc_freq;
void* pvclock_buffer;
thread* current_thread;
-} cpudata_t;
+};
namespace x86_64 {
@@ -45,4 +47,20 @@ namespace x86_64 {
}
return (cpudata_t*)cpudata;
}
+
+ template <typename T, std::size_t Offset> [[nodiscard]] static inline T cpu_local_read() {
+ T out;
+ asm volatile("mov %%gs:%c1, %0" : "=r"(out) : "i"(Offset));
+ return out;
+ }
+
+ template <typename T, std::size_t Offset, typename V> static inline void cpu_local_write(V&& value) {
+ static_assert(std::is_same_v<std::remove_cvref_t<V>, std::remove_cv_t<T>>, "member type and value type are not compatible");
+ T v = static_cast<T>(value);
+ asm volatile("mov %0, %%gs:%c1" : : "r"(v), "i"(Offset));
+ }
+
};
+
+#define CPU_LOCAL_READ(field) x86_64::cpu_local_read<decltype(((cpudata_t*) nullptr)->field), offsetof(cpudata_t, field)>()
+#define CPU_LOCAL_WRITE(field, value) x86_64::cpu_local_write<decltype(((cpudata_t*) nullptr)->field), offsetof(cpudata_t, field)>((value)) \ No newline at end of file
diff --git a/kernel/src/arch/x86_64/drivers/hpet.cpp b/kernel/src/arch/x86_64/drivers/hpet.cpp
index 152f0d9..5421157 100644
--- a/kernel/src/arch/x86_64/drivers/hpet.cpp
+++ b/kernel/src/arch/x86_64/drivers/hpet.cpp
@@ -23,7 +23,7 @@ void drivers::hpet::init() {
uacpi_table hpet;
uacpi_status ret = uacpi_table_find_by_signature("HPET",&hpet);
if(ret != UACPI_STATUS_OK) {
- klibc::printf("HPET: hpet is not detected with status %d\r\n",ret);
+ log("hpet", "hpet is not detected with status %d",ret);
return;
}
@@ -36,7 +36,7 @@ void drivers::hpet::init() {
hpet_clock_nano = (*(volatile uint32_t*)(hpet_base + 4)) / 1000000;
hpet_timer* new_hpet_inst = new hpet_timer;
time::setup_timer(new_hpet_inst);
- klibc::printf("HPET: Detected %s hpet, current timestamp in nano %lli (hpet_base 0x%p)\r\n",hpet_is_32_bit ? "32 bit" : "64 bit", new_hpet_inst->current_nano(),hpet_base);
+ log("hpet", "Detected %s hpet, current timestamp in nano %lli (hpet_base 0x%p)",hpet_is_32_bit ? "32 bit" : "64 bit", new_hpet_inst->current_nano(),hpet_base);
}
namespace drivers {
diff --git a/kernel/src/arch/x86_64/drivers/ioapic.cpp b/kernel/src/arch/x86_64/drivers/ioapic.cpp
index 4b9c04a..ee5170f 100644
--- a/kernel/src/arch/x86_64/drivers/ioapic.cpp
+++ b/kernel/src/arch/x86_64/drivers/ioapic.cpp
@@ -41,13 +41,13 @@ void drivers::ioapic::init() {
struct acpi_madt_ioapic* cur_ioapic = (acpi_madt_ioapic*)current;
paging::map_range(gobject::kernel_root,cur_ioapic->address,cur_ioapic->address + etc::hhdm(),PAGE_SIZE,PAGING_PRESENT | PAGING_RW);
apics[apic_ent++] = *cur_ioapic;
- klibc::printf("IOAPIC: Found ioapic with gsi base %d, address 0x%p, id %d\r\n",cur_ioapic->gsi_base,cur_ioapic->address,cur_ioapic->id);
+ log("ioapic", "Found ioapic with gsi base %d, address 0x%p, id %d",cur_ioapic->gsi_base,cur_ioapic->address,cur_ioapic->id);
break;
}
case ACPI_MADT_ENTRY_TYPE_INTERRUPT_SOURCE_OVERRIDE: {
struct acpi_madt_interrupt_source_override* cur_iso = (struct acpi_madt_interrupt_source_override*)current;
iso[iso_ent++] = *cur_iso;
- klibc::printf("IOAPIC: Found ISO with bus %d, irq %d, gsi base %d, flags %d\r\n",cur_iso->bus,cur_iso->source,cur_iso->gsi,cur_iso->flags);
+ log("ioapic", "Found ISO with bus %d, irq %d, gsi base %d, flags %d",cur_iso->bus,cur_iso->source,cur_iso->gsi,cur_iso->flags);
break;
}
}
diff --git a/kernel/src/arch/x86_64/drivers/pvclock.cpp b/kernel/src/arch/x86_64/drivers/pvclock.cpp
index d77ef0f..db19120 100644
--- a/kernel/src/arch/x86_64/drivers/pvclock.cpp
+++ b/kernel/src/arch/x86_64/drivers/pvclock.cpp
@@ -43,26 +43,42 @@ void drivers::pvclock::bsp_init() {
drivers::pvclock_timer* timer = new drivers::pvclock_timer;
time::setup_timer(timer);
- klibc::printf("pvclock: pointer to buffer 0x%p\r\n",x86_64::cpu_data()->pvclock_buffer);
+ log("pvclock", "pointer to buffer 0x%p",x86_64::cpu_data()->pvclock_buffer);
}
namespace drivers {
std::uint64_t pvclock_timer::current_nano() {
- uint32_t lo, hi;
- asm volatile ("rdtsc" : "=a"(lo), "=d"(hi));
- std::uint64_t tsc_v = ((uint64_t)hi << 32) | lo;
- pvclock_vcpu_time_info* kvmclock_info = (pvclock_vcpu_time_info*)(x86_64::cpu_data()->pvclock_buffer);
- std::uint64_t time0 = tsc_v - kvmclock_info->tsc_timestamp;
- if(kvmclock_info->tsc_shift >= 0)
- time0 <<= kvmclock_info->tsc_shift;
- else
- time0 >>= -kvmclock_info->tsc_shift;
- time0 = (time0 * kvmclock_info->tsc_to_system_mul) >> 32;
- time0 = time0 + kvmclock_info->system_time;
+ auto* info = (pvclock_vcpu_time_info*)CPU_LOCAL_READ(pvclock_buffer);
+ uint32_t version;
+ uint64_t time0;
+
+ do {
+ version = info->version;
+ std::atomic_thread_fence(std::memory_order_acquire);
+
+ uint32_t lo, hi;
+ asm volatile ("rdtsc" : "=a"(lo), "=d"(hi) : : "memory");
+ uint64_t tsc_v = (static_cast<uint64_t>(hi) << 32) | lo;
+
+ uint64_t delta = tsc_v - info->tsc_timestamp;
+
+ if (info->tsc_shift >= 0)
+ delta <<= info->tsc_shift;
+ else
+ delta >>= -info->tsc_shift;
+
+ uint64_t scaled_delta = (static_cast<unsigned __int128>(delta) * info->tsc_to_system_mul) >> 32;
+
+ time0 = info->system_time + scaled_delta;
+
+ std::atomic_thread_fence(std::memory_order_acquire);
+ } while ((info->version & 1) || (info->version != version));
+
return time0;
}
+
void pvclock_timer::sleep(std::uint64_t us) {
std::uint64_t current = this->current_nano();
std::uint64_t end_ns = us * 1000;
diff --git a/kernel/src/arch/x86_64/drivers/tsc.cpp b/kernel/src/arch/x86_64/drivers/tsc.cpp
index 3776144..4203d76 100644
--- a/kernel/src/arch/x86_64/drivers/tsc.cpp
+++ b/kernel/src/arch/x86_64/drivers/tsc.cpp
@@ -17,7 +17,7 @@ static inline uint64_t rdtsc() {
void drivers::tsc::init() {
if(time::timer == nullptr) {
- klibc::printf("TSC: Can't initialize without timer !\n");
+ log("tsc", "can't initialize without timer !");
}
uint64_t tsc_start, tsc_end;
@@ -55,7 +55,7 @@ void drivers::tsc::init() {
x86_64::cpu_data()->tsc_freq = tsc_freq;
static bool is_print = 0;
- if(!is_print) {klibc::printf("TSC: TSC Frequency is %llu\r\n", tsc_freq); is_print = 1;}
+ if(!is_print) {log("tsc", "tsc frequency is %llu", tsc_freq); is_print = 1;}
drivers::tsc_timer* tsc_timer = new drivers::tsc_timer;
time::setup_timer(tsc_timer);
}
diff --git a/kernel/src/arch/x86_64/schedule_timer.cpp b/kernel/src/arch/x86_64/schedule_timer.cpp
index 97882c7..60bb649 100644
--- a/kernel/src/arch/x86_64/schedule_timer.cpp
+++ b/kernel/src/arch/x86_64/schedule_timer.cpp
@@ -35,12 +35,12 @@ void x86_64::schedule_timer::off() {
std::uint32_t timeout = 10;
- klibc::printf("Poweroff: Waiting for all cpus to done work\r\n"); // used from poweroff so
+ log("poweroff", "waiting for all cpus to done work"); // used from poweroff so
while(stfu_cpus != (std::int32_t)(mp::cpu_count() - 1)) {
arch::memory_barrier();
if(--timeout == 0) {
- klibc::printf("Poweroff: Can't wait longer, forching them to be disabled\r\n");
+ log("poweroff", "poweroff: Can't wait longer, forcing them to be disabled");
x86_64::lapic::off();
return;
}
diff --git a/kernel/src/bg.bmp b/kernel/src/bg.bmp
deleted file mode 100644
index 9aa3900..0000000
--- a/kernel/src/bg.bmp
+++ /dev/null
Binary files differ
diff --git a/kernel/src/drivers/disk.cpp b/kernel/src/drivers/disk.cpp
index 36742f2..19142b9 100644
--- a/kernel/src/drivers/disk.cpp
+++ b/kernel/src/drivers/disk.cpp
@@ -173,7 +173,7 @@ void drivers::init_disk(disk* new_disk) {
return;
partition_style style = determine_disk_type(new_disk);
- klibc::printf("Disk: Detected %s partition style\r\n", disk_type_to_str(style));
+ log("disk", "detected %s partition style", disk_type_to_str(style));
switch (style)
{
diff --git a/kernel/src/drivers/ext2.cpp b/kernel/src/drivers/ext2.cpp
index 34fdf32..74048f4 100644
--- a/kernel/src/drivers/ext2.cpp
+++ b/kernel/src/drivers/ext2.cpp
@@ -361,7 +361,7 @@ void ext2_free_blocks(ext2_partition* part, uint32_t count, uint64_t* blocks) {
pmm::freelist::free((uint64_t)bitmap - etc::hhdm());
}
-signed long ext2_read(file_descriptor* file, void* buffer, signed long count) {
+signed long ext2_read(file_descriptor* file, void* buffer, std::size_t count) {
if (count <= 0) return 0;
file->vnode.fs->lock.lock();
@@ -387,7 +387,7 @@ signed long ext2_read(file_descriptor* file, void* buffer, signed long count) {
std::uint32_t block_size = 1024 << part->sb->s_log_block_size;
char* temp_block = (char*)(pmm::freelist::alloc_4k() + etc::hhdm());
- signed long total_read = 0;
+ std::size_t total_read = 0;
char* out_ptr = (char*)buffer;
while (total_read < count) {
@@ -506,7 +506,7 @@ void ext2_write_inode(ext2_partition* part, uint64_t ino, ext2_inode* inode) {
pmm::freelist::free((uint64_t)buf - etc::hhdm());
}
-signed long ext2_write(file_descriptor* file, void* buffer, signed long count) {
+signed long ext2_write(file_descriptor* file, void* buffer, std::size_t count) {
if (count <= 0) return 0;
file->vnode.fs->lock.lock();
@@ -515,7 +515,7 @@ signed long ext2_write(file_descriptor* file, void* buffer, signed long count) {
uint32_t block_size = 1024 << part->sb->s_log_block_size;
char* temp_block = (char*)(pmm::freelist::alloc_4k() + etc::hhdm());
- signed long total_written = 0;
+ std::size_t total_written = 0;
const char* in_ptr = (const char*)buffer;
bool inode_dirty = false;
@@ -552,13 +552,17 @@ signed long ext2_write(file_descriptor* file, void* buffer, signed long count) {
return total_written;
}
-std::uint32_t ext2_open(filesystem* fs, void* file_desc, char* path) {
+std::uint32_t ext2_open(filesystem* fs, void* file_desc, char* path, bool is_directory) {
fs->lock.lock();
ext2_inode res;
std::uint64_t inode_num = 0;
std::uint32_t status = ext2_lookup((ext2_partition*)(fs->fs_specific.partition), path, &res, &inode_num);
if(status != 0) { fs->lock.unlock();
return status; }
+
+ if(is_directory && !(res.i_mode & EXT2_S_IFDIR))
+ return -ENOTDIR;
+
file_descriptor* fd = (file_descriptor*)file_desc;
fd->fs_specific.ino = inode_num;
fd->vnode.fs = fs;
@@ -569,6 +573,7 @@ std::uint32_t ext2_open(filesystem* fs, void* file_desc, char* path) {
}
std::int32_t ext2_stat(file_descriptor* file, stat* out) {
+ file->vnode.fs->lock.lock();
std::int32_t status = 0;
ext2_partition* part = (ext2_partition*)(file->vnode.fs->fs_specific.partition);
ext2_inode inode = ext2_get_inode(part, file->fs_specific.ino, &status);
@@ -593,7 +598,30 @@ std::int32_t ext2_stat(file_descriptor* file, stat* out) {
out->st_rdev = 0; // should be filled by vfs
out->st_nlink = inode.i_links_count;
out->st_mode = inode.i_mode;
+ out->st_ino = file->fs_specific.ino;
+ file->vnode.fs->lock.unlock();
+ return 0;
+}
+
+std::int32_t ext2_readlink(filesystem* fs, char* path, char* buffer) {
+ fs->lock.lock();
+ ext2_partition* part = (ext2_partition*)(fs->fs_specific.partition);
+ std::uint64_t inode = 0;
+ ext2_inode node = {};
+ std::int32_t status = ext2_lookup(part, path, &node, &inode);
+
+ if(status != 0) { fs->lock.unlock();
+ return status; }
+
+ if(!(node.i_mode & EXT2_S_IFLNK)) { fs->lock.unlock();
+ return -EINVAL; }
+
+ for(int i = 0;i < 4096 / (1024 << part->sb->s_log_block_size);i++) {
+ ext2_read_block(part, get_phys_block(part, &node, i), buffer);
+ }
+
+ fs->lock.unlock();
return 0;
}
@@ -648,7 +676,7 @@ void drivers::ext2::init(disk* target_disk, std::uint64_t lba_start) {
}
if(sb->revision >= 1) {
- klibc::printf("ext2: detected features %s %s %s\r\n",(sb->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_LARGE_FILE) ? "EXT2_FEATURE_RO_COMPAT_LARGE_FILE" : "", (sb->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT) ? "EXT4_FEATURE_INCOMPAT_64BIT" : "", (sb->s_feature_incompat & EXT4_FEATURE_INCOMPAT_EXTENTS) ? "EXT4_FEATURE_INCOMPAT_EXTENTS" : "");
+ log("ext2", "detected features %s %s %s",(sb->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_LARGE_FILE) ? "EXT2_FEATURE_RO_COMPAT_LARGE_FILE" : "", (sb->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT) ? "EXT4_FEATURE_INCOMPAT_64BIT" : "", (sb->s_feature_incompat & EXT4_FEATURE_INCOMPAT_EXTENTS) ? "EXT4_FEATURE_INCOMPAT_EXTENTS" : "");
}
uint32_t groups_count = (ext2_blocks_count(sb) + sb->s_blocks_per_group - 1);
@@ -663,26 +691,28 @@ void drivers::ext2::init(disk* target_disk, std::uint64_t lba_start) {
ext2_load_group_descriptors(part);
- ext2_inode root = ext2_get_inode(part, 2);
- klibc::printf("inode 2 size %lli links count %lli mode 0x%p block_size %lli\r\n",root.i_size, root.i_links_count, root.i_mode, 1024 << part->sb->s_log_block_size);
- klibc::printf("logic blocks for root first block = %lli, second block = %lli\r\n", get_phys_block(part, &root, 0),get_phys_block(part, &root, 1));
(void)print_buffer;
- char* buffer2 = (char*)(pmm::freelist::alloc_4k() + etc::hhdm());
- ext2_read_block(part, get_phys_block(part, &root, 0), buffer2);
- klibc::printf("dumping first root block\r\n");
- print_buffer((const unsigned char*)buffer2, 1024 << part->sb->s_log_block_size);
+ // ext2_inode root = ext2_get_inode(part, 2);
+ // klibc::printf("inode 2 size %lli links count %lli mode 0x%p block_size %lli\r\n",root.i_size, root.i_links_count, root.i_mode, 1024 << part->sb->s_log_block_size);
+ // klibc::printf("logic blocks for root first block = %lli, second block = %lli\r\n", get_phys_block(part, &root, 0),get_phys_block(part, &root, 1));
+ // (void)print_buffer;
+
+ // char* buffer2 = (char*)(pmm::freelist::alloc_4k() + etc::hhdm());
+ // ext2_read_block(part, get_phys_block(part, &root, 0), buffer2);
+ // klibc::printf("dumping first root block\r\n");
+ // print_buffer((const unsigned char*)buffer2, 1024 << part->sb->s_log_block_size);
- const char* file_test = "/test1/meow";
- ext2_inode res = {};
- std::uint64_t in = 0;
- std::int32_t status = ext2_lookup(part, file_test, &res, &in);
+ // const char* file_test = "/test1/meow";
+ // ext2_inode res = {};
+ // std::uint64_t in = 0;
+ // std::int32_t status = ext2_lookup(part, file_test, &res, &in);
- klibc::memset(buffer2, 0, PAGE_SIZE);
- klibc::printf("reading file %s, status %d, size %lli\r\n", file_test, status, res.i_size);
- ext2_read_block(part, get_phys_block(part, &res, 0), buffer2);
- klibc::printf("%s\r\n", buffer2);
+ // klibc::memset(buffer2, 0, PAGE_SIZE);
+ // klibc::printf("reading file %s, status %d, size %lli\r\n", file_test, status, res.i_size);
+ // ext2_read_block(part, get_phys_block(part, &res, 0), buffer2);
+ // klibc::printf("%s\r\n", buffer2);
- klibc::printf("group count %lli (size %lli)\r\n",groups_count,groups_count * sizeof(ext2_group_desc));
+ // klibc::printf("group count %lli (size %lli)\r\n",groups_count,groups_count * sizeof(ext2_group_desc));
} \ No newline at end of file
diff --git a/kernel/src/drivers/ext2.hpp b/kernel/src/drivers/ext2.hpp
index 4fdcd3c..2fee3fb 100644
--- a/kernel/src/drivers/ext2.hpp
+++ b/kernel/src/drivers/ext2.hpp
@@ -105,6 +105,10 @@ struct ext2_inode {
uint32_t i_osd2[3];
};
+#define EXT2_S_IFMT 0xF000
+#define EXT2_S_IFLNK 0xA000
+#define EXT2_S_IFDIR 0040000
+
struct ext2_dir_entry {
uint32_t inode;
uint16_t rec_len;
diff --git a/kernel/src/drivers/mbr.hpp b/kernel/src/drivers/mbr.hpp
index 4a78a95..6fb81a1 100644
--- a/kernel/src/drivers/mbr.hpp
+++ b/kernel/src/drivers/mbr.hpp
@@ -3,7 +3,7 @@
// mbr headers
-#define MBR_ORANGE_TRACE
+//#define MBR_ORANGE_TRACE
struct __attribute__((packed)) mbr_partition {
std::uint8_t drive_status;
diff --git a/kernel/src/drivers/nvme.cpp b/kernel/src/drivers/nvme.cpp
index 7ec7a21..cbec409 100644
--- a/kernel/src/drivers/nvme.cpp
+++ b/kernel/src/drivers/nvme.cpp
@@ -186,7 +186,7 @@ bool nvme_identify_namespace(struct nvme_controller* ctrl, uint32_t nsid) {
}
ns->valid = true;
- klibc::printf("NVME: Detected namespace %d with lba_size %lli bytes and total size %lli bytes\r\n", nsid, ns->lba_size, ns->size * ns->lba_size);
+ log("nvme", "detected namespace %d with lba_size %lli bytes and total size %lli bytes", nsid, ns->lba_size, ns->size * ns->lba_size);
return true;
}
@@ -438,7 +438,7 @@ bool nvme_identify(nvme_controller* ctrl) {
char model[41];
klibc::memcpy(model, (void*)(phys_buffer + etc::hhdm() + 24), 40);
model[40] = '\0';
- klibc::printf("NVME: Controller Model: %s\r\n", model);
+ log("nvme", "controller Model: %s", model);
ctrl->identify = (void*)(phys_buffer + etc::hhdm());
@@ -505,7 +505,7 @@ void nvme_init(std::uint64_t base) {
void nvme_pci_init(pci_t pci, std::uint8_t a, std::uint8_t b, std::uint8_t c) {
if(pci.progIF == 2) { // nvme
std::uint32_t cmd = x86_64::pci::pci_read_config32(a,b,c,0x4);
- klibc::printf("NVME_PCI: Bus mastering %d, memory access %d\r\n",(cmd & (1 << 2)) ? 1 : 0, (cmd & (1 << 1)) ? 1 : 0);
+ log("nvme_pci", "bus mastering %d, memory access %d",(cmd & (1 << 2)) ? 1 : 0, (cmd & (1 << 1)) ? 1 : 0);
cmd |= 1 << 2;
cmd |= 1 << 1;
x86_64::pci::pci_write_config32(a,b,c,0x4,cmd);
diff --git a/kernel/src/drivers/powerbutton.cpp b/kernel/src/drivers/powerbutton.cpp
index f34bdb9..a1ce3e4 100644
--- a/kernel/src/drivers/powerbutton.cpp
+++ b/kernel/src/drivers/powerbutton.cpp
@@ -16,7 +16,7 @@ void drivers::powerbutton::init() {
UACPI_FIXED_EVENT_POWER_BUTTON,
handle_power_button, UACPI_NULL
);
- klibc::printf("PowerButton: Registered powerbutton at ip 0x%p\r\n",(std::uint64_t)handle_power_button);
+ log("powerbutton", "registered powerbutton at ip 0x%p",(std::uint64_t)handle_power_button);
}
#else
diff --git a/kernel/src/drivers/uacpi_kernel_api.cpp b/kernel/src/drivers/uacpi_kernel_api.cpp
index 1a4c5cb..ac8e4c4 100644
--- a/kernel/src/drivers/uacpi_kernel_api.cpp
+++ b/kernel/src/drivers/uacpi_kernel_api.cpp
@@ -36,7 +36,7 @@ void uacpi_kernel_unmap(void *addr, uacpi_size len) {
}
void uacpi_kernel_log(uacpi_log_level, const uacpi_char* msg) {
- klibc::printf("uACPI: %s\r", msg);
+ klibc::printf("\033[1;31muacpi\033[0m: %s\r", msg);
}
uacpi_status uacpi_kernel_pci_device_open(
diff --git a/kernel/src/generic/bootloader/bootloader.hpp b/kernel/src/generic/bootloader/bootloader.hpp
index de9483e..ab9518f 100644
--- a/kernel/src/generic/bootloader/bootloader.hpp
+++ b/kernel/src/generic/bootloader/bootloader.hpp
@@ -14,6 +14,7 @@ namespace bootloader {
virtual limine_memmap_response* get_memory_map() = 0;
virtual limine_mp_response* get_mp_info() = 0;
virtual bool is_5_level_paging() = 0;
+ virtual limine_flanterm_fb_init_params_response* get_flanterm() = 0;
};
void init();
diff --git a/kernel/src/generic/bootloader/limine.cpp b/kernel/src/generic/bootloader/limine.cpp
index 00a7859..e6a3c8a 100644
--- a/kernel/src/generic/bootloader/limine.cpp
+++ b/kernel/src/generic/bootloader/limine.cpp
@@ -6,7 +6,7 @@
namespace {
__attribute__((used, section(".limine_requests")))
-volatile std::uint64_t limine_base_revision[] = LIMINE_BASE_REVISION(5);
+volatile std::uint64_t limine_base_revision[] = LIMINE_BASE_REVISION(6);
}
@@ -31,6 +31,8 @@ __attribute__((used, section(".limine_requests"))) volatile limine_mp_request mp
__attribute__((used, section(".limine_requests"))) volatile limine_rsdp_request rsdp_request = { .id = LIMINE_RSDP_REQUEST_ID, .revision = 0, .response = nullptr };
+__attribute__((used, section(".limine_requests"))) volatile limine_flanterm_fb_init_params_request flanterm = { .id = LIMINE_FLANTERM_FB_INIT_PARAMS_REQUEST_ID, .revision = 0, .response = nullptr };
+
#if defined(__x86_64__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
@@ -79,6 +81,10 @@ namespace bootloader {
return mp_request.response;
}
+ limine_flanterm_fb_init_params_response* limine::get_flanterm() {
+ return flanterm.response;
+ }
+
#if defined(__x86_64__)
bool limine::is_5_level_paging() {
return _5lvl_paging.response->mode == LIMINE_PAGING_MODE_X86_64_5LVL ? true : false;
diff --git a/kernel/src/generic/bootloader/limine.hpp b/kernel/src/generic/bootloader/limine.hpp
index eac231d..bac22bd 100644
--- a/kernel/src/generic/bootloader/limine.hpp
+++ b/kernel/src/generic/bootloader/limine.hpp
@@ -12,5 +12,6 @@ public:
limine_memmap_response* get_memory_map() override;
limine_mp_response* get_mp_info() override;
bool is_5_level_paging() override;
+ limine_flanterm_fb_init_params_response* get_flanterm() override;
};
}; \ No newline at end of file
diff --git a/kernel/src/generic/devfs.cpp b/kernel/src/generic/devfs.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/kernel/src/generic/devfs.cpp
diff --git a/kernel/src/generic/devfs.hpp b/kernel/src/generic/devfs.hpp
new file mode 100644
index 0000000..2c91d83
--- /dev/null
+++ b/kernel/src/generic/devfs.hpp
@@ -0,0 +1,13 @@
+#pragma once
+#include <cstdint>
+#include <generic/vfs.hpp>
+
+struct devfs_node {
+ vfs::pipe* pipe;
+};
+
+// for non input devices
+namespace devfs {
+ void create();
+ void init(vfs::node* new_node);
+} \ No newline at end of file
diff --git a/kernel/src/generic/evdev.cpp b/kernel/src/generic/evdev.cpp
new file mode 100644
index 0000000..b7bb4c1
--- /dev/null
+++ b/kernel/src/generic/evdev.cpp
@@ -0,0 +1,185 @@
+#include <cstdint>
+#include <generic/evdev.hpp>
+#include <generic/vfs.hpp>
+#include <klibc/string.hpp>
+#include <generic/lock/mutex.hpp>
+#include <generic/pmm.hpp>
+#include <generic/hhdm.hpp>
+#include <utils/align.hpp>
+#include <utils/errno.hpp>
+#include <utils/assert.hpp>
+
+locks::mutex evdev_lock;
+evdev::evdev_node evroot_node = {};
+evdev::evdev_node* evhead_node = nullptr;
+std::uint32_t evdev_ptr = 0;
+
+evdev::evdev_node* evdev_lookup(char* path) {
+ evdev::evdev_node* current = evhead_node;
+ while(current) {
+ if(klibc::strcmp(current->name, path) == 0) {
+ return current;
+ }
+ }
+ return nullptr;
+}
+
+int __bitmap_size(int c) {
+ return ALIGNUP(c,8) / 8;
+}
+
+bool evdev_poll(file_descriptor* file, vfs_poll_type type) {
+ evdev::evdev_node* node = (evdev::evdev_node*)(file->fs_specific.tmpfs_pointer);
+ assert(node->main_ring, "say gex !!!11!11151");
+ if(type == vfs_poll_type::pollin) {
+ return node->main_ring->is_not_empty(file->other.queue, file->other.cycle);
+ } else if(type == vfs_poll_type::pollout) {
+ return true;
+ }
+ return false;
+}
+
+std::int32_t evdev_ioctl(file_descriptor* file, std::uint64_t req, void* arg) {
+
+ evdev::evdev_node* node = (evdev::evdev_node*)(file->fs_specific.tmpfs_pointer);
+
+ std::uint64_t size = _IOC_SIZE(req);
+
+ if (_IOC_DIR(req) == _IOC_READ && (_IOC_NR(req) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0))) {
+ switch(_IOC_NR(req) & EV_MAX) {
+ case 0:
+ klibc::memcpy(arg,node->ev_bitmap->pool,__bitmap_size(EV_MAX));
+ return 0;
+ }
+ assert(0,"doing req %d",_IOC_NR(req) & EV_MAX);
+ } else {
+ switch(EVIOC_MASK_SIZE(req)) {
+ case EVIOCGNAME(0):
+ klibc::memcpy(arg, node->name, size > (std::uint64_t)klibc::strlen(node->name) ? size : (std::uint64_t)klibc::strlen(node->name));
+ return 0;
+ };
+ }
+
+ assert(0, "ioctl req 0x%p arg 0x%p path %s rev 0x%p",EVIOC_MASK_SIZE(req),arg,node->path,_IOC_NR(req) & EV_MAX);
+ return -EFAULT;
+}
+
+signed long evdev_read(file_descriptor* file, void* buffer, std::size_t count) {
+ evdev::evdev_node* node = (evdev::evdev_node*)(file->fs_specific.tmpfs_pointer);
+ assert(node->main_ring,"FAFASF");
+
+ return node->main_ring->receive((input_event*)buffer, count, &file->other.cycle, &file->other.queue);
+}
+
+void evdev::submit(int num, input_event event) {
+ evdev_lock.lock();
+ evdev::evdev_node* node = evhead_node;
+ while(node) {
+ if(node->num == num)
+ break;
+ }
+ assert(node, "hlehlpehspgfdkjfs");
+ assert(node->main_ring,"ffff");
+
+ node->main_ring->send(event);
+}
+
+int evdev::create(char* name, int type) {
+
+ evdev_lock.lock();
+ evdev::evdev_node* new_node = (evdev::evdev_node*)(pmm::freelist::alloc_4k() + etc::hhdm());
+ new_node->main_ring = new utils::ring_buffer<input_event>(256);
+
+ if(type == EVDEV_TYPE_KEYBOARD) {
+ new_node->ev_bitmap = new utils::bitmap(EV_MAX + 1);
+ new_node->ev_bitmap->set(EV_KEY);
+ new_node->ev_bitmap->set(EV_REP);
+ } else if(type == EVDEV_TYPE_MOUSE) {
+ new_node->ev_bitmap = new utils::bitmap(EV_MAX + 1);
+ new_node->ev_bitmap->set(EV_REL);
+ new_node->ev_bitmap->set(EV_SYN);
+ }
+
+ new_node->num = ++evdev_ptr;
+ klibc::__printfbuf(new_node->path, 256, "/event%d\r\n",new_node->num);
+ klibc::memcpy(new_node->name, name, klibc::strlen(name));
+
+ new_node->type = type;
+ new_node->next = evhead_node;
+ evhead_node = new_node;
+ return new_node->num;
+}
+
+std::int32_t evdev_readlink(filesystem* fs, char* path, char* buffer) {
+ (void)fs;
+ (void)path;
+ (void)buffer;
+ return -EINVAL;
+}
+
+std::int32_t evdev_create(filesystem* fs, char* path, vfs_file_type type, std::uint32_t mode) {
+ (void)fs;
+ (void)path;
+ (void)type;
+ (void)mode;
+ return -ENOTSUP;
+}
+
+signed long evdev_write(file_descriptor* file, void* buffer, std::size_t count) {
+ (void)file;
+ (void)buffer;
+ (void)count;
+ return -EACCES;
+}
+
+std::int32_t evdev_stat(file_descriptor* file, stat* out) {
+ evdev::evdev_node* node = (evdev::evdev_node*)(file->fs_specific.tmpfs_pointer);
+
+ klibc::memset(out, 0, sizeof(stat));
+
+ if(node->is_root) {
+ out->st_mode = S_IFDIR | 0666;
+ return 0;
+ }
+
+ out->st_size = 0;
+ out->st_blksize = 0;
+ out->st_blocks = 0;
+ out->st_mode = S_IFCHR | 0666;
+ out->st_ino = node->num;
+ return 0;
+}
+
+std::int32_t evdev_open(filesystem* fs, void* file_desc, char* path, bool is_directory) {
+
+ file_descriptor* fd = (file_descriptor*)file_desc;
+
+ if(klibc::strcmp(path, "/") == 0) {
+ fd->fs_specific.tmpfs_pointer = (std::uint64_t)&evroot_node;
+ return 0;
+ }
+
+ evdev_lock.lock();
+
+ if(is_directory)
+ return -EISDIR;
+
+ evdev::evdev_node* node = evdev_lookup(path);
+ fd->fs_specific.tmpfs_pointer = (std::uint64_t)node;
+ fd->vnode.read = evdev_read;
+ fd->vnode.ioctl = evdev_ioctl;
+ fd->vnode.write = evdev_write;
+ fd->vnode.stat = evdev_stat;
+
+ evdev_lock.unlock();
+ return 0;
+}
+
+void evdev::init_default(vfs::node* node) {
+ evroot_node.is_root = true;
+ klibc::memcpy(node->path, "/dev/input/\0\0", sizeof("/dev/input/\0\0") + 1);
+ node->fs->readlink = evdev_readlink;
+ node->fs->open = evdev_open;
+ node->fs->create = evdev_create;
+
+} \ No newline at end of file
diff --git a/kernel/src/generic/evdev.hpp b/kernel/src/generic/evdev.hpp
new file mode 100644
index 0000000..f10b268
--- /dev/null
+++ b/kernel/src/generic/evdev.hpp
@@ -0,0 +1,150 @@
+#pragma once
+
+#include <cstdint>
+#include <atomic>
+#include <utils/bitmap.hpp>
+#include <utils/ringbuffer.hpp>
+#include <generic/vfs.hpp>
+
+#define EVDEV_TYPE_MOUSE 1
+#define EVDEV_TYPE_KEYBOARD 2
+
+struct evdevtimeval {
+ long long tv_sec; /* seconds */
+ long long tv_usec; /* microseconds */
+
+};
+struct input_event {
+ struct evdevtimeval time;
+#define input_event_sec time.tv_sec
+#define input_event_usec time.tv_usec
+ std::uint16_t type;
+ std::uint16_t code;
+ std::int32_t value;
+};
+
+#define BTN_MOUSE 0x110
+#define BTN_LEFT 0x110
+#define BTN_RIGHT 0x111
+#define BTN_MIDDLE 0x112
+#define BTN_SIDE 0x113
+#define BTN_EXTRA 0x114
+#define BTN_FORWARD 0x115
+#define BTN_BACK 0x116
+#define BTN_TASK 0x117
+
+#define _IOC_NONE 0U
+#define _IOC_WRITE 1U
+#define _IOC_READ 2U
+
+#define _IOC_NRBITS 8
+#define _IOC_TYPEBITS 8
+#define _IOC_SIZEBITS 14
+#define _IOC_DIRBITS 2
+#define _IOC_NRMASK ((1 << _IOC_NRBITS) - 1)
+#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS) - 1)
+#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS) - 1)
+#define _IOC_DIRMASK ((1 << _IOC_DIRBITS) - 1)
+#define _IOC_NRSHIFT 0
+#define _IOC_TYPESHIFT (_IOC_NRSHIFT + _IOC_NRBITS)
+#define _IOC_SIZESHIFT (_IOC_TYPESHIFT + _IOC_TYPEBITS)
+#define _IOC_DIRSHIFT (_IOC_SIZESHIFT + _IOC_SIZEBITS)
+
+#define _IOC(dir, type, nr, size) \
+ (((dir) << _IOC_DIRSHIFT) | \
+ ((type) << _IOC_TYPESHIFT) | \
+ ((nr) << _IOC_NRSHIFT) | \
+ ((size) << _IOC_SIZESHIFT))
+
+#define _IO(type, nr) _IOC(_IOC_NONE, (type), (nr), 0)
+#define _IOR(type, nr, size) _IOC(_IOC_READ, (type), (nr), sizeof(size))
+#define _IOW(type, nr, size) _IOC(_IOC_WRITE, (type), (nr), sizeof(size))
+#define _IOWR(type, nr, size) _IOC(_IOC_READ | _IOC_WRITE, (type), (nr), sizeof(size))
+
+#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+#define EVIOC_MASK_SIZE(nr) ((nr) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT))
+#define EVIOCGVERSION _IOR('E', 0x01, int)
+#define EVIOCGID _IOR('E', 0x02, struct input_id)
+#define EVIOCGREP _IOR('E', 0x03, int[2])
+#define EVIOCSREP _IOW('E', 0x03, int[2])
+#define EVIOCGKEYCODE _IOR('E', 0x04, int[2])
+#define EVIOCSKEYCODE _IOW('E', 0x04, int[2])
+#define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len)
+#define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len)
+#define EVIOCGUNIQ(len) _IOC(_IOC_READ, 'E', 0x08, len)
+#define EVIOCGPROP(len) _IOC(_IOC_READ, 'E', 0x09, len)
+#define EVIOCGMTSLOTS(len) _IOC(_IOC_READ, 'E', 0x0a, len)
+#define EVIOCGKEY(len) _IOC(_IOC_READ, 'E', 0x18, len)
+#define EVIOCGLED(len) _IOC(_IOC_READ, 'E', 0x19, len)
+#define EVIOCGSND(len) _IOC(_IOC_READ, 'E', 0x1a, len)
+#define EVIOCGSW(len) _IOC(_IOC_READ, 'E', 0x1b, len)
+#define EVIOCGBIT(ev, len) _IOC(_IOC_READ, 'E', 0x20 + (ev), len)
+#define EVIOCGABS(abs) _IOR('E', 0x40 + (abs), struct input_absinfo)
+#define EVIOCSABS(abs) _IOW('E', 0x40 + (abs), struct input_absinfo)
+#define EVIOCSFF _IOC(_IOC_WRITE, 'E', 0x80, sizeof(struct ff_effect))
+#define EVIOCRMFF _IOW('E', 0x81, int)
+#define EVIOCGEFFECTS _IOR('E', 0x84, int)
+#define EVIOCGRAB _IOW('E', 0x90, int)
+#define EVIOCREVOKE _IOW('E', 0x91, int)
+#define EVIOCSMASK _IOW('E', 0x92, struct input_mask)
+#define EV_MAX 0x1f
+#define KEY_MAX 0x2ff
+#define REL_MAX 0x0f
+#define ABS_MAX 0x3f
+#define MSC_MAX 0x07
+#define LED_MAX 0x0f
+#define SND_MAX 0x07
+#define FF_MAX 0x7f
+#define SW_MAX 0x0f
+
+#define EV_SYN 0x00
+#define EV_KEY 0x01
+#define EV_REL 0x02
+#define EV_ABS 0x03
+#define EV_MSC 0x04
+#define EV_SW 0x05
+#define EV_LED 0x11
+#define EV_SND 0x12
+#define EV_REP 0x14
+#define EV_FF 0x15
+#define EV_PWR 0x16
+#define EV_FF_STATUS 0x17
+#define EV_MAX 0x1f
+#define EV_CNT (EV_MAX+1)
+
+#define BTN_MOUSE 0x110
+#define BTN_LEFT 0x110
+#define BTN_RIGHT 0x111
+#define BTN_MIDDLE 0x112
+#define BTN_SIDE 0x113
+#define BTN_EXTRA 0x114
+#define BTN_FORWARD 0x115
+#define BTN_BACK 0x116
+#define BTN_TASK 0x117
+
+namespace evdev {
+ struct evdev_node {
+ int num;
+ int type;
+ bool is_root;
+
+ utils::bitmap* ev_bitmap;
+ utils::ring_buffer<input_event>* main_ring;
+
+ char path[64];
+ char name[2048];
+
+ evdev_node* next;
+ };
+
+ static_assert(sizeof(evdev_node) < 4096, "stuf");
+
+ int create(char* name, int type);
+ void submit(int num, input_event event);
+ void init_default(vfs::node* node);
+
+} \ No newline at end of file
diff --git a/kernel/src/generic/poweroff.cpp b/kernel/src/generic/poweroff.cpp
index d81b3df..f9643f3 100644
--- a/kernel/src/generic/poweroff.cpp
+++ b/kernel/src/generic/poweroff.cpp
@@ -13,19 +13,19 @@
void poweroff::prepare_for_shutdown() {
drivers::nvme::disable();
- klibc::printf("Poweroff: NVME is disabled\r\n");
+ log("poweroff", "NVME is disabled");
#if defined(__x86_64__)
x86_64::schedule_timer::off();
#endif
locks::is_disabled = true;
- klibc::printf("Poweroff: Preparing for shutdown is successful\r\n");
+ log("poweroff", "preparing for shutdown is successful");
}
void poweroff::off() {
arch::disable_interrupts();
prepare_for_shutdown();
if(time::timer) {
- klibc::printf("Poweroff: Shutdowning after 3 seconds\r\n");
+ log("poweroff", "shutdowning after 3 seconds");
time::timer->sleep(3 * (1000 * 1000));
}
#if defined(__x86_64__)
@@ -40,7 +40,7 @@ void poweroff::reboot() {
arch::disable_interrupts();
prepare_for_shutdown();
if(time::timer) {
- klibc::printf("Poweroff: Rebooting after 3 seconds\r\n");
+ log("poweroff","rebooting after 3 seconds");
time::timer->sleep(3 * (1000 * 1000));
}
#if defined(__x86_64__)
diff --git a/kernel/src/generic/tmpfs.cpp b/kernel/src/generic/tmpfs.cpp
new file mode 100644
index 0000000..650fda3
--- /dev/null
+++ b/kernel/src/generic/tmpfs.cpp
@@ -0,0 +1,306 @@
+#include <cstdint>
+#include <generic/tmpfs.hpp>
+#include <generic/pmm.hpp>
+#include <generic/hhdm.hpp>
+#include <generic/vfs.hpp>
+#include <klibc/string.hpp>
+#include <utils/errno.hpp>
+#include <utils/assert.hpp>
+#include <atomic>
+
+tmpfs::tmpfs_node root_node = {};
+std::atomic<std::uint64_t> tmpfs_id_ptr = 1;
+
+bool tmpfs_find_child(tmpfs::tmpfs_node* node, char* name, tmpfs::tmpfs_node** out) {
+ if(node->type != vfs_file_type::directory)
+ return false;
+
+ for(std::uint64_t i = 0;i < node->size / sizeof(std::uint64_t);i++ ) {
+
+ if(node->directory_content[i] == nullptr)
+ continue;
+
+ if(klibc::strcmp(node->directory_content[i]->name, name) == 0) {
+ *out = node->directory_content[i];
+ return true;
+ }
+ }
+
+ return false;
+}
+
+tmpfs::tmpfs_node* tmpfs_lookup(char* path) {
+ if(klibc::strcmp(path,"/\0") == 0)
+ return &root_node;
+
+ tmpfs::tmpfs_node* current_node = &root_node;
+
+ char path_copy[4096];
+ klibc::memcpy(path_copy, path, klibc::strlen(path) + 1);
+
+ char* saveptr;
+ char* token = klibc::strtok(&saveptr, path_copy, "/");
+
+ while (token != nullptr) {
+ bool status = tmpfs_find_child(current_node, token, &current_node);
+ if(status == false)
+ return nullptr;
+ token = klibc::strtok(&saveptr, nullptr, "/");
+ }
+ return current_node;
+}
+
+tmpfs::tmpfs_node* tmpfs_get_parent(char* path) {
+ if (klibc::strcmp(path, "/") == 0 || klibc::strlen(path) == 0) {
+ return nullptr;
+ }
+
+ char path_copy[4096];
+ klibc::memcpy(path_copy, path, klibc::strlen(path) + 1);
+
+ char* last_slash = nullptr;
+ for (int i = 0; path_copy[i] != '\0'; i++) {
+ if (path_copy[i] == '/') {
+ last_slash = &path_copy[i];
+ }
+ }
+
+ if (last_slash == nullptr)
+ return &root_node;
+
+ if (last_slash == path_copy)
+ return &root_node;
+
+ *last_slash = '\0';
+ return tmpfs_lookup(path_copy);
+}
+
+char* tmpfs_get_name_from_path(char* path) {
+ if (path[0] == '\0') return path;
+ if (klibc::strcmp(path, "/") == 0) return path;
+
+ char* last_slash = nullptr;
+ int i = 0;
+
+ while (path[i] != '\0') {
+ if (path[i] == '/') {
+ last_slash = &path[i];
+ }
+ i++;
+ }
+
+ if (last_slash == nullptr)
+ return path;
+
+ return last_slash + 1;
+}
+
+std::int32_t tmpfs_readlink(filesystem* fs, char* path, char* buffer) {
+ fs->lock.lock();
+ tmpfs::tmpfs_node* node = tmpfs_lookup(path);
+ if(node == nullptr) { fs->lock.unlock();
+ return -ENOENT; }
+
+ if(node->type != vfs_file_type::symlink) { fs->lock.unlock();
+ return -EINVAL; }
+
+ assert(node->content,"meeeow meeeeeow :3");
+
+ klibc::memcpy(buffer, node->content, 4096);
+
+ fs->lock.unlock();
+ return 0;
+}
+
+signed long tmpfs_ls(file_descriptor* file, char* out, std::size_t count) {
+ file->vnode.fs->lock.lock();
+ auto node = (tmpfs::tmpfs_node*)file->fs_specific.tmpfs_pointer;
+
+ std::size_t current_offset = 0;
+ dirent file_ls = {};
+
+ if(node->type != vfs_file_type::directory)
+ return -ENOTDIR;
+
+again:
+
+ if(file->offset >= node->size) {
+ file->vnode.fs->lock.unlock();
+ return 0;
+ }
+
+ while(true) {
+ auto current_node = node->directory_content[file->offset];
+ if(sizeof(dirent) + klibc::strlen(current_node->name) + 1 > count - current_offset) {
+ file->vnode.fs->lock.unlock();
+ return current_offset;
+ }
+
+ file->offset += sizeof(tmpfs::tmpfs_node**);
+
+ if(current_node == nullptr)
+ goto again;
+
+ dirent* current_dir = (dirent*)(out + current_offset);
+ current_dir->d_ino = current_node->ino;
+ current_dir->d_type = vfs_to_dt_type(current_node->type);
+ current_dir->d_reclen = sizeof(dirent) + klibc::strlen(current_node->name) + 1;
+ current_dir->d_off = 0;
+ current_offset += current_dir->d_reclen;
+
+ }
+
+ file->vnode.fs->lock.unlock();
+ return 0;
+}
+
+std::int32_t tmpfs_create(filesystem* fs, char* path, vfs_file_type type, std::uint32_t mode) {
+ fs->lock.lock();
+ tmpfs::tmpfs_node* parent = tmpfs_get_parent(path);
+
+ if(parent == nullptr) { fs->lock.unlock();
+ return -ENOENT; }
+
+ parent->size += sizeof(tmpfs::tmpfs_node*);
+
+ if(parent->physical_size < parent->size) {
+ alloc_t res = pmm::buddy::alloc(parent->size * sizeof(tmpfs::tmpfs_node*));
+ tmpfs::tmpfs_node** new_dir = (tmpfs::tmpfs_node**)(res.phys + etc::hhdm());
+ klibc::memcpy(new_dir, parent->directory_content, parent->size);
+ pmm::buddy::free((std::uint64_t)parent->directory_content - etc::hhdm());
+ parent->directory_content = new_dir;
+ parent->physical_size = res.real_size;
+ }
+
+ tmpfs::tmpfs_node* new_node = (tmpfs::tmpfs_node*)(pmm::freelist::alloc_4k() + etc::hhdm());
+
+ new_node->type = type;
+ new_node->ino = tmpfs_id_ptr++;
+ new_node->mode = mode;
+ klibc::memcpy(new_node->name, tmpfs_get_name_from_path(path), klibc::strlen(tmpfs_get_name_from_path(path)) + 1);
+
+ parent->directory_content[(parent->size / sizeof(tmpfs::tmpfs_node**)) - 1] = new_node;
+
+ fs->lock.unlock();
+ return 0;
+}
+
+signed long tmpfs_read(file_descriptor* file, void* buffer, std::size_t count) {
+ file->vnode.fs->lock.lock();
+ tmpfs::tmpfs_node* node = (tmpfs::tmpfs_node*)(file->fs_specific.tmpfs_pointer);
+ if(node->type == vfs_file_type::directory) { file->vnode.fs->lock.unlock();
+ return -EISDIR; }
+
+ if(file->offset >= node->size || node->content == nullptr) {
+ file->vnode.fs->lock.unlock();
+ return 0;
+ }
+
+ std::size_t available = node->size - file->offset;
+ std::size_t to_read = (count > available) ? available : count;
+ klibc::memcpy(buffer, node->content + file->offset, to_read);
+ file->offset += to_read;
+
+ file->vnode.fs->lock.unlock();
+ return to_read;
+}
+
+signed long tmpfs_write(file_descriptor* file, void* buffer, std::size_t count) {
+ file->vnode.fs->lock.lock();
+ tmpfs::tmpfs_node* node = (tmpfs::tmpfs_node*)(file->fs_specific.tmpfs_pointer);
+ if(node->type == vfs_file_type::directory) { file->vnode.fs->lock.unlock();
+ return -EISDIR; }
+
+ if(file->offset + count > node->physical_size || node->content == nullptr) {
+ alloc_t new_content = pmm::buddy::alloc(file->offset + count);
+ char* new_cont = (char*)(new_content.phys + etc::hhdm());
+ if(node->content) {
+ klibc::memcpy(new_cont, node->content, node->size);
+ pmm::buddy::free((std::uint64_t)node->content - etc::hhdm());
+ }
+ node->content = new_cont;
+ node->physical_size = new_content.real_size;
+ }
+
+ if(file->offset + count > node->size)
+ node->size = file->offset + count;
+
+ klibc::memcpy(node->content + file->offset, buffer, count);
+
+ file->offset += count;
+ file->vnode.fs->lock.unlock();
+ return count;
+}
+
+inline static std::int32_t type_to_mode(vfs_file_type type) {
+ switch (type)
+ {
+
+ case vfs_file_type::directory:
+ return S_IFDIR;
+
+ case vfs_file_type::file:
+ return S_IFREG;
+
+ case vfs_file_type::symlink:
+ return S_IFLNK;
+
+ default:
+ assert(0,"say gex");
+ }
+}
+
+std::int32_t tmpfs_stat(file_descriptor* file, stat* out) {
+ file->vnode.fs->lock.lock();
+ tmpfs::tmpfs_node* node = (tmpfs::tmpfs_node*)file->fs_specific.tmpfs_pointer;
+ out->st_gid = 0;
+ out->st_uid = 0;
+ out->st_rdev = 0;
+ out->st_blksize = PAGE_SIZE;
+ out->st_blocks = node->physical_size / PAGE_SIZE;
+ out->st_mode = type_to_mode(node->type) | node->mode;
+ out->st_size = node->size;
+ out->st_ino = node->ino;
+ file->vnode.fs->lock.unlock();
+ return 0;
+}
+
+std::int32_t tmpfs_open(filesystem* fs, void* file_desc, char* path, bool is_directory) {
+ fs->lock.lock();
+ tmpfs::tmpfs_node* node = tmpfs_lookup(path);
+ if(node == nullptr) { fs->lock.unlock();
+ return -ENOENT; }
+
+ if(is_directory && node->type != vfs_file_type::directory) { fs->lock.unlock();
+ return -ENOTDIR; }
+
+ file_descriptor* fd = (file_descriptor*)file_desc;
+
+ fd->vnode.fs = fs;
+ fd->vnode.stat = tmpfs_stat;
+ fd->vnode.read = tmpfs_read;
+ fd->vnode.write = tmpfs_write;
+ fd->vnode.ls = tmpfs_ls;
+ fd->fs_specific.tmpfs_pointer = (std::uint64_t)node;
+
+ fs->lock.unlock();
+ return 0;
+}
+
+void tmpfs::init_default(vfs::node* node) {
+ filesystem* new_fs = new filesystem;
+ node->fs = new_fs;
+ node->fs->open = tmpfs_open;
+ node->fs->create = tmpfs_create;
+ node->fs->readlink = tmpfs_readlink;
+ klibc::memcpy(node->path, "/tmp/\0\0", sizeof("/tmp/\0\0") + 1);
+
+ alloc_t root_alloc = pmm::buddy::alloc(PAGE_SIZE);
+
+ root_node.size = 0;
+ root_node.physical_size = root_alloc.real_size;
+ klibc::memcpy(root_node.name, "/\0", sizeof("/\0") + 1);
+ root_node.directory_content = (tmpfs::tmpfs_node**)(root_alloc.phys + etc::hhdm());
+ log("tmpfs", "root_node is 0x%p",&root_node);
+
+} \ No newline at end of file
diff --git a/kernel/src/generic/tmpfs.hpp b/kernel/src/generic/tmpfs.hpp
new file mode 100644
index 0000000..86d9f13
--- /dev/null
+++ b/kernel/src/generic/tmpfs.hpp
@@ -0,0 +1,21 @@
+#pragma once
+#include <cstdint>
+#include <generic/vfs.hpp>
+
+namespace tmpfs {
+
+ struct tmpfs_node {
+ union {
+ char* content;
+ tmpfs_node** directory_content;
+ };
+ vfs_file_type type;
+ std::size_t size;
+ std::size_t physical_size;
+ std::uint64_t ino;
+ std::uint64_t mode;
+ char name[256];
+ };
+
+ void init_default(vfs::node* node);
+} \ No newline at end of file
diff --git a/kernel/src/generic/vfs.cpp b/kernel/src/generic/vfs.cpp
index 75c3ed8..296f72c 100644
--- a/kernel/src/generic/vfs.cpp
+++ b/kernel/src/generic/vfs.cpp
@@ -5,6 +5,8 @@
#include <utils/errno.hpp>
#include <klibc/stdio.hpp>
#include <generic/lock/mutex.hpp>
+#include <utils/assert.hpp>
+#include <generic/tmpfs.hpp>
// /bin/path -> /usr/bin/path
void __vfs_symlink_resolve_no_at_symlink_follow(char* path, char* out) {
@@ -13,15 +15,15 @@ void __vfs_symlink_resolve_no_at_symlink_follow(char* path, char* out) {
int e = vfs::readlink(path,buffer,4096);
- if(e == ENOSYS)
+ if(e == -ENOSYS)
klibc::memcpy(out,path,klibc::strlen(path) + 1);
- if(e == EINVAL)
+ if(e == -EINVAL)
klibc::memcpy(out,path,klibc::strlen(path) + 1);
else if(e == 0) {
klibc::memcpy(out,path,klibc::strlen(path) + 1);
- } else if(e == ENOENT) {
+ } else if(e == -ENOENT) {
klibc::memcpy(out,path,klibc::strlen(path) + 1);
// maybe it wants directory symlink ?
char path0[4096];
@@ -54,7 +56,7 @@ void __vfs_symlink_resolve_no_at_symlink_follow(char* path, char* out) {
klibc::memcpy(buffer2 + c, path + klibc::strlen(result) + 1, klibc::strlen(path) - klibc::strlen(result));
__vfs_symlink_resolve_no_at_symlink_follow(buffer2,out);
return;
- } else if(e == ENOENT) {
+ } else if(e == -ENOENT) {
klibc::memcpy(out,path,klibc::strlen(path) + 1);
}
@@ -78,17 +80,17 @@ void __vfs_symlink_resolve(char* path, char* out, int level) {
int e = vfs::readlink(path,buffer,4096);
- if(e == ENOSYS)
+ if(e == -ENOSYS)
klibc::memcpy(out,path,klibc::strlen(path) + 1);
- if(e == EINVAL)
+ if(e == -EINVAL)
klibc::memcpy(out,path,klibc::strlen(path) + 1);
else if(e == 0) {
char result[4096];
vfs::resolve_path(buffer,path,result,0);
__vfs_symlink_resolve(result,out, level + 1);
- } else if(e == ENOENT) {
+ } else if(e == -ENOENT) {
klibc::memcpy(out,path,klibc::strlen(path) + 1);
// maybe it wants directory symlink ?
char path0[4096];
@@ -121,7 +123,7 @@ void __vfs_symlink_resolve(char* path, char* out, int level) {
klibc::memcpy(buffer2 + c, path + klibc::strlen(result) + 1, klibc::strlen(path) - klibc::strlen(result));
__vfs_symlink_resolve(buffer2,out, level + 1);
return;
- } else if(e == ENOENT) {
+ } else if(e == -ENOENT) {
klibc::memcpy(out,path,klibc::strlen(path) + 1);
return;
} else {
@@ -135,7 +137,134 @@ void __vfs_symlink_resolve(char* path, char* out, int level) {
}
}
+vfs::node vfs_nodes[512];
-void vfs::init() {
+
+vfs::node* find_node(char* path) {
+ int r = 0;
+ vfs::node* match;
+ for(int i = 0;i < 512;i++) {
+ if(!klibc::strncmp(path,vfs_nodes[i].path,klibc::strlen(vfs_nodes[i].path))) {
+ if(klibc::strlen(vfs_nodes[i].path) > r) {
+ match = &vfs_nodes[i];
+ }
+ }
+
+ if(!klibc::strncmp(path, vfs_nodes[i].path,klibc::strlen(vfs_nodes[i].path) - 1) && path[klibc::strlen(vfs_nodes[i].path) + 1] == '\0') {
+ return &vfs_nodes[i];
+ }
+
+ }
+ return match;
+}
+
+std::int32_t vfs::open(file_descriptor* fd, char* path, bool follow_symlinks, bool is_directory) {
+ char out[4096];
+ klibc::memset(out,0,4096);
+
+ node* node = find_node(out);
+
+ if(follow_symlinks) {
+ __vfs_symlink_resolve(path, out, 0);
+ } else {
+ __vfs_symlink_resolve_no_at_symlink_follow(path, out);
+ }
+
+ if(!node) {
+ return -ENOENT; }
+
+ char* fs_love_name = out + klibc::strlen(node->path) - 1;
+ if(!node->fs->open) { assert(0, "meow :3");
+ return -ENOSYS; }
+
+ if(fs_love_name[0] == '\0') {
+ fs_love_name[0] = '/';
+ fs_love_name[1] = '\0';
+ }
+
+ std::int32_t status = node->fs->open(node->fs, (void*)fd, fs_love_name, is_directory);
+ return status;
+}
+
+std::int32_t vfs::create(char* path, vfs_file_type type, std::uint32_t mode) {
+ char out[4096];
+ klibc::memset(out,0,4096);
+
+ node* node = find_node(out);
+
+ __vfs_symlink_resolve_no_at_symlink_follow(path, out);
+
+ if(!node) {
+ return -ENOENT; }
+
+ char* fs_love_name = out + klibc::strlen(node->path) - 1;
+ if(!node->fs->create) { assert(0, "meow :3");
+ return -ENOSYS; }
+
+ if(fs_love_name[0] == '\0') {
+ fs_love_name[0] = '/';
+ fs_love_name[1] = '\0';
+ }
+
+ std::int32_t status = node->fs->create(node->fs, fs_love_name, type, mode);
+ return status;
+}
+
+std::int32_t vfs::readlink(char* path, char* out, std::uint32_t out_len) {
+
+ assert(out_len == 4096, "stfu");
+
+ char outp[4096];
+ klibc::memset(outp,0,4096);
+
+ node* node = find_node(outp);
+
+ klibc::memcpy(outp, path, klibc::strlen(path) + 1);
+
+ if(!node) {
+ return -ENOENT; }
+ char* fs_love_name = outp + klibc::strlen(node->path) - 1;
+ if(!node->fs->readlink) { assert(0, "meow :3");
+ return -ENOSYS; }
+
+ if(fs_love_name[0] == '\0') {
+ fs_love_name[0] = '/';
+ fs_love_name[1] = '\0';
+ }
+
+ std::int32_t status = node->fs->readlink(node->fs, fs_love_name, out);
+ return status;
+}
+
+std::int32_t vfs::remove(char* path) {
+ char out[4096];
+ klibc::memset(out,0,4096);
+
+ node* node = find_node(out);
+
+ __vfs_symlink_resolve_no_at_symlink_follow(path, out);
+
+ if(!node) {
+ return -ENOENT; }
+
+ char* fs_love_name = out + klibc::strlen(node->path) - 1;
+ if(!node->fs->remove) { assert(0, "meow remove :3");
+ return -ENOSYS; }
+
+ if(fs_love_name[0] == '\0') {
+ fs_love_name[0] = '/';
+ fs_love_name[1] = '\0';
+ }
+
+ std::int32_t status = node->fs->remove(node->fs, fs_love_name);
+ return status;
+}
+
+// will init default environment
+
+void vfs::init() {
+ klibc::memset(vfs_nodes, 0, sizeof(vfs_nodes));
+ tmpfs::init_default(&vfs_nodes[0]);
+ log("vfs", "vfs_nodes 0x%p",vfs_nodes);
} \ No newline at end of file
diff --git a/kernel/src/generic/vfs.hpp b/kernel/src/generic/vfs.hpp
index d6fac32..ecfd25b 100644
--- a/kernel/src/generic/vfs.hpp
+++ b/kernel/src/generic/vfs.hpp
@@ -3,6 +3,144 @@
#include <drivers/disk.hpp>
#include <generic/lock/mutex.hpp>
#include <utils/linux.hpp>
+#include <utils/assert.hpp>
+#include <generic/scheduling.hpp>
+
+#define USERSPACE_PIPE_SIZE (64 * 1024)
+#define S_IFSOCK 0140000
+#define S_IFLNK 0120000
+#define S_IFREG 0100000
+#define S_IFBLK 0060000
+#define S_IFDIR 0040000
+#define S_IFCHR 0020000
+#define S_IFIFO 0010000
+#define DT_UNKNOWN 0
+#define DT_FIFO 1
+#define DT_CHR 2
+#define DT_DIR 4
+#define DT_BLK 6
+#define DT_REG 8
+#define DT_LNK 10
+#define DT_SOCK 12
+#define DT_WHT 14
+
+#define CS8 0000060
+#define ECHO 0000010 /* Enable echo. */
+#define IGNBRK 0000001 /* Ignore break condition. */
+#define BRKINT 0000002 /* Signal interrupt on break. */
+#define IGNPAR 0000004 /* Ignore characters with parity errors. */
+#define PARMRK 0000010 /* Mark parity and framing errors. */
+#define INPCK 0000020 /* Enable input parity check. */
+#define ISTRIP 0000040 /* Strip 8th bit off characters. */
+#define INLCR 0000100 /* Map NL to CR on input. */
+#define IGNCR 0000200 /* Ignore CR. */
+#define ICRNL 0000400 /* Map CR to NL on input. */
+#define OPOST 0000001 /* Post-process output. */
+
+#define ICANON 0000002
+#define VMIN 6
+
+#define S_IRWXU 0700
+#define S_IRUSR 0400
+#define S_IWUSR 0200
+#define S_IXUSR 0100
+#define S_IRWXG 070
+#define S_IRGRP 040
+#define S_IWGRP 020
+#define S_IXGRP 010
+#define S_IRWXO 07
+#define S_IROTH 04
+#define S_IWOTH 02
+#define S_IXOTH 01
+#define S_ISUID 04000
+#define S_ISGID 02000
+#define S_ISVTX 01000
+
+/* open/fcntl. */
+#define O_ACCMODE 0003
+#define O_RDONLY 00
+#define O_WRONLY 01
+#define O_RDWR 02
+#ifndef O_CREAT
+# define O_CREAT 0100 /* Not fcntl. */
+#endif
+#ifndef O_EXCL
+# define O_EXCL 0200 /* Not fcntl. */
+#endif
+#ifndef O_NOCTTY
+# define O_NOCTTY 0400 /* Not fcntl. */
+#endif
+#ifndef O_TRUNC
+# define O_TRUNC 01000 /* Not fcntl. */
+#endif
+#ifndef O_APPEND
+# define O_APPEND 02000
+#endif
+#ifndef O_NONBLOCK
+# define O_NONBLOCK 04000
+#endif
+#ifndef O_NDELAY
+# define O_NDELAY O_NONBLOCK
+#endif
+#ifndef O_SYNC
+# define O_SYNC 04010000
+#endif
+#define O_FSYNC O_SYNC
+#ifndef O_ASYNC
+# define O_ASYNC 020000
+#endif
+#ifndef __O_LARGEFILE
+# define __O_LARGEFILE 0100000
+#endif
+
+#ifndef __O_DIRECTORY
+# define __O_DIRECTORY 0200000
+#endif
+#ifndef __O_NOFOLLOW
+# define __O_NOFOLLOW 0400000
+#endif
+#ifndef __O_CLOEXEC
+# define __O_CLOEXEC 02000000
+#endif
+#ifndef __O_DIRECT
+# define __O_DIRECT 040000
+#endif
+#ifndef __O_NOATIME
+# define __O_NOATIME 01000000
+#endif
+#ifndef __O_PATH
+# define __O_PATH 010000000
+#endif
+#ifndef __O_DSYNC
+# define __O_DSYNC 010000
+#endif
+#ifndef __O_TMPFILE
+# define __O_TMPFILE (020000000 | __O_DIRECTORY)
+#endif
+
+inline static std::uint32_t s_to_dt_type(std::uint32_t s_type) {
+ switch (s_type)
+ {
+ case S_IFSOCK:
+ return DT_SOCK;
+ case S_IFREG:
+ return DT_REG;
+ case S_IFBLK:
+ return DT_BLK;
+ case S_IFIFO:
+ return DT_FIFO;
+ case S_IFDIR:
+ return DT_DIR;
+ case S_IFCHR:
+ return DT_CHR;
+ case S_IFLNK:
+ return DT_LNK;
+ default:
+ assert(0,"shitfuck");
+ return 0;
+ }
+ return 0;
+}
enum class file_descriptor_type : std::uint8_t {
unallocated = 0,
@@ -13,6 +151,15 @@ enum class file_descriptor_type : std::uint8_t {
memfd = 5
};
+struct dirent {
+ std::uint64_t d_ino;
+ std::int64_t d_off;
+ unsigned short d_reclen;
+ unsigned char d_type;
+ char d_name[];
+};
+
+
struct stat {
dev_t st_dev;
ino_t st_ino;
@@ -34,6 +181,32 @@ struct stat {
#define st_ctime st_ctim.tv_sec
};
+enum class vfs_file_type : std::uint8_t {
+ file = 1,
+ directory = 2,
+ symlink = 3
+};
+
+enum class vfs_poll_type : std::uint8_t {
+ pollin = 1,
+ pollout = 2
+};
+
+inline static std::uint32_t vfs_to_dt_type(vfs_file_type type) {
+ switch(type) {
+ case vfs_file_type::directory:
+ return DT_DIR;
+ case vfs_file_type::file:
+ return DT_REG;
+ case vfs_file_type::symlink:
+ return DT_LNK;
+ default:
+ assert(0,"fsaifsi");
+ return 0; //
+ }
+ return 0;
+}
+
struct filesystem {
locks::mutex lock;
@@ -41,8 +214,11 @@ struct filesystem {
std::uint64_t partition;
} fs_specific;
- std::uint32_t (*open)(filesystem* fs, void* file_desc, char* path);
-
+ std::int32_t (*remove)(filesystem* fs, char* path);
+ std::int32_t (*open)(filesystem* fs, void* file_desc, char* path, bool is_directory);
+ std::int32_t (*readlink)(filesystem* fs, char* path, char* buffer);
+ std::int32_t (*create)(filesystem* fs, char* path, vfs_file_type type, std::uint32_t mode);
+
char path[2048];
};
@@ -59,27 +235,262 @@ struct file_descriptor {
} fs_specific;
struct {
+ int cycle;
+ int queue;
+ } other;
+
+ struct {
disk* target_disk;
filesystem* fs;
- signed long (*read)(file_descriptor* file, void* buffer, signed long count);
- signed long (*write)(file_descriptor* file, void* buffer, signed long count);
+ std::int32_t (*ioctl)(file_descriptor* file, std::uint64_t req, void* arg);
+ signed long (*read)(file_descriptor* file, void* buffer, std::size_t count);
+ signed long (*write)(file_descriptor* file, void* buffer, std::size_t count);
std::int32_t (*stat)(file_descriptor* file, stat* out);
void (*close)(file_descriptor* file);
+
+ signed long (*ls)(file_descriptor* file, char* out, std::size_t count);
+ bool (*poll)(file_descriptor* file, vfs_poll_type type);
+
} vnode;
};
namespace vfs {
+ struct node {
+ filesystem* fs;
+ char path[2048];
+ };
+
void init();
- std::int32_t open(file_descriptor* fd, char* path, bool follow_symlinks);
- std::int32_t create(char* path, std::uint32_t mode); // mode contains type too
+ std::int32_t open(file_descriptor* fd, char* path, bool follow_symlinks, bool is_directory);
+ std::int32_t create(char* path, vfs_file_type type, std::uint32_t mode);
std::int32_t readlink(char* path, char* out, std::uint32_t out_len);
+ std::int32_t remove(char* path);
}
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+#define NCCS 19
+
+typedef struct {
+ tcflag_t c_iflag;
+ tcflag_t c_oflag;
+ tcflag_t c_cflag;
+ tcflag_t c_lflag;
+ cc_t c_line;
+ cc_t c_cc[NCCS];
+ speed_t ibaud;
+ speed_t obaud;
+} __attribute__((packed)) termios_t;
+
+typedef struct {
+ tcflag_t c_iflag;
+ tcflag_t c_oflag;
+ tcflag_t c_cflag;
+ tcflag_t c_lflag;
+ cc_t c_line;
+ cc_t c_cc[NCCS];
+} __attribute__((packed)) termiosold_t;
+
+#define PIPE_SIDE_WRITE 1
+#define PIPE_SIDE_READ 2
+
// took from old kernel
namespace vfs {
+
+ class pipe {
+ private:
+
+ std::uint64_t read_ptr = 0;
+
+ std::atomic_flag is_received = ATOMIC_FLAG_INIT;
+ std::atomic_flag is_n_closed = ATOMIC_FLAG_INIT;
+
+
+ int is_was_writed_ever = 0;
+
+ public:
+
+ char* buffer;
+
+ locks::preempt_spinlock lock;
+
+ std::atomic_flag is_closed = ATOMIC_FLAG_INIT;
+
+ std::uint64_t total_size = 0;
+ std::atomic<std::int64_t> size = 0;
+ std::int64_t write_counter = 0;
+ std::int64_t read_counter = 0;
+
+ std::uint32_t connected_to_pipe = 0;
+ std::uint32_t connected_to_pipe_write = 0;
+ std::uint64_t flags = 0;
+
+ std::uint32_t zero_message_count = 0;
+
+ int is_closed_socket = 0;
+
+ void* fd_pass = 0;
+ pipe(std::uint64_t flags) {
+ this->buffer = (char*)(pmm::buddy::alloc(USERSPACE_PIPE_SIZE).phys + etc::hhdm());
+ this->total_size = USERSPACE_PIPE_SIZE;
+ this->size = 0;
+ this->connected_to_pipe = 2; /* syscall which creates pipe should create 2 fds too */
+ this->connected_to_pipe_write = 1;
+ this->flags = flags;
+
+ this->is_closed.clear(std::memory_order_release);
+
+ }
+
+ void close(std::uint8_t side) {
+ bool state = this->lock.lock();
+ this->connected_to_pipe--;
+
+ if(side == PIPE_SIDE_WRITE) {
+ this->connected_to_pipe_write--;
+ if(this->connected_to_pipe_write == 0) {
+ this->is_received.clear();
+ this->is_closed.test_and_set(std::memory_order_acquire);
+ }
+ }
+
+ this->lock.unlock(state);
+
+ if(this->connected_to_pipe == 0) {
+ delete this;
+ }
+ }
+
+ void create(std::uint8_t side) {
+ bool state = this->lock.lock();
+ this->connected_to_pipe++;
+ if(side == PIPE_SIDE_WRITE)
+ this->connected_to_pipe_write++;
+ this->lock.unlock(state);
+ }
+
+ std::uint64_t force_write(const char* src_buffer, std::uint64_t count) {
+ if (this->size + count > this->total_size) {
+ count = this->total_size - this->size;
+ }
+ this->size += count;
+ klibc::memcpy(this->buffer + (this->size - count), src_buffer, count);
+ return count;
+ }
+
+ std::uint64_t write(const char* src_buffer, std::uint64_t count,int id) {
+
+ std::uint64_t written = 0;
+
+ while (written < count) {
+ bool state = this->lock.lock();
+
+ std::uint64_t space_left = this->total_size - this->size;
+ if (space_left == 0) {
+ this->lock.unlock(state);
+ process::yield();
+ continue;
+ }
+
+ uint64_t old_size = this->size;
+
+ std::uint64_t to_write = (count - written) < space_left ? (count - written) : space_left;
+ if(to_write < 0)
+ to_write = 0;
+
+
+ force_write(src_buffer + written, to_write);
+
+ written += to_write;
+
+ this->lock.unlock(state);
+ }
+ return written;
+ }
+
+ std::uint64_t nolock_write(const char* src_buffer, std::uint64_t count,int id) {
+
+ std::uint64_t written = 0;
+
+ if(count == 0) {
+ this->zero_message_count = 1;
+ return 0;
+ }
+
+ while (written < count) {
+
+ std::uint64_t space_left = this->total_size - this->size;
+
+ uint64_t old_size = this->size;
+
+ std::uint64_t to_write = (count - written) < space_left ? (count - written) : space_left;
+ if(to_write < 0)
+ to_write = 0;
+
+
+ force_write(src_buffer + written, to_write);
+
+ written += to_write;
+ this->read_counter++;
+
+ }
+ return written;
+ }
+
+ std::int64_t read(std::int64_t* read_count, char* dest_buffer, std::uint64_t count, int is_block) {
+
+ std::uint64_t read_bytes = 0;
+ int tries = 0;
+
+ while (true) {
+ bool state = this->lock.lock();
+
+ if (this->size == 0) {
+
+ if (this->is_closed.test(std::memory_order_acquire)) {
+ this->lock.unlock(state);
+ return 0;
+ }
+
+ if(this->is_closed_socket) {
+ this->lock.unlock(state);
+ return 0;
+ }
+
+ if (flags & O_NONBLOCK || is_block) {
+ this->lock.unlock(state);
+ return -11;
+ }
+ this->lock.unlock(state);
+ process::yield();
+ continue;
+ }
+
+ read_bytes = (count < (std::uint64_t)this->size) ? count : (std::uint64_t)this->size;
+ klibc::memcpy(dest_buffer, this->buffer, read_bytes);
+ klibc::memmove(this->buffer, this->buffer + read_bytes, this->size - read_bytes);
+ this->size -= read_bytes;
+
+ this->lock.unlock(state);
+ break;
+ }
+ return read_bytes;
+ }
+
+
+
+ ~pipe() {
+ pmm::buddy::free((std::uint64_t)this->buffer - etc::hhdm());
+ }
+
+ };
+
+
static inline std::uint64_t resolve_count(char* str,std::uint64_t sptr,char delim) {
char* current = str;
std::uint16_t att = 0;
diff --git a/kernel/src/klibc/stdio.hpp b/kernel/src/klibc/stdio.hpp
index cce2bcf..71b98e5 100644
--- a/kernel/src/klibc/stdio.hpp
+++ b/kernel/src/klibc/stdio.hpp
@@ -15,4 +15,6 @@ namespace klibc {
}
void printf(const char* fmt, ...);
-}; \ No newline at end of file
+};
+
+#define log(name, msg, ...) klibc::printf("\033[1;31m" name "\033[0m: " msg "\r\n" , ##__VA_ARGS__) \ No newline at end of file
diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp
index 7c9ba13..aedd7a1 100644
--- a/kernel/src/main.cpp
+++ b/kernel/src/main.cpp
@@ -11,6 +11,7 @@
#include <drivers/nvme.hpp>
#include <drivers/powerbutton.hpp>
#include <generic/mp.hpp>
+#include <generic/vfs.hpp>
#if defined(__x86_64__)
#include <arch/x86_64/drivers/pci.hpp>
@@ -23,17 +24,17 @@ extern int is_early;
extern "C" void main() {
utils::cxx::init_constructors();
bootloader::init();
- utils::flanterm::init();
#if defined(__x86_64__)
x86_64::serial::init();
#endif
pmm::init();
paging::init();
kheap::init();
+ utils::flanterm::init();
utils::flanterm::fullinit();
- klibc::printf("PMM: Total usable memory: %lli bytes\r\n",memory_size); // i dont want to forgot these messages
- klibc::printf("Paging: Enabled kernel root with %d level paging\n\r", arch::level_paging());
- klibc::printf("KHeap: Available memory %lli bytes\r\n",KHEAP_SIZE);
+ log("pmm", "total usable memory: %lli bytes", memory_size);
+ log("paging", "enabled kernel root with %d level paging", arch::level_paging());
+ log("kheap", "available memory %lli bytes", KHEAP_SIZE);
acpi::init_tables();
arch::init(ARCH_INIT_EARLY);
acpi::full_init();
@@ -41,11 +42,12 @@ extern "C" void main() {
arch::init(ARCH_INIT_COMMON);
mp::init();
mp::sync();
+ vfs::init();
drivers::powerbutton::init();
drivers::nvme::init();
#if defined(__x86_64__)
x86_64::pci::initworkspace();
- klibc::printf("PCI: launched all drivers\r\n");
+ log("pci", "launched all drivers");
#endif
klibc::printf("Boot is done\r\n");
mp::sync();
diff --git a/kernel/src/utils/bitmap.hpp b/kernel/src/utils/bitmap.hpp
index 0ebbb15..a56fe60 100644
--- a/kernel/src/utils/bitmap.hpp
+++ b/kernel/src/utils/bitmap.hpp
@@ -7,10 +7,10 @@
namespace utils {
class bitmap {
private:
- std::uint8_t* pool;
std::uint32_t pool_size;
-
public:
+ std::uint8_t* pool;
+
bitmap(std::uint32_t size, std::uint8_t* custom_pool = 0) {
if (custom_pool) {
this->pool = custom_pool;
diff --git a/kernel/src/utils/flanterm.cpp b/kernel/src/utils/flanterm.cpp
index 1c46922..c132497 100644
--- a/kernel/src/utils/flanterm.cpp
+++ b/kernel/src/utils/flanterm.cpp
@@ -14,16 +14,12 @@
locks::spinlock flanterm_lock;
flanterm_context* ft_ctx0 = 0;
-int is_disabled_flanterm = 0;
+int is_disabled_flanterm = 1;
std::uint32_t default_fg = 0xEEEEEEEE;
std::uint32_t default_bright_fg = 0xFFFFFFFF;
std::uint32_t default_bg = 0;
-static inline int abs(int x) {
- return x < 0 ? -x : x;
-}
-
extern "C" void* __flanterm_malloc(size_t size) {
return klibc::malloc(size);
}
@@ -33,152 +29,6 @@ extern "C" void __flanterm_free(void* ptr,size_t size) {
klibc::free(ptr);
}
-void scale_image_nn(unsigned char* src, int src_w, int src_h,
- unsigned char* dst, int dst_w, int dst_h, int channels) {
- for (int y = 0; y < dst_h; y++) {
- int src_y = y * src_h / dst_h;
- for (int x = 0; x < dst_w; x++) {
- int src_x = x * src_w / dst_w;
- for (int c = 0; c < channels; c++) {
- dst[(y*dst_w + x)*channels + c] = src[(src_y*src_w + src_x)*channels + c];
- }
- }
- }
-}
-
-uint32_t rgb_to_pixel(uint8_t r, uint8_t g, uint8_t b,
- int r_len, int r_off,
- int g_len, int g_off,
- int b_len, int b_off) {
- uint32_t pixel = 0;
- uint32_t R = (r >> (8 - r_len)) << r_off;
- uint32_t G = (g >> (8 - g_len)) << g_off;
- uint32_t B = (b >> (8 - b_len)) << b_off;
- pixel = R | G | B;
- return pixel;
-}
-
-static uint32_t blend_pixel(uint32_t dst, uint8_t r_src, uint8_t g_src, uint8_t b_src, int alpha_fixed,
- int r_len, int r_off, int g_len, int g_off, int b_len, int b_off) {
- // alpha_fixed в диапазоне 0-256 (где 256 = 1.0)
-
- uint8_t r_dst = (dst >> r_off) & ((1 << r_len) - 1);
- uint8_t g_dst = (dst >> g_off) & ((1 << g_len) - 1);
- uint8_t b_dst = (dst >> b_off) & ((1 << b_len) - 1);
-
- // Расширяем до 8 бит
- r_dst = (r_dst << (8 - r_len)) | (r_dst >> (2 * r_len - 8));
- g_dst = (g_dst << (8 - g_len)) | (g_dst >> (2 * g_len - 8));
- b_dst = (b_dst << (8 - b_len)) | (b_dst >> (2 * b_len - 8));
-
- // Блендинг с фиксированной точкой
- uint8_t r = (uint8_t)((r_src * alpha_fixed + r_dst * (256 - alpha_fixed)) >> 8);
- uint8_t g = (uint8_t)((g_src * alpha_fixed + g_dst * (256 - alpha_fixed)) >> 8);
- uint8_t b = (uint8_t)((b_src * alpha_fixed + b_dst * (256 - alpha_fixed)) >> 8);
-
- uint32_t pixel = 0;
- pixel |= ((r >> (8 - r_len)) << r_off);
- pixel |= ((g >> (8 - g_len)) << g_off);
- pixel |= ((b >> (8 - b_len)) << b_off);
-
- return pixel;
-}
-
-static void draw_transparent_black_square(uint32_t* canvas, int width, int height,
- int r_len, int r_off,
- int g_len, int g_off,
- int b_len, int b_off,
- int margin) {
- int square_w = width - 2 * margin;
- int square_h = height - 2 * margin;
- int start_x = margin;
- int start_y = margin;
-
- int alpha_fixed = 128;
-
- for (int y = start_y; y < start_y + square_h; y++) {
- for (int x = start_x; x < start_x + square_w; x++) {
- int idx = y * width + x;
- canvas[idx] = blend_pixel(canvas[idx], 0, 0, 0, alpha_fixed,
- r_len, r_off, g_len, g_off, b_len, b_off);
- }
- }
-}
-
-#pragma pack(push, 1)
-struct BMPHeader {
- uint16_t signature;
- uint32_t file_size;
- uint32_t reserved;
- uint32_t data_offset;
- uint32_t header_size;
- int32_t width;
- int32_t height;
- uint16_t planes;
- uint16_t bpp;
- uint32_t compression;
- uint32_t image_size;
- int32_t x_pixels_per_meter;
- int32_t y_pixels_per_meter;
- uint32_t colors_used;
- uint32_t important_colors;
-};
-#pragma pack(pop)
-
-static const unsigned char bg_bmp[] = {
- #embed "src/bg.bmp"
-};
-
-static unsigned char* load_bmp_from_memory(const unsigned char* bmp_data, size_t bmp_size,
- int* width, int* height, int* channels) {
- if (bmp_size < sizeof(BMPHeader)) {
- return nullptr;
- }
-
- BMPHeader* header = (BMPHeader*)bmp_data;
-
- if (header->signature != 0x4D42) { // 'BM'
- return nullptr;
- }
-
- if (header->bpp != 24 || header->compression != 0) {
- return nullptr;
- }
-
- *width = abs(header->width);
- *height = abs(header->height);
- *channels = 3;
-
- unsigned char* rgb_data = (unsigned char*)(pmm::buddy::alloc((*width) * (*height) * 3).phys + etc::hhdm());
- if (!rgb_data) {
- return nullptr;
- }
-
- int row_size = ((*width) * 3 + 3) & ~3;
- unsigned char* bmp_pixels = (unsigned char*)(bmp_data + header->data_offset);
-
- for (int y = 0; y < *height; y++) {
- int src_y;
- if (header->height > 0) {
-
- src_y = (*height - 1 - y);
- } else {
-
- src_y = y;
- }
-
- unsigned char* src_row = bmp_pixels + src_y * row_size;
- unsigned char* dst_row = rgb_data + y * (*width) * 3;
-
- for (int x = 0; x < *width; x++) {
- dst_row[x*3 + 0] = src_row[x*3 + 2]; // R
- dst_row[x*3 + 1] = src_row[x*3 + 1]; // G
- dst_row[x*3 + 2] = src_row[x*3 + 0]; // B
- }
- }
-
- return rgb_data;
-}
unsigned char unifont_arr[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x81, 0xa5,
@@ -537,91 +387,49 @@ namespace utils {
return;
}
- struct flanterm_context *ft_ctx = flanterm_fb_init(
- NULL,
- NULL,
- (uint32_t*)fb0->address, fb0->width, fb0->height, fb0->pitch,
- fb0->red_mask_size, fb0->red_mask_shift,
- fb0->green_mask_size, fb0->green_mask_shift,
- fb0->blue_mask_size, fb0->blue_mask_shift,
- NULL,
- NULL, NULL,
- &default_bg, &default_fg,
- NULL, &default_bright_fg,
- (void*)NULL, 0, 0, 0,
- 1, 1, 0, 0
- );
+ struct flanterm_context *ft_ctx;
+ if(bootloader::bootloader->get_flanterm() == nullptr) {
+ ft_ctx = flanterm_fb_init(
+ NULL,
+ NULL,
+ (uint32_t*)fb0->address, fb0->width, fb0->height, fb0->pitch,
+ fb0->red_mask_size, fb0->red_mask_shift,
+ fb0->green_mask_size, fb0->green_mask_shift,
+ fb0->blue_mask_size, fb0->blue_mask_shift,
+ NULL,
+ NULL, NULL,
+ &default_bg, &default_fg,
+ NULL, &default_bright_fg,
+ (void*)NULL, 0, 0, 0,
+ 1, 1, 0, 0
+ );
+ } else {
+
+ limine_flanterm_fb_init_params_response* flan = bootloader::bootloader->get_flanterm();
+
+ ft_ctx = flanterm_fb_init(
+ __flanterm_malloc,
+ __flanterm_free,
+ (uint32_t*)fb0->address, fb0->width, fb0->height, fb0->pitch,
+ fb0->red_mask_size, fb0->red_mask_shift,
+ fb0->green_mask_size, fb0->green_mask_shift,
+ fb0->blue_mask_size, fb0->blue_mask_shift,
+ flan->entries[0]->canvas,
+ flan->entries[0]->ansi_colours, flan->entries[0]->ansi_bright_colours,
+ &flan->entries[0]->default_bg, &flan->entries[0]->default_fg,
+ &flan->entries[0]->default_bg_bright, &flan->entries[0]->default_fg_bright,
+ flan->entries[0]->font, flan->entries[0]->font_width, flan->entries[0]->font_height , flan->entries[0]->font_spacing,
+ flan->entries[0]->font_scale_x, flan->entries[0]->font_scale_y, flan->entries[0]->margin, flan->entries[0]->rotation
+ );
+ }
ft_ctx0 = ft_ctx;
- const char* msg = "flanterm: Found usable framebuffer\r\n";
+ const char* msg = "\033[1;31mflanterm\033[0m: Found usable framebuffer\r\n";
+ is_disabled_flanterm = 0;
flanterm::write(msg,klibc::strlen(msg));
}
void flanterm::fullinit() {
-
- limine_framebuffer* fb0 = bootloader::bootloader->get_framebuffer();
-
- if(fb0 == nullptr) {
- is_disabled_flanterm = 1;
- return;
- }
-
-
- uint32_t* test_canvas = (uint32_t*)(pmm::buddy::alloc(fb0->pitch * fb0->height).phys + etc::hhdm());
- if (!test_canvas) {
- return;
- }
-
- int img_w, img_h, img_channels;
- unsigned char* img_data = load_bmp_from_memory(bg_bmp, sizeof(bg_bmp), &img_w, &img_h, &img_channels);
- if (!img_data) {
- klibc::printf("error in stbi\n\r");
- return;
- }
-
- unsigned char* scaled_rgb = (unsigned char*)(pmm::buddy::alloc(fb0->pitch * fb0->height * 3).phys + etc::hhdm());
- if (!scaled_rgb) {
- return;
- }
-
- scale_image_nn(img_data, img_w, img_h, scaled_rgb, fb0->width, fb0->height, 3);
-
- for (std::size_t y = 0; y < fb0->height; y++) {
- for (std::size_t x = 0; x < fb0->width; x++) {
- int idx = (y * fb0->width + x) * 3;
- uint8_t r = scaled_rgb[idx];
- uint8_t g = scaled_rgb[idx + 1];
- uint8_t b = scaled_rgb[idx + 2];
- test_canvas[y * fb0->width + x] = rgb_to_pixel(r, g, b,
- fb0->red_mask_size, fb0->red_mask_shift,
- fb0->green_mask_size, fb0->green_mask_shift,
- fb0->blue_mask_size, fb0->blue_mask_shift);
- }
- }
-
- int margin = 64;
-
- draw_transparent_black_square(test_canvas, fb0->width, fb0->height,
- fb0->red_mask_size, fb0->red_mask_shift,
- fb0->green_mask_size, fb0->green_mask_shift,
- fb0->blue_mask_size, fb0->blue_mask_shift,
- margin - 1);
-
- flanterm_deinit(ft_ctx0, nullptr);
-
- ft_ctx0 = flanterm_fb_init(
- __flanterm_malloc, __flanterm_free,
- (uint32_t*)fb0->address, fb0->width, fb0->height, fb0->pitch,
- fb0->red_mask_size, fb0->red_mask_shift,
- fb0->green_mask_size, fb0->green_mask_shift,
- fb0->blue_mask_size, fb0->blue_mask_shift,
- test_canvas,
- NULL, NULL,
- NULL, &default_fg,
- NULL, &default_bright_fg,
- (void*)unifont_arr, FONT_WIDTH, FONT_HEIGHT, 0,
- 1, 1, margin,0
- );
-
+ return;
}
void flanterm::write(const char* buffer, std::size_t size) {
diff --git a/kernel/src/utils/ringbuffer.hpp b/kernel/src/utils/ringbuffer.hpp
new file mode 100644
index 0000000..d6f6c2c
--- /dev/null
+++ b/kernel/src/utils/ringbuffer.hpp
@@ -0,0 +1,91 @@
+#pragma once
+
+#include <cstdint>
+#include <klibc/string.hpp>
+#include <generic/lock/spinlock.hpp>
+
+#include <atomic>
+
+namespace utils {
+ template <typename T>
+ struct buffer_obj_t {
+ std::uint32_t cycle;
+ T data;
+ };
+
+ template <typename T>
+ class ring_buffer {
+ private:
+ buffer_obj_t<T>* objs;
+ int tail;
+ int size;
+ int cycle;
+
+ locks::preempt_spinlock lock;
+
+ public:
+ explicit ring_buffer(std::size_t size_elements) {
+ size = static_cast<int>(size_elements);
+ objs = new buffer_obj_t<T>[size];
+ tail = 0;
+ cycle = 1;
+
+ klibc::memset(objs, 0, sizeof(buffer_obj_t<T>) * size);
+ }
+
+ ~ring_buffer() {
+ delete[] objs;
+ }
+
+ ring_buffer(const ring_buffer&) = delete;
+ ring_buffer& operator=(const ring_buffer&) = delete;
+
+ void send(const T& item) {
+ bool state = lock.lock();
+
+ objs[tail].cycle = cycle;
+ objs[tail].data = item;
+
+ write_counter++;
+
+ if (++tail == size) {
+ tail = 0;
+ cycle = !cycle;
+ }
+
+ lock.unlock(state);
+ }
+
+ bool is_not_empty(int reader_queue, int reader_cycle) const {
+ return objs[reader_queue].cycle == (std::uint32_t)reader_cycle;
+ }
+
+ int receive(T* out, int max, int* c_io, int* q_io) {
+ bool state = lock.lock();
+
+ int count = 0;
+ int q = *q_io;
+ int c = *c_io;
+
+ while (count < max && objs[q].cycle == (std::uint32_t)c) {
+ out[count] = objs[q].data;
+ read_counter++;
+
+ if (++q == size) {
+ q = 0;
+ c = !c;
+ }
+ count += sizeof(T);
+ }
+
+ *q_io = q;
+ *c_io = c;
+
+ lock.unlock(state);
+ return count;
+ }
+
+ std::uint64_t get_write_count() const { return write_counter; }
+ };
+
+} \ No newline at end of file
diff --git a/limine.conf b/limine.conf
index 4fc44ff..7d69f1a 100644
--- a/limine.conf
+++ b/limine.conf
@@ -1,5 +1,7 @@
# Timeout in seconds that Limine will use before automatically booting.
timeout: 2
+term_foreground: EEEEEEEE
+term_background: 000011
# The entry name that will be displayed in the boot menu.
/Orange
@@ -8,3 +10,4 @@ timeout: 2
# Path to the kernel to boot. boot():/ represents the partition on which limine.conf is located.
path: boot():/boot/kernel
+