diff options
| author | cpplover0 <osdev555@yandex.com> | 2025-11-11 07:22:26 +0300 |
|---|---|---|
| committer | cpplover0 <osdev555@yandex.com> | 2025-11-11 07:22:26 +0300 |
| commit | 165c5f2dbdb2a348266d0cc8ee20ced4d9fb1bdb (patch) | |
| tree | e28a60e439c315a535940027f929d601687f0e4a | |
| parent | 87e973d53cd59e5d578f594fd23fa6ee446c4aa3 (diff) | |
twm st port a lot of bug fixes and finally working xorg port
52 files changed, 1829 insertions, 594 deletions
@@ -2,6 +2,7 @@ build orange
orange.iso
obj
+serial.txt
trash
.code
serial_output.txt
diff --git a/GNUmakefile b/GNUmakefile index 11af968..c733a82 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -3,7 +3,7 @@ MAKEFLAGS += -rR .SUFFIXES: # Default user QEMU flags. These are appended to the QEMU command calls. -QEMUFLAGS := -m 16G -serial stdio -d int -no-reboot -s -M q35 -smp 1 -enable-kvm -device qemu-xhci -device usb-kbd -device usb-ehci +QEMUFLAGS := -m 4G -d int -no-reboot -s -M q35 -smp 1 -enable-kvm -serial stdio -device qemu-xhci -device usb-kbd -device usb-mouse override IMAGE_NAME := orange diff --git a/kernel/include/arch/x86_64/cpu/data.hpp b/kernel/include/arch/x86_64/cpu/data.hpp index e796d25..3dde7a8 100644 --- a/kernel/include/arch/x86_64/cpu/data.hpp +++ b/kernel/include/arch/x86_64/cpu/data.hpp @@ -13,6 +13,7 @@ typedef struct { std::uint64_t user_stack; std::uint64_t kernel_stack; std::uint64_t timer_ist_stack; + int last_sys; struct { std::uint16_t cpu_id; } smp; diff --git a/kernel/include/arch/x86_64/interrupts/irq.hpp b/kernel/include/arch/x86_64/interrupts/irq.hpp index d7d8c63..4003184 100644 --- a/kernel/include/arch/x86_64/interrupts/irq.hpp +++ b/kernel/include/arch/x86_64/interrupts/irq.hpp @@ -11,6 +11,7 @@ typedef struct { void (*func)(void* arg); void* arg; + int irq; char is_userspace; } irq_t; diff --git a/kernel/include/arch/x86_64/scheduling.hpp b/kernel/include/arch/x86_64/scheduling.hpp index 4650796..250cabd 100644 --- a/kernel/include/arch/x86_64/scheduling.hpp +++ b/kernel/include/arch/x86_64/scheduling.hpp @@ -148,6 +148,8 @@ namespace arch { char* cwd; char* name; + int sys; + int exit_code; int is_cloned; std::uint64_t* original_cr3_pointer; diff --git a/kernel/include/arch/x86_64/syscalls/syscalls.hpp b/kernel/include/arch/x86_64/syscalls/syscalls.hpp index 5788bab..03821ed 100644 --- a/kernel/include/arch/x86_64/syscalls/syscalls.hpp +++ b/kernel/include/arch/x86_64/syscalls/syscalls.hpp @@ -218,6 +218,8 @@ syscall_ret_t sys_link(char* old_path, char* new_path); syscall_ret_t sys_mkdirat(int dirfd, char* path, int mode); syscall_ret_t sys_chmod(char* path, int mode); +syscall_ret_t sys_ttyname(int fd, char *buf, size_t size); + /* Process */ syscall_ret_t sys_mmap(std::uint64_t hint, std::uint64_t size, int fd0, int_frame_t* ctx); syscall_ret_t sys_free(void *pointer, size_t size); @@ -255,6 +257,7 @@ syscall_ret_t sys_mkfifoat(int dirfd, const char *path, int mode); syscall_ret_t sys_enabledebugmode(); syscall_ret_t sys_clone(std::uint64_t stack, std::uint64_t rip, int c, int_frame_t* ctx); +syscall_ret_t sys_breakpoint(int num); /* Futex */ syscall_ret_t sys_futex_wait(int* pointer, int excepted); diff --git a/kernel/include/etc/list.hpp b/kernel/include/etc/list.hpp index d19c0b9..0169721 100644 --- a/kernel/include/etc/list.hpp +++ b/kernel/include/etc/list.hpp @@ -161,6 +161,20 @@ namespace Lists { return len; } + int isnotempty(int* queue0, char* cycle0) { + char cycle = *cycle0; + int queue = *queue0; + while (ring.objs[queue].cycle == cycle) { + return 1; + queue = queue + 1; + if (queue == ring.size) { + queue = 0; + cycle = !(cycle); + } + } + return 0; + } + int receivevals(void* out, int id, int max, std::uint8_t* cycle, std::uint32_t* queue) { ring_lock.lock(); int len = 0; diff --git a/kernel/include/generic/mm/pmm.hpp b/kernel/include/generic/mm/pmm.hpp index 3f35db6..03cd5bc 100644 --- a/kernel/include/generic/mm/pmm.hpp +++ b/kernel/include/generic/mm/pmm.hpp @@ -10,15 +10,16 @@ typedef struct buddy_info { union { struct { - std::uint64_t level : 8; - std::uint64_t is_was_splitted : 1; - std::uint64_t is_splitted : 1; - std::uint64_t is_free : 1; - std::uint64_t split_x : 1; - std::uint64_t parent_id : 48; + std::uint16_t level : 8; + std::uint16_t is_was_splitted : 1; + std::uint16_t is_splitted : 1; + std::uint16_t is_free : 1; + std::uint16_t split_x : 1; }; - std::uint64_t buddy_info_raw; + std::uint16_t buddy_info_raw; }; + struct buddy_info* parent; + struct buddy_info* twin; std::uint32_t id; std::uint64_t phys; } __attribute__((packed)) buddy_info_t; @@ -46,7 +47,7 @@ namespace memory { static buddy_info_t* split_maximum(buddy_info_t* blud, std::uint64_t size); static buddy_info_t* put(std::uint64_t phys, std::uint8_t level); static buddy_split_t split(buddy_info_t* info); - static void merge(uint64_t parent_id); + static void merge(buddy_info_t* budy); public: static void init(); static void free(std::uint64_t phys); diff --git a/kernel/include/generic/mm/vmm.hpp b/kernel/include/generic/mm/vmm.hpp index 3170cb7..07dbfb7 100644 --- a/kernel/include/generic/mm/vmm.hpp +++ b/kernel/include/generic/mm/vmm.hpp @@ -25,6 +25,7 @@ typedef struct vmm_obj { uint8_t is_mapped; int* how_much_connected; // used for sharedmem + locks::spinlock lock; uint64_t src_len; @@ -127,11 +128,12 @@ namespace memory { inline static void* map(arch::x86_64::process_t* proc, std::uint64_t base, std::uint64_t length, std::uint64_t flags) { vmm_obj_t* current = (vmm_obj_t*)proc->vmm_start; + current->lock.lock(); while(current) { - if(current->phys == base) - return (void*)current->base; // Just return + if(current->phys == base) { ((vmm_obj_t*)proc->vmm_start)->lock.unlock(); + return (void*)current->base; } if(current->base == (std::uint64_t)Other::toVirt(0) - 4096) break; @@ -146,6 +148,7 @@ namespace memory { new_vmm->src_len = length; new_vmm->is_mapped = 1; paging::maprangeid(proc->original_cr3,base,new_vmm->base,length,flags,*proc->vmm_id); + ((vmm_obj_t*)proc->vmm_start)->lock.unlock(); return (void*)new_vmm->base; } @@ -164,25 +167,30 @@ namespace memory { inline static vmm_obj_t* get(arch::x86_64::process_t* proc, std::uint64_t base) { vmm_obj_t* current = (vmm_obj_t*)proc->vmm_start; + current->lock.lock(); while(current) { - if(current->base == base) - return current; + if(current->base == base) { ((vmm_obj_t*)proc->vmm_start)->lock.unlock(); + return current; } if(current->base == (std::uint64_t)Other::toVirt(0) - 4096) break; current = current->next; } + ((vmm_obj_t*)proc->vmm_start)->lock.unlock(); + return 0; } inline static vmm_obj_t* getlen(arch::x86_64::process_t* proc, std::uint64_t addr) { vmm_obj_t* current = (vmm_obj_t*)proc->vmm_start; + current->lock.lock(); while (current) { if (addr >= current->base && addr < current->base + current->len) { + ((vmm_obj_t*)proc->vmm_start)->lock.unlock(); return current; } @@ -191,11 +199,13 @@ namespace memory { current = current->next; } - + ((vmm_obj_t*)proc->vmm_start)->lock.unlock(); return 0; } inline static void clone(arch::x86_64::process_t* dest_proc, arch::x86_64::process_t* src_proc) { + vmm_obj_t* current = (vmm_obj_t*)src_proc->vmm_start; + current->lock.lock(); if(dest_proc && src_proc) { vmm_obj_t* src_current = (vmm_obj_t*)src_proc->vmm_start; @@ -233,6 +243,7 @@ namespace memory { } } + ((vmm_obj_t*)src_proc->vmm_start)->lock.unlock(); } inline static void reload(arch::x86_64::process_t* proc) { @@ -280,6 +291,7 @@ namespace memory { inline static void free(arch::x86_64::process_t* proc) { vmm_obj_t* current = (vmm_obj_t*)proc->vmm_start; + current->lock.lock(); if(!current) return; @@ -323,6 +335,7 @@ namespace memory { inline static void* alloc(arch::x86_64::process_t* proc, std::uint64_t len, std::uint64_t flags, int is_shared) { vmm_obj_t* current = (vmm_obj_t*)proc->vmm_start; + current->lock.lock(); vmm_obj_t* new_vmm = v_alloc(current,len); new_vmm->flags = flags; new_vmm->src_len = len; @@ -336,21 +349,25 @@ namespace memory { } paging::maprangeid(proc->original_cr3,new_vmm->phys,new_vmm->base,new_vmm->len,flags,*proc->vmm_id); + ((vmm_obj_t*)proc->vmm_start)->lock.unlock(); return (void*)new_vmm->base; } inline static void* customalloc(arch::x86_64::process_t* proc, std::uint64_t virt, std::uint64_t len, std::uint64_t flags, int is_shared) { vmm_obj_t* current = (vmm_obj_t*)proc->vmm_start; + current->lock.lock(); std::uint64_t phys = memory::pmm::_physical::alloc(len); void* new_virt = mark(proc,virt,phys,len,flags,is_shared); paging::maprangeid(proc->original_cr3,phys,(std::uint64_t)virt,len,flags,*proc->vmm_id); - + current->lock.unlock(); vmm_obj_t* new_vmm = get(proc,virt); if(is_shared) { new_vmm->is_shared = 1; new_vmm->how_much_connected = new int; } + ((vmm_obj_t*)proc->vmm_start)->lock.unlock(); + return (void*)virt; } diff --git a/kernel/include/generic/vfs/devfs.hpp b/kernel/include/generic/vfs/devfs.hpp index 4128f3e..b59513e 100644 --- a/kernel/include/generic/vfs/devfs.hpp +++ b/kernel/include/generic/vfs/devfs.hpp @@ -35,26 +35,6 @@ struct winsize { #define TIOCGWINSZ 0x5413 #define TIOCSWINSZ 0x5414 -typedef unsigned char cc_t; -typedef unsigned int speed_t; -typedef unsigned int tcflag_t; - -#define NCCS 32 - -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; - -#define ICANON 0000002 -#define VMIN 6 - namespace vfs { typedef struct { @@ -131,6 +111,9 @@ namespace vfs { std::int32_t (*ioctl)(userspace_fd_t* fd, unsigned long req, void *arg, int *res); std::int32_t (*open)(userspace_fd_t* fd, char* path); + int mode; + + termios_t* term_flags; struct devfs_node* next; char masterpath[256]; diff --git a/kernel/include/generic/vfs/fd.hpp b/kernel/include/generic/vfs/fd.hpp index 255bd0d..9717a23 100644 --- a/kernel/include/generic/vfs/fd.hpp +++ b/kernel/include/generic/vfs/fd.hpp @@ -13,7 +13,7 @@ namespace vfs { inline static int create(arch::x86_64::process_t* proc) { userspace_fd_t* current = proc->fd; while(current) { - if(current->state == USERSPACE_FD_STATE_UNUSED) + if(current->state == USERSPACE_FD_STATE_UNUSED && current->index > 2) break; current = current->next; } @@ -38,6 +38,27 @@ namespace vfs { } + inline static userspace_fd_t* searchlowest(arch::x86_64::process_t* proc,std::uint32_t idx) { + + if(!proc) + return 0; + + userspace_fd_t* current = proc->fd; + userspace_fd_t* lowest = 0; + + while(current) { + if(current->state == USERSPACE_FD_STATE_UNUSED || current->can_be_closed) { + if(!lowest) + lowest = current; + if(current->index < lowest->index) + lowest = current; + } + current = current->next; + } + + return lowest; + } + inline static userspace_fd_t* search(arch::x86_64::process_t* proc,std::uint32_t idx) { if(!proc) diff --git a/kernel/include/generic/vfs/vfs.hpp b/kernel/include/generic/vfs/vfs.hpp index e888aca..3c61394 100644 --- a/kernel/include/generic/vfs/vfs.hpp +++ b/kernel/include/generic/vfs/vfs.hpp @@ -24,6 +24,22 @@ #define VFS_TYPE_DIRECTORY 2 #define VFS_TYPE_SYMLINK 3 +#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 @@ -105,16 +121,33 @@ #define PIPE_SIDE_WRITE 1 #define PIPE_SIDE_READ 2 + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned int tcflag_t; + +#define NCCS 32 + +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; + void __vfs_symlink_resolve(char* path, char* out); namespace vfs { class pipe { private: - char* buffer; - std::uint64_t total_size = 0; + std::uint64_t read_ptr = 0; - locks::spinlock lock; + std::atomic_flag is_received = ATOMIC_FLAG_INIT; std::atomic_flag is_n_closed = ATOMIC_FLAG_INIT; std::atomic_flag is_closed = ATOMIC_FLAG_INIT; @@ -123,14 +156,22 @@ namespace vfs { public: + char* buffer; + + locks::spinlock lock; + + std::uint64_t total_size = 0; std::int64_t size = 0; - std::uint64_t write_counter = 0; - std::uint64_t read_counter = 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; + int tty_ret = 0; + termios_t* ttyflags = 0; + pipe(std::uint64_t flags) { this->buffer = (char*)memory::pmm::_virtual::alloc(USERSPACE_PIPE_SIZE); this->total_size = USERSPACE_PIPE_SIZE; @@ -143,19 +184,19 @@ namespace vfs { } + void set_tty_ret() { + tty_ret = 1; + } + void fifoclose() { - asm volatile("sti"); this->lock.lock(); this->is_received.clear(); this->is_closed.test_and_set(); this->lock.unlock(); - asm volatile("cli"); } void close(std::uint8_t side) { - asm volatile("sti"); this->lock.lock(); - asm volatile("cli"); this->connected_to_pipe--; if(side == PIPE_SIDE_WRITE) { @@ -167,7 +208,6 @@ namespace vfs { } this->lock.unlock(); - asm volatile("cli"); if(this->connected_to_pipe == 0) { delete this; @@ -175,9 +215,7 @@ namespace vfs { } void create(std::uint8_t side) { - asm volatile("sti"); this->lock.lock(); - asm volatile("cli"); this->connected_to_pipe++; if(side == PIPE_SIDE_WRITE) this->connected_to_pipe_write++; @@ -196,37 +234,43 @@ namespace vfs { std::uint64_t write(const char* src_buffer, std::uint64_t count) { std::uint64_t written = 0; while (written < count) { + asm volatile("cli"); this->lock.lock(); std::uint64_t space_left = this->total_size - this->size; if (space_left == 0) { this->lock.unlock(); + asm volatile("sti"); asm volatile("pause"); continue; } - asm volatile("cli"); + 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++; - asm volatile("sti"); - this->lock.unlock(); + asm volatile("sti"); asm volatile("pause"); } return written; } - std::uint64_t read(char* dest_buffer, std::uint64_t count) { + std::uint64_t read(std::int64_t* read_count, char* dest_buffer, std::uint64_t count, int is_block) { std::uint64_t read_bytes = 0; + while (true) { - this->lock.lock(); asm volatile("cli"); + this->lock.lock(); if (this->size == 0) { if (this->is_closed.test(std::memory_order_acquire)) { @@ -234,29 +278,59 @@ namespace vfs { asm volatile("sti"); return 0; } - if (flags & O_NONBLOCK) { + if (flags & O_NONBLOCK || is_block) { this->lock.unlock(); asm volatile("sti"); return 0; } + if(ttyflags) { + if(!(ttyflags->c_lflag & ICANON) && ttyflags->c_cc[VMIN] == 0) { + this->lock.unlock(); + asm volatile("sti"); + return 0; + } + } this->lock.unlock(); asm volatile("sti"); asm volatile("pause"); continue; } + if(ttyflags) { + if(!(ttyflags->c_lflag & ICANON)) { + if(this->size < ttyflags->c_cc[VMIN]) { + this->lock.unlock(); + return 0; + } + } + } + + if(ttyflags) { + if(ttyflags->c_lflag & ICANON) { + if(!tty_ret) { + this->lock.unlock(); + asm volatile("sti"); + asm volatile("pause"); + continue; + } + } + } read_bytes = (count < this->size) ? count : this->size; memcpy(dest_buffer, this->buffer, read_bytes); memmove(this->buffer, this->buffer + read_bytes, this->size - read_bytes); this->size -= read_bytes; - if(this->size == 0) { - this->write_counter++; + this->write_counter++; + + if(this->size <= 0) { + *read_count = read_counter; + tty_ret = 0; } else this->read_counter++; - asm volatile("sti"); + + this->lock.unlock(); break; } @@ -264,6 +338,7 @@ namespace vfs { } + ~pipe() { memory::pmm::_virtual::free(this->buffer); } diff --git a/kernel/src/arch/x86_64/cpu/smp.cpp b/kernel/src/arch/x86_64/cpu/smp.cpp index 3316396..1955796 100644 --- a/kernel/src/arch/x86_64/cpu/smp.cpp +++ b/kernel/src/arch/x86_64/cpu/smp.cpp @@ -57,7 +57,7 @@ void __mp_bootstrap(struct LIMINE_MP(info)* smp_info) { arch::x86_64::cpu::data()->smp.cpu_id = balance_how_much_cpus++; - arch::x86_64::cpu::lapic::init(5000); + arch::x86_64::cpu::lapic::init(100); arch::x86_64::cpu::sse::init(); arch::x86_64::syscall::init(); Log::Display(LEVEL_MESSAGE_OK,"Cpu %d is online \n",arch::x86_64::cpu::data()->smp.cpu_id); diff --git a/kernel/src/arch/x86_64/interrupts/irq.cpp b/kernel/src/arch/x86_64/interrupts/irq.cpp index 1704de4..9cb2d26 100644 --- a/kernel/src/arch/x86_64/interrupts/irq.cpp +++ b/kernel/src/arch/x86_64/interrupts/irq.cpp @@ -22,14 +22,22 @@ extern "C" void* irqTable[]; extern "C" void irqHandler(int_frame_t* ctx) { memory::paging::enablekernel(); - if(!irq_table[ctx->vec - 1].is_userspace) irq_table[ctx->vec - 1].func(irq_table[ctx->vec - 1].arg); else { - drivers::ioapic::mask(ctx->vec - 1); /* Mask */ + + if(irq_table[ctx->vec - 1].irq == 1) { // irq 12 and irq 1 are connected together + drivers::ioapic::mask(12); + } else if(irq_table[ctx->vec - 1].irq == 12) { + drivers::ioapic::mask(1); + } else + drivers::ioapic::mask(irq_table[ctx->vec - 1].irq); /* Mask */ + userspace_fd_t fd; + fd.is_cached_path = 0; memset(fd.path,0,sizeof(fd.path)); - __printfbuf(fd.path,sizeof(fd.path),"/dev/masterirq%d",ctx->vec - 1); + __printfbuf(fd.path,sizeof(fd.path),"/dev/masterirq%d",irq_table[ctx->vec - 1].irq); + char i = 1; int status = vfs::vfs::write(&fd,&i,1); } @@ -68,11 +76,13 @@ std::uint8_t arch::x86_64::interrupts::irq::create(std::uint16_t irq,std::uint8_ } else { arch::x86_64::interrupts::idt::set_entry((std::uint64_t)irqTable[irq],irq + 0x20,0x8E,3); irq_table[irq].arg = arg; + irq_table[irq].func = func; return irq + 0x20; } irq_table[irq_ptr].arg = arg; + irq_table[irq_ptr].irq = irq; irq_table[irq_ptr++].func = func; return entry; }
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/interrupts/panic.cpp b/kernel/src/arch/x86_64/interrupts/panic.cpp index 65e71eb..bb06232 100644 --- a/kernel/src/arch/x86_64/interrupts/panic.cpp +++ b/kernel/src/arch/x86_64/interrupts/panic.cpp @@ -7,6 +7,7 @@ #include <generic/locks/spinlock.hpp> #include <etc/bootloaderinfo.hpp> +#include <generic/mm/vmm.hpp> #include <arch/x86_64/scheduling.hpp> @@ -27,7 +28,8 @@ void panic(int_frame_t* ctx, const char* msg) { if(proc) { uint64_t cr2; asm volatile("mov %%cr2, %0" : "=r"(cr2) : : "memory"); - Log::SerialDisplay(LEVEL_MESSAGE_FAIL,"process %d fired cpu exception with vec %d, rip 0x%p, cr2 0x%p, error code 0x%p\n",proc->id,ctx->vec,ctx->rip,cr2,ctx->err_code); + vmm_obj_t* obj = memory::vmm::getlen(proc,ctx->rip); + Log::SerialDisplay(LEVEL_MESSAGE_FAIL,"process %d fired cpu exception with vec %d, rip 0x%p (offset 0x%p), cr2 0x%p, error code 0x%p, lastsys %d, rdx 0x%p\n",proc->id,ctx->vec,ctx->rip,ctx->rip - 0x41400000,cr2,ctx->err_code,proc->sys,ctx->rdx); arch::x86_64::scheduling::kill(proc); schedulingSchedule(0); } diff --git a/kernel/src/arch/x86_64/scheduling.cpp b/kernel/src/arch/x86_64/scheduling.cpp index 0397353..7d8f796 100644 --- a/kernel/src/arch/x86_64/scheduling.cpp +++ b/kernel/src/arch/x86_64/scheduling.cpp @@ -193,6 +193,7 @@ int arch::x86_64::scheduling::loadelf(process_t* proc,char* path,char** argv,cha zeromem(&stat); memcpy(fd.path,path,strlen(path)); + memcpy(proc->name,path,strlen(path)); int status = vfs::vfs::stat(&fd,&stat); if(status) { @@ -401,24 +402,37 @@ arch::x86_64::process_t* arch::x86_64::scheduling::create() { return proc; } +locks::spinlock futex_lock; + void arch::x86_64::scheduling::futexwake(process_t* proc, int* lock) { process_t* proc0 = head_proc; + futex_lock.lock(); while(proc0) { - if((proc0->parent_id == proc->id || proc->parent_id == proc0->id) && proc0->futex == (std::uint64_t)lock) { - proc0->futex = 0; - proc0->futex_lock.unlock(); - DEBUG(proc->is_debug,"Process which we can wakeup is %d",proc0->id); + if((proc0->parent_id == proc->id || proc->parent_id == proc0->id)) { + if(!proc0->futex) { + proc0->futex = (std::uint64_t)lock; // now when proc doing wait() it can check and just ignore it + } else { + proc0->futex = 0; + proc0->futex_lock.unlock(); + } + + //DEBUG(proc->is_debug,"Process which we can wakeup is %d",proc0->id); } proc0 = proc0->next; } + futex_lock.unlock(); } void arch::x86_64::scheduling::futexwait(process_t* proc, int* lock, int val, int* original_lock) { + + futex_lock.lock(); int lock_val = *lock; - if(lock_val == val) { + if(lock_val == val && proc->futex == 0) { proc->futex_lock.lock(); proc->futex = (std::uint64_t)original_lock; - } + } else if(proc->futex == (std::uint64_t)lock) + proc->futex = 0; + futex_lock.unlock(); } int l = 0; diff --git a/kernel/src/arch/x86_64/syscalls/file.cpp b/kernel/src/arch/x86_64/syscalls/file.cpp index 954ad9b..05db1cf 100644 --- a/kernel/src/arch/x86_64/syscalls/file.cpp +++ b/kernel/src/arch/x86_64/syscalls/file.cpp @@ -45,7 +45,7 @@ syscall_ret_t sys_openat(int dirfd, const char* path, int flags, int_frame_t* ct memset(result,0,2048); vfs::resolve_path(kpath,first_path,result,1,0); - //DEBUG(proc->is_debug,"Trying to open %s from proc %d",result,proc->id); + DEBUG(proc->is_debug,"Trying to open %s from proc %d",result,proc->id); if(result[0] == '\0') { result[0] = '/'; @@ -106,28 +106,33 @@ syscall_ret_t sys_read(int fd, void *buf, size_t count) { if(!fd_s) return {1,EBADF,0}; + if(fd_s->can_be_closed) + fd_s->can_be_closed = 0; + vmm_obj_t* vmm_object = memory::vmm::getlen(proc,(std::uint64_t)buf); uint64_t need_phys = vmm_object->phys + ((std::uint64_t)buf - vmm_object->base); char* temp_buffer = (char*)Other::toVirt(need_phys); memset(temp_buffer,0,count); + //DEBUG(proc->is_debug,"Trying to read %s (fd %d) with state %d from proc %d",fd_s->path,fd,fd_s->state,proc->id); + std::int64_t bytes_read; if(fd_s->state == USERSPACE_FD_STATE_FILE) bytes_read = vfs::vfs::read(fd_s,temp_buffer,count); else if(fd_s->state == USERSPACE_FD_STATE_PIPE && fd_s->pipe) { - bytes_read = fd_s->pipe->read(temp_buffer,count); + bytes_read = fd_s->pipe->read(&fd_s->read_counter,temp_buffer,count,0); } else if(fd_s->state == USERSPACE_FD_STATE_SOCKET) { if(!fd_s->write_socket_pipe || !fd_s->read_socket_pipe) return {1,EFAULT,0}; - DEBUG(proc->is_debug,"reading socket %d, buf 0x%p, count %d (target_size: %d)",fd,buf,count,fd_s->other_state == USERSPACE_FD_OTHERSTATE_MASTER ? fd_s->write_socket_pipe->size : fd_s->read_socket_pipe->size); - + //DEBUG(proc->is_debug,"reading socket %d from proc %d",fd,proc->id); + if(fd_s->other_state == USERSPACE_FD_OTHERSTATE_MASTER) { - bytes_read = fd_s->write_socket_pipe->read(temp_buffer,count); + bytes_read = fd_s->write_socket_pipe->read(&fd_s->read_counter,temp_buffer,count,0); } else { - bytes_read = fd_s->read_socket_pipe->read(temp_buffer,count); + bytes_read = fd_s->read_socket_pipe->read(&fd_s->read_counter,temp_buffer,count,0); } if(bytes_read == 0) @@ -147,6 +152,9 @@ syscall_ret_t sys_write(int fd, const void *buf, size_t count) { if(!fd_s) return {1,EBADF,0}; + if(fd_s->can_be_closed) + fd_s->can_be_closed = 0; + vmm_obj_t* vmm_object = memory::vmm::getlen(proc,(std::uint64_t)buf); uint64_t need_phys = vmm_object->phys + ((std::uint64_t)buf - vmm_object->base); @@ -154,32 +162,22 @@ syscall_ret_t sys_write(int fd, const void *buf, size_t count) { const char* _0 = "Content view is disabled in files"; - //DEBUG(proc->is_debug,"Writing to %s (fd %d) from proc %d with content \"%s\"",fd_s->path,fd,proc->id,temp_buffer,fd_s->state != USERSPACE_FD_STATE_FILE ? temp_buffer : _0); - std::int64_t bytes_written; if(fd_s->state == USERSPACE_FD_STATE_FILE) bytes_written = vfs::vfs::write(fd_s,temp_buffer,count); else if(fd_s->state == USERSPACE_FD_STATE_PIPE) { - SYSCALL_ENABLE_PREEMPT(); bytes_written = fd_s->pipe->write(temp_buffer,count); - SYSCALL_DISABLE_PREEMPT(); } else if(fd_s->state == USERSPACE_FD_STATE_SOCKET) { if(!fd_s->write_socket_pipe || !fd_s->read_socket_pipe) return {1,EFAULT,0}; - - DEBUG(proc->is_debug,"Writing to socket %d from proc %d other_state: %d, buf: 0x%p, count: %d",fd,proc->id,fd_s->other_state,buf,count); - - + + //DEBUG(proc->is_debug,"writing socket %d from proc %d",fd,proc->id); if(fd_s->other_state == USERSPACE_FD_OTHERSTATE_MASTER) { - SYSCALL_ENABLE_PREEMPT(); bytes_written = fd_s->read_socket_pipe->write(temp_buffer,count); - SYSCALL_DISABLE_PREEMPT(); } else { - SYSCALL_ENABLE_PREEMPT(); bytes_written = fd_s->write_socket_pipe->write(temp_buffer,count); - SYSCALL_DISABLE_PREEMPT(); } if(bytes_written == 0) @@ -323,8 +321,14 @@ syscall_ret_t sys_dup(int fd, int flags) { if(!fd_s) return {0,EBADF,0}; - int new_fd = vfs::fdmanager::create(proc); - userspace_fd_t* nfd_s = vfs::fdmanager::search(proc,new_fd); + userspace_fd_t* nfd_s = vfs::fdmanager::searchlowest(proc,0); + + if(!nfd_s) { + int new_fd = vfs::fdmanager::create(proc); + nfd_s = vfs::fdmanager::search(proc,new_fd); + } + + DEBUG(proc->is_debug,"dup from %d to %d",fd,nfd_s->index); nfd_s->cycle = fd_s->cycle; nfd_s->offset = fd_s->offset; @@ -336,7 +340,7 @@ syscall_ret_t sys_dup(int fd, int flags) { nfd_s->is_a_tty = fd_s->is_a_tty; nfd_s->read_counter = fd_s->read_counter; nfd_s->write_counter = fd_s->write_counter; - nfd_s->can_be_closed = fd_s->can_be_closed; + nfd_s->can_be_closed = 0; nfd_s->write_socket_pipe = fd_s->write_socket_pipe; nfd_s->read_socket_pipe = fd_s->read_socket_pipe; @@ -345,7 +349,7 @@ syscall_ret_t sys_dup(int fd, int flags) { if(nfd_s->state ==USERSPACE_FD_STATE_PIPE) nfd_s->pipe->create(nfd_s->pipe_side); - return {1,0,new_fd}; + return {1,0,nfd_s->index}; } syscall_ret_t sys_dup2(int fd, int flags, int newfd) { @@ -427,6 +431,7 @@ syscall_ret_t sys_ioctl(int fd, unsigned long request, void *arg) { copy_in_userspace(proc,ioctl_item,arg,ioctl_size); std::int64_t ret = vfs::vfs::ioctl(fd_s,request,ioctl_item,&res); + copy_in_userspace(proc,arg,ioctl_item,ioctl_size); return {0,(int)ret,0}; @@ -481,6 +486,8 @@ syscall_ret_t sys_isatty(int fd) { int ret = vfs::vfs::var(fd_s,0,DEVFS_VAR_ISATTY); + DEBUG(proc->is_debug,"sys_isatty %s fd %d ret %d",fd_s->path,fd,ret); + fd_s->is_a_tty = ret == 0 ? 1 : 0; return {0,ret != 0 ? ENOTTY : 0,0}; @@ -529,6 +536,7 @@ syscall_ret_t sys_ptsname(int fd, void* out, int max_size) { memset(buffer2,0,256); __printfbuf(buffer2,256,"/dev%s",buffer); + zero_in_userspace(proc,out,max_size); copy_in_userspace(proc,out,buffer2,strlen(buffer2)); return {0,0,0}; @@ -570,6 +578,7 @@ syscall_ret_t sys_read_dir(int fd, void* buffer) { syscall_ret_t sys_fcntl(int fd, int request, std::uint64_t arg) { + arch::x86_64::process_t* pproc = CURRENT_PROC; switch(request) { case F_DUPFD: { return sys_dup(fd,arg); @@ -587,14 +596,13 @@ syscall_ret_t sys_fcntl(int fd, int request, std::uint64_t arg) { case F_SETFL: { arch::x86_64::process_t* proc = CURRENT_PROC; userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); + if(!fd_s) return {0,EBADF,0}; fd_s->flags &= ~(O_APPEND | O_ASYNC | O_NONBLOCK); fd_s->flags |= (arg & (O_APPEND | O_ASYNC | O_NONBLOCK)); - DEBUG(proc->is_debug,"Fcntl fd %d O_NONBLOCK %d from proc %d",fd,(fd_s->flags & O_NONBLOCK) ? 1 : 0,proc->id); - if(fd_s->state == USERSPACE_FD_STATE_PIPE) { fd_s->pipe->flags & ~(O_NONBLOCK); fd_s->pipe->flags |= (arg & O_NONBLOCK); @@ -700,15 +708,14 @@ syscall_ret_t sys_poll(struct pollfd *fds, int count, int timeout) { fd[i].revents = 0; if(!fd0) - return {1,EINVAL,0}; - - DEBUG(proc->is_debug,"Trying to poll %s operation %d (fd %d with state %d, read_socket: 0x%p, write_socket: 0x%p) with timeout %d in proc %d",fd0->path,fd[i].events,fd[i].fd,fd0->state,fd0->read_socket_pipe,fd0->write_socket_pipe,timeout,proc->id); + return {1,EBADF,0}; if(fd[i].events & POLLIN) total_events++; - if(fd[i].events & POLLOUT) - total_events++; + if(fd[i].events & POLLOUT) { + total_events++; + } if(fd0->state == USERSPACE_FD_STATE_SOCKET && fd0->is_listen && fd0->read_counter == -1) { fd0->read_counter = 0; @@ -737,8 +744,7 @@ syscall_ret_t sys_poll(struct pollfd *fds, int count, int timeout) { userspace_fd_t* fd0 = vfs::fdmanager::search(proc,fd[i].fd); if(fd[i].events & POLLIN) { std::int64_t ret = vfs::vfs::poll(fd0,POLLIN); - if(fd0->is_listen) - DEBUG(proc->is_debug,"ret %d readcounter %d",ret,fd0->read_counter); + if(ret > fd0->read_counter) { fd0->read_counter = ret; num_events++; @@ -763,7 +769,6 @@ syscall_ret_t sys_poll(struct pollfd *fds, int count, int timeout) { if(success == false) { copy_in_userspace(proc,fds,fd,count * sizeof(struct pollfd)); - return {1,0,num_events}; } @@ -778,8 +783,7 @@ syscall_ret_t sys_poll(struct pollfd *fds, int count, int timeout) { SYSCALL_DISABLE_PREEMPT(); std::int64_t ret = vfs::vfs::poll(fd0,POLLIN); SYSCALL_ENABLE_PREEMPT(); - if(fd0->is_listen) - DEBUG(proc->is_debug,"ret %d readcounter %d",ret,fd0->read_counter); + if(ret > fd0->read_counter) { fd0->read_counter = ret; num_events++; @@ -839,7 +843,6 @@ syscall_ret_t sys_poll(struct pollfd *fds, int count, int timeout) { } copy_in_userspace(proc,fds,fd,count * sizeof(struct pollfd)); - return {1,0,num_events}; @@ -970,4 +973,30 @@ syscall_ret_t sys_chmod(char* path, int mode) { ret = vfs::vfs::var(&fd,value | mode, TMPFS_VAR_CHMOD | (1 << 7)); return {0,ret,0}; +} + +syscall_ret_t sys_ttyname(int fd, char *buf, size_t size) { + arch::x86_64::process_t* proc = CURRENT_PROC; + userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd); + if(!fd_s) + return {0,EBADF,0}; + + if(!buf) + return {0,EINVAL,0}; + + SYSCALL_IS_SAFEA(buf,2048); + + int ret = vfs::vfs::var(fd_s,0,DEVFS_VAR_ISATTY); + + fd_s->is_a_tty = ret == 0 ? 1 : 0; + + if(!fd_s->is_a_tty) + return {0,ENOTTY,0}; + + zero_in_userspace(proc,buf,size); + if(strlen(fd_s->path) > size) + return {0,ERANGE,0}; + + copy_in_userspace(proc,buf,fd_s->path,strlen(fd_s->path)); + return {0,0,0}; }
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/syscalls/futex.cpp b/kernel/src/arch/x86_64/syscalls/futex.cpp index 7e32717..cf28eeb 100644 --- a/kernel/src/arch/x86_64/syscalls/futex.cpp +++ b/kernel/src/arch/x86_64/syscalls/futex.cpp @@ -9,7 +9,7 @@ syscall_ret_t sys_futex_wait(int* pointer, int excepted) { arch::x86_64::process_t* proc = arch::x86_64::cpu::data()->temp.proc; int copied_pointer_val = 0; copy_in_userspace(proc,&copied_pointer_val,pointer,sizeof(int)); - DEBUG(proc->is_debug,"Waiting for futex, pointer: 0x%p excepted: %d, pointer_value %d in proc %d",pointer,excepted,copied_pointer_val,proc->id); + //DEBUG(proc->is_debug,"Waiting for futex, pointer: 0x%p excepted: %d, pointer_value %d in proc %d",pointer,excepted,copied_pointer_val,proc->id); arch::x86_64::scheduling::futexwait(proc,&copied_pointer_val,excepted,pointer); asm volatile("int $32"); // yield return {0,0,0}; @@ -17,7 +17,7 @@ syscall_ret_t sys_futex_wait(int* pointer, int excepted) { syscall_ret_t sys_futex_wake(int* pointer) { arch::x86_64::process_t* proc = arch::x86_64::cpu::data()->temp.proc; - DEBUG(proc->is_debug,"Wakeup futex with pointer 0x%p in proc %d",pointer,proc->id); + //DEBUG(proc->is_debug,"Wakeup futex with pointer 0x%p in proc %d",pointer,proc->id); arch::x86_64::scheduling::futexwake(proc,pointer); return {0,0,0}; } diff --git a/kernel/src/arch/x86_64/syscalls/process.cpp b/kernel/src/arch/x86_64/syscalls/process.cpp index c06c407..1431c4e 100644 --- a/kernel/src/arch/x86_64/syscalls/process.cpp +++ b/kernel/src/arch/x86_64/syscalls/process.cpp @@ -31,6 +31,7 @@ syscall_ret_t sys_tcb_set(std::uint64_t fs) { arch::x86_64::process_t* proc = CURRENT_PROC; + proc->fs_base = fs; __wrmsr(0xC0000100,fs); DEBUG(proc->is_debug,"Setting tcb %p to proc %d",fs,proc->id); return {0,0,0}; @@ -41,7 +42,7 @@ syscall_ret_t sys_libc_log(const char* msg) { char buffer[2048]; memset(buffer,0,2048); copy_in_userspace_string(proc,buffer,(void*)msg,2048); - DEBUG(proc->is_debug,"%s from proc %d",buffer,proc->id); + DEBUG(1,"%s from proc %d",buffer,proc->id); return {0,0,0}; } @@ -63,6 +64,8 @@ syscall_ret_t sys_exit(int status) { fd = next; } + DEBUG(proc->is_debug,"Process %s (%d) exited with code %d",proc->name,proc->id,status); + arch::x86_64::scheduling::kill(proc); if(!proc->is_cloned) @@ -71,7 +74,6 @@ syscall_ret_t sys_exit(int status) { memory::pmm::_virtual::free(proc->cwd); memory::pmm::_virtual::free(proc->name); memory::pmm::_virtual::free(proc->sse_ctx); - DEBUG(proc->is_debug,"Process %d exited with code %d",proc->id,status); schedulingScheduleAndChangeStack(arch::x86_64::cpu::data()->timer_ist_stack,0); __builtin_unreachable(); } @@ -181,10 +183,10 @@ syscall_ret_t sys_exec(char* path, char** argv, char** envp, int_frame_t* ctx) { envp_length = __elf_get_length2((char**)envp); memory::paging::enablekernel(); - char** argv0 = (char**)memory::heap::malloc(8 * (argv_length + 1)); + char** argv0 = (char**)memory::heap::malloc(8 * (argv_length + 2)); char** envp0 = (char**)memory::heap::malloc(8 * (envp_length + 1)); - memset(argv0,0,8 * (envp_length + 1)); + memset(argv0,0,8 * (envp_length + 2)); memset(envp0,0,8 * (envp_length + 1)); char stack_path[2048]; @@ -233,7 +235,7 @@ syscall_ret_t sys_exec(char* path, char** argv, char** envp, int_frame_t* ctx) { int status = vfs::vfs::stat(&fd,&stat); - DEBUG(proc->is_debug,"Exec file %s from proc %d",fd.path,proc->id); + DEBUG(1,"Exec file %s from proc %d",fd.path,proc->id); if(proc->is_debug) { for(int i = 0;i < argv_length;i++) { DEBUG(proc->is_debug,"Argv %d: %s",i,argv0[i]); @@ -282,6 +284,55 @@ syscall_ret_t sys_exec(char* path, char** argv, char** envp, int_frame_t* ctx) { int i = 0; memcpy(interp,"/bin/sh",strlen("/bin/sh")); + userspace_fd_t test; + test.is_cached_path = 0; + test.offset = 0; + memset(test.path,0,2048); + memcpy(test.path,result,strlen(result)); + + + + char first; + status = vfs::vfs::read(&test,&first,1); + if(status > 0) { + if(first == '!') { + memset(interp,0,2048); + while(1) { + int c = vfs::vfs::read(&test,&first,1); + if(c && c != '\n') + interp[i++] = c; + if(c && c == '\n') + break; + } + } + argv_length++; + memcpy(&argv0[1], argv0,sizeof(std::uint64_t) * argv_length); + char* t1 = (char*)malloc(2048); + memset(t1,0,2048); + memcpy(t1,result,strlen(result)); + argv0[0] = t1; + + + status = arch::x86_64::scheduling::loadelf(proc,interp,argv0,envp0,0); + if(status == 0) { + + for(int i = 0;i < argv_length; i++) { + memory::heap::free(argv0[i]); + } + + for(int i = 0;i < envp_length; i++) { + memory::heap::free(envp0[i]); + } + + memory::heap::free(argv0); + memory::heap::free(envp0); + + schedulingScheduleAndChangeStack(arch::x86_64::cpu::data()->timer_ist_stack,0); + __builtin_unreachable(); + } + + } + } } @@ -470,4 +521,9 @@ syscall_ret_t sys_clone(std::uint64_t stack, std::uint64_t rip, int c, int_frame new_proc->is_debug = proc->is_debug; return {1,0,new_proc->id}; +} + +syscall_ret_t sys_breakpoint(int num) { + Log::SerialDisplay(LEVEL_MESSAGE_INFO,"breakpoint %d\n",num); + return {0,0,0}; }
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/syscalls/syscalls.cpp b/kernel/src/arch/x86_64/syscalls/syscalls.cpp index bb721be..431c249 100644 --- a/kernel/src/arch/x86_64/syscalls/syscalls.cpp +++ b/kernel/src/arch/x86_64/syscalls/syscalls.cpp @@ -63,7 +63,9 @@ arch::x86_64::syscall_item_t sys_table[] = { {51,(void*)sys_mkdirat}, {52,(void*)sys_chmod}, {53,(void*)sys_enabledebugmode}, - {54,(void*)sys_clone} + {54,(void*)sys_clone}, + {56,(void*)sys_ttyname}, + {57,(void*)sys_breakpoint} }; arch::x86_64::syscall_item_t* __syscall_find(int rax) { @@ -71,6 +73,8 @@ arch::x86_64::syscall_item_t* __syscall_find(int rax) { if(sys_table[i].syscall_num == rax) return &sys_table[i]; } + Log::SerialDisplay(LEVEL_MESSAGE_WARN,"unknown syscall %d",rax); + return 0; // without it there will be ub } extern "C" void syscall_handler_c(int_frame_t* ctx) { @@ -83,18 +87,25 @@ extern "C" void syscall_handler_c(int_frame_t* ctx) { } else if(!item->syscall_func) { return; } - arch::x86_64::process_t* proc = arch::x86_64::cpu::data()->temp.proc; + proc->sys = ctx->rax; + + DEBUG(0,"sys %d from %d",ctx->rax,proc->id); + syscall_ret_t (*sys)(std::uint64_t D, std::uint64_t S, std::uint64_t d, int_frame_t* frame) = (syscall_ret_t (*)(std::uint64_t, std::uint64_t, std::uint64_t, int_frame_t*))item->syscall_func; syscall_ret_t ret = sys(ctx->rdi,ctx->rsi,ctx->rdx,ctx); if(ret.is_rdx_ret) { ctx->rdx = ret.ret_val; + if((std::int64_t)ret.ret_val < 0) + DEBUG(proc->is_debug,"rdx ret 0x%p smaller than zero from sys %d",ret.ret_val,ctx->rax); } + DEBUG(0,"sys ret %d from proc %d ",ret.ret,proc->id); + if(ret.ret != 0) - DEBUG(proc->is_debug,"Syscall %d from proc %d fails with code %d",ctx->rax,proc->id,ret.ret); + DEBUG(0,"Syscall %d from proc %d fails with code %d",ctx->rax,proc->id,ret.ret); ctx->rax = ret.ret; return; diff --git a/kernel/src/drivers/acpi.cpp b/kernel/src/drivers/acpi.cpp index 62dfb7d..841090f 100644 --- a/kernel/src/drivers/acpi.cpp +++ b/kernel/src/drivers/acpi.cpp @@ -53,7 +53,7 @@ void drivers::acpi::init() { drivers::ioapic::init(); Log::Display(LEVEL_MESSAGE_OK,"IOAPIC initializied\n"); - arch::x86_64::cpu::lapic::init(5000); + arch::x86_64::cpu::lapic::init(100); ret = uacpi_namespace_load(); diff --git a/kernel/src/generic/mm/pmm.cpp b/kernel/src/generic/mm/pmm.cpp index 22f89df..981f3ce 100644 --- a/kernel/src/generic/mm/pmm.cpp +++ b/kernel/src/generic/mm/pmm.cpp @@ -14,15 +14,15 @@ locks::spinlock pmm_lock; buddy_t mem; -buddy_info_t* buddy_find_by_parent(std::uint64_t parent_id,char split_x) { +buddy_info_t* buddy_find_by_parent(buddy_info_t* blud,char split_x) { if(split_x) { for(std::uint64_t i = 0;i < mem.buddy_queue;i++) { - if(mem.mem[i].parent_id == parent_id && mem.mem[i].split_x) + if(mem.mem[i].parent == blud && mem.mem[i].split_x) return &mem.mem[i]; } } else { for(std::uint64_t i = 0;i < mem.buddy_queue;i++) { - if(mem.mem[i].parent_id == parent_id && !mem.mem[i].split_x) + if(mem.mem[i].parent == blud && !mem.mem[i].split_x) return &mem.mem[i]; } } @@ -51,7 +51,7 @@ buddy_info_t* memory::buddy::put(std::uint64_t phys, std::uint8_t level) { blud->is_free = 1; blud->is_splitted = 0; blud->is_was_splitted = 0; - blud->parent_id = 0; + blud->parent = 0; blud->split_x = 0; return blud; } @@ -62,13 +62,13 @@ buddy_info_t* memory::buddy::split_maximum(buddy_info_t* blud, std::uint64_t siz return split_maximum(split(blud).first,size); } -void memory::buddy::merge(uint64_t parent_id) { - buddy_info_t* bl = buddy_find_by_parent(parent_id,0); - buddy_info_t* ud = buddy_find_by_parent(parent_id,1); +void memory::buddy::merge(buddy_info_t* budy) { + buddy_info_t* bl = budy; + buddy_info_t* ud = budy->twin; if(!bl || !ud || !bl->is_free || !ud->is_free) return; - buddy_info_t* blud = &mem.mem[parent_id]; + buddy_info_t* blud = budy->parent; bl->is_free = 0; ud->is_free = 0; blud->is_splitted = 0; @@ -77,15 +77,14 @@ void memory::buddy::merge(uint64_t parent_id) { blud->id = 0; bl->id = 0; ud->id = 0; - if(blud->parent_id) - merge(blud->parent_id); + if(blud->parent) + merge(blud); return; } buddy_split_t memory::buddy::split(buddy_info_t* info) { if(!info || LEVEL_TO_SIZE(info->level) == 4096 || !info->is_free) return {info,info}; - uint64_t daddy = ((uint64_t)info - (uint64_t)mem.mem) / sizeof(buddy_info_t); buddy_info_t* bl = 0; buddy_info_t* ud = 0; if(!info->is_was_splitted) { @@ -95,11 +94,13 @@ buddy_split_t memory::buddy::split(buddy_info_t* info) { bl->is_free = 1; ud->split_x = 1; ud->is_free = 1; - bl->parent_id = daddy; - ud->parent_id = daddy; + bl->parent = info; + ud->parent = info; + bl->twin = ud; + ud->twin = bl; } else { - bl = buddy_find_by_parent(daddy,0); - ud = buddy_find_by_parent(daddy,1); + bl = buddy_find_by_parent(info,0); + ud = bl->twin; bl->is_free = 1; ud->is_free = 1; } @@ -177,8 +178,8 @@ void memory::buddy::free(std::uint64_t phys) { return; blud->is_free = 1; blud->id = 0; - if(blud->parent_id) - merge(blud->parent_id); + if(blud->parent) + merge(blud); } std::int64_t memory::buddy::alloc(std::size_t size) { @@ -192,6 +193,8 @@ std::int64_t memory::buddy::alloc(std::size_t size) { if(LEVEL_TO_SIZE(mem.mem[i].level) >= size && LEVEL_TO_SIZE(mem.mem[i].level) < top_size && mem.mem[i].is_free) { top_size = LEVEL_TO_SIZE(mem.mem[i].level); nearest_buddy = &mem.mem[i]; + if(top_size == size) + break; } } @@ -217,6 +220,8 @@ alloc_t memory::buddy::alloc_ext(std::size_t size) { if(LEVEL_TO_SIZE(mem.mem[i].level) >= size && LEVEL_TO_SIZE(mem.mem[i].level) < top_size && mem.mem[i].is_free) { top_size = LEVEL_TO_SIZE(mem.mem[i].level); nearest_buddy = &mem.mem[i]; + if(top_size == size) + break; } } @@ -246,6 +251,8 @@ std::int64_t memory::buddy::allocid(std::size_t size,std::uint32_t id0) { if(LEVEL_TO_SIZE(mem.mem[i].level) >= size && LEVEL_TO_SIZE(mem.mem[i].level) < top_size && mem.mem[i].is_free) { top_size = LEVEL_TO_SIZE(mem.mem[i].level); nearest_buddy = &mem.mem[i]; + if(top_size == size) + break; } } diff --git a/kernel/src/generic/vfs/devfs.cpp b/kernel/src/generic/vfs/devfs.cpp index 9b3dda0..95f46fc 100644 --- a/kernel/src/generic/vfs/devfs.cpp +++ b/kernel/src/generic/vfs/devfs.cpp @@ -25,6 +25,19 @@ bool isdigit(char ch) { return ch >= '0' && ch <= '9'; } +long reverse_number(long num) { + long reversed_num = 0; + + while(num > 0) { + int digit = num % 10; + reversed_num = reversed_num * 10 + digit; + num /= 10; + } + + return reversed_num; +} + + vfs::devfs_node_t* devfs_find_dev(const char* loc) { vfs::devfs_node_t* dev = __devfs_head; char temp[256]; @@ -38,6 +51,8 @@ vfs::devfs_node_t* devfs_find_dev(const char* loc) { i--; } + dev_num = reverse_number(dev_num); + memcpy(temp, loc, i + 1); temp[i + 1] = '\0'; @@ -56,7 +71,7 @@ vfs::devfs_node_t* devfs_find_dev(const char* loc) { } std::int32_t __devfs__open(userspace_fd_t* fd, char* path) { - vfs::devfs_node_t* node = devfs_find_dev(path); + vfs::devfs_node_t* node = devfs_find_dev(path); if(!node) return ENOENT; @@ -78,6 +93,10 @@ std::int32_t __devfs__open(userspace_fd_t* fd, char* path) { return 0; } +int is_printable(char c) { + return (c >= 32 && c <= 126) || c == 10; +} + std::int64_t __devfs__write(userspace_fd_t* fd, char* path, void* buffer, std::uint64_t size) { vfs::devfs_node_t* node = devfs_find_dev(path); @@ -91,14 +110,96 @@ std::int64_t __devfs__write(userspace_fd_t* fd, char* path, void* buffer, std::u if(is_slave == 1 && node->slave_write) return node->slave_write(fd,buffer,size); - vfs::devfs_packet_t packet; - packet.request = !is_slave ? DEVFS_PACKET_WRITE_READRING : DEVFS_PACKET_WRITE_WRITERING; - packet.cycle = &fd->cycle; - packet.queue = &fd->queue; - packet.size = size; - packet.value = (std::uint64_t)buffer; + if(node->is_tty && !is_slave) { // handle stdio logic from /dev/pty writing + vfs::vfs::unlock(); + for(int i = 0;i < size;i++) { + char c = ((char*)buffer)[i]; + + if(!(node->term_flags->c_lflag & ICANON)) { + if(c == '\n') c = 13; + } + + if((node->term_flags->c_lflag & ECHO) && (is_printable(c) || c == 13)) { + if(c == 13) { + node->writepipe->write("\n",1); + } else if(c == '\n') + node->writepipe->write("\r",1); + asm volatile("cli"); + node->writepipe->write(&((char*)buffer)[i],1); + asm volatile("cli"); + } + + if(c == '\b') { + if(node->readpipe->size > 0) { + const char* back = "\b \b"; + node->writepipe->write(back,strlen(back)); + asm volatile("cli"); + node->readpipe->lock.lock(); + node->readpipe->read_counter--; + node->readpipe->buffer[node->readpipe->size--] = '\0'; + node->readpipe->lock.unlock(); + } + } + + if(is_printable(c) || !(node->term_flags->c_lflag & ICANON)) { + node->readpipe->write(&c,1); + asm volatile("cli"); + } else if(c == 13) { + node->readpipe->write("\n",1); + asm volatile("cli"); + } + + if((c == '\n' || c == 13) && (node->term_flags->c_lflag & ICANON)) { + node->readpipe->set_tty_ret(); + } + asm volatile("cli"); + } + return size; + } else if(node->is_tty && is_slave) { + vfs::vfs::unlock(); + for(int i = 0;i < size;i++) { + char c = ((char*)buffer)[i]; + if(c == '\n') { + node->writepipe->write("\r\n",2); + } else + node->writepipe->write(&c,1); + asm volatile("cli"); + } + return size; + } - return vfs::devfs::send_packet(path,&packet); + std::uint64_t status; + int is_master = !is_slave; + if(node->open_flags.is_pipe_rw) { + vfs::vfs::unlock(); + status = is_master ? node->readpipe->write((char*)buffer,size) : node->writepipe->write((char*)buffer,size); + } else { + if(!is_master) { + if(node->writering->ring.bytelen == 1) { + node->writering->send(*(char*)buffer); + } else if(node->writering->ring.bytelen == 2) { + node->writering->send(*(short*)buffer); + } else if(node->writering->ring.bytelen == 4) { + node->writering->send(*(int*)buffer); + } else if(node->writering->ring.bytelen == 8) { + node->writering->send(*(long long*)buffer); + } + } else { + if(node->readring->ring.bytelen == 1) { + node->readring->send(*(char*)buffer); + } else if(node->readring->ring.bytelen == 2) { + node->readring->send(*(short*)buffer); + } else if(node->readring->ring.bytelen == 4) { + node->readring->send(*(int*)buffer); + } else if(node->readring->ring.bytelen == 8) { + node->readring->send(*(long long*)buffer); + } + } + vfs::vfs::unlock(); + return node->writering->ring.bytelen; + } + + return status; } std::int64_t __devfs__read(userspace_fd_t* fd, char* path, void* buffer, std::uint64_t count) { @@ -111,14 +212,17 @@ std::int64_t __devfs__read(userspace_fd_t* fd, char* path, void* buffer, std::ui if(node->read) return node->read(fd,buffer,count); - vfs::devfs_packet_t packet; - packet.request = !is_slave ? DEVFS_PACKET_READ_WRITERING : DEVFS_PACKET_READ_READRING; - packet.cycle = &fd->cycle; - packet.queue = &fd->queue; - packet.size = count; - packet.value = (std::uint64_t)buffer; + std::uint64_t status; + int is_master = !is_slave; - std::int64_t status = vfs::devfs::send_packet(path,&packet); + if(node->open_flags.is_pipe_rw) { + vfs::vfs::unlock(); + status = is_master ? node->writepipe->read(&fd->read_counter,(char*)buffer,count,(fd->flags & O_NONBLOCK) ? 1 : 0) : node->readpipe->read(&fd->read_counter,(char*)buffer,count,(fd->flags & O_NONBLOCK) ? 1 : 0); + } else { + //DEBUG(1,"read %s ring count %d",path,count); + status = is_master ? node->writering->receivevals(buffer,dev_num,count,&fd->cycle,&fd->queue) : node->readring->receivevals(buffer,dev_num,count,&fd->cycle,&fd->queue); + vfs::vfs::unlock(); + } return status; } @@ -164,9 +268,21 @@ std::int32_t __devfs__mmap(userspace_fd_t* fd, char* path, std::uint64_t* outp, std::int32_t __devfs__var(userspace_fd_t* fd, char* path, std::uint64_t value, std::uint8_t request) { - vfs::devfs_packet_t packet; - packet.request = DEVFS_PACKET_ISATTY; - std::int32_t status = vfs::devfs::send_packet(path,&packet); + vfs::devfs_node_t* node = devfs_find_dev(path); + if(!node) + return ENOENT; + + int status = 0; + if(request == DEVFS_VAR_ISATTY) + status = node->is_tty ? 0 : ENOTTY; + + if((request & ~(1 << 7)) == TMPFS_VAR_CHMOD) { + if(request & (1 << 7)) + node->mode = value & 0xFFFFFFFF; + else + *(std::uint64_t*)value = (std::uint64_t)node->mode; + } + return status; } @@ -198,10 +314,38 @@ std::int64_t __devfs__poll(userspace_fd_t* fd, char* path, int operation_type) { case POLLIN: ret = !is_slave ? node->writepipe->read_counter : node->readpipe->read_counter; + if(!is_slave) + if(fd->read_counter == -1 && node->writepipe->size != 0) + ret = 0; + else + if(fd->read_counter == -1 && node->readpipe->size != 0) + ret = 0; + + if(!is_slave) { + if(fd->read_counter < node->writepipe->read_counter && node->writepipe->size == 0) { + fd->read_counter = node->writepipe->read_counter; + } else if(fd->read_counter < node->readpipe->read_counter && node->readpipe->size == 0) + fd->read_counter = node->readpipe->read_counter; + } + break; case POLLOUT: ret = !is_slave ? node->readpipe->write_counter : node->writepipe->write_counter; + if(ret == fd->write_counter) { + if(!is_slave) { + if(node->readpipe->size != node->readpipe->total_size) { + // fix this shit + node->readpipe->write_counter++; + } + } else { + if(node->writepipe->size != node->writepipe->total_size) { + node->writepipe->write_counter++; + } + } + ret = !is_slave ? node->readpipe->write_counter : node->writepipe->write_counter; + } + break; default: @@ -210,6 +354,17 @@ std::int64_t __devfs__poll(userspace_fd_t* fd, char* path, int operation_type) { } else { if(operation_type == POLLIN) { ret = !is_slave ? node->writering->read_counter : node->readring->read_counter; + if(!is_slave && ret == fd->read_counter) { + if(node->writering->isnotempty((int*)&fd->queue,(char*)&fd->cycle)) { + fd->read_counter--; + } + } else if(ret == fd->read_counter && is_slave) { + if(node->readring->isnotempty((int*)&fd->queue,(char*)&fd->cycle)) { + fd->read_counter--; + + } + } + } else if(operation_type == POLLOUT) { ret = !is_slave ? ++node->readring->write_counter : ++node->writering->write_counter; } @@ -254,94 +409,6 @@ std::int64_t vfs::devfs::send_packet(char* path,devfs_packet_t* packet) { return 0; } - case DEVFS_PACKET_READ_READRING: { - - if(!node) { vfs::vfs::unlock(); - return -ENOENT; } - - if(!node->open_flags.is_pipe_rw) { - - std::uint64_t count = node->readring->receivevals((std::uint64_t*)packet->value,dev_num,packet->size,packet->cycle,packet->queue); - vfs::unlock(); - return count; - } else { - vfs::unlock(); - asm volatile("sti"); - std::uint64_t count = node->readpipe->read((char*)packet->value,packet->size); - asm volatile("cli"); - return count; - } - } - - case DEVFS_PACKET_WRITE_READRING: - - if(!node) { vfs::vfs::unlock(); - return -ENOENT; } - - if(!node->open_flags.is_pipe_rw) { - if(node->readring->ring.bytelen == 1) { - node->readring->send(*(char*)packet->value); - } else if(node->readring->ring.bytelen == 2) { - node->readring->send(*(short*)packet->value); - } else if(node->readring->ring.bytelen == 4) { - node->readring->send(*(int*)packet->value); - } else if(node->readring->ring.bytelen == 8) { - node->readring->send(*(long long*)packet->value); - } - vfs::vfs::unlock(); - } else { - vfs::vfs::unlock(); - asm volatile("sti"); - std::uint64_t i = node->readpipe->write((char*)packet->value,packet->size); - asm volatile("cli"); - return i; - } - - return 8; - - case DEVFS_PACKET_READ_WRITERING: { - - if(!node) { vfs::vfs::unlock(); - return -ENOENT; } - - if(!node->open_flags.is_pipe_rw) { - std::int32_t count = node->writering->receivevals((std::uint64_t*)packet->value,dev_num,packet->size,packet->cycle,packet->queue); - vfs::unlock(); - return count; - } else { - vfs::unlock(); - asm volatile("sti"); - std::int64_t count = node->writepipe->read((char*)packet->value,packet->size); - asm volatile("cli"); - return count; - } - } - - case DEVFS_PACKET_WRITE_WRITERING: - - if(!node) { vfs::vfs::unlock(); - return -ENOENT; } - - if(!node->open_flags.is_pipe_rw) { - if(node->writering->ring.bytelen == 1) { - node->writering->send(*(char*)packet->value); - } else if(node->writering->ring.bytelen == 2) { - node->writering->send(*(short*)packet->value); - } else if(node->writering->ring.bytelen == 4) { - node->writering->send(*(int*)packet->value); - } else if(node->writering->ring.bytelen == 8) { - node->writering->send(*(long long*)packet->value); - } - vfs::vfs::unlock(); - } else { - vfs::vfs::unlock(); - asm volatile("sti"); - std::uint64_t i = node->writepipe->write((char*)packet->value,packet->size); - asm volatile("cli"); - return i; - } - return node->writering->ring.bytelen; - case DEVFS_PACKET_IOCTL: { if(!node) @@ -355,11 +422,6 @@ std::int64_t vfs::devfs::send_packet(char* path,devfs_packet_t* packet) { if(node->is_tty) { if(packet->ioctl.ioctlreq == TCSETS) { termios_t* termios = (termios_t*)packet->ioctl.arg; - if(!(termios->c_lflag & ICANON) && termios->c_cc[VMIN] == 0) { - node->readpipe->flags |= (O_NONBLOCK); - } else { - node->readpipe->flags &= ~(O_NONBLOCK); - } } } memcpy(node->ioctls[i].pointer_to_struct,(void*)packet->ioctl.arg,node->ioctls[i].size); @@ -394,6 +456,13 @@ std::int64_t vfs::devfs::send_packet(char* path,devfs_packet_t* packet) { current->write_req = packet->create_ioctl.writereg; current->pointer_to_struct = (void*)packet->create_ioctl.pointer; current->size = packet->create_ioctl.size; + + if(current->write_req == TCSETS) { + node->writepipe->ttyflags = 0; + node->readpipe->ttyflags = (termios_t*)packet->create_ioctl.pointer; + node->term_flags = (termios_t*)packet->create_ioctl.pointer; + } + return 0; } } @@ -464,6 +533,7 @@ std::int64_t vfs::devfs::send_packet(char* path,devfs_packet_t* packet) { return 0; } + int tty_ptr = 0; std::int32_t __ptmx_open(userspace_fd_t* fd, char* path) { @@ -480,13 +550,26 @@ std::int32_t __ptmx_open(userspace_fd_t* fd, char* path) { vfs::devfs::send_packet(ttyname + 4,&packet); + memset(fd->path,0,2048); + __printfbuf(fd->path,2048,"/dev/pty%d",tty_ptr); + memset(ttyname,0,2048); + __printfbuf(ttyname,2048,"/dev/tty%d",tty_ptr); + packet.request = DEVFS_PACKET_SETUPTTY; packet.value = (std::uint64_t)fd->path + 4; vfs::devfs::send_packet(ttyname + 4,&packet); + termios_t* t = (termios_t*)memory::pmm::_virtual::alloc(4096); + + t->c_lflag |= (ICANON | ECHO); + + t->c_iflag = IGNPAR | ICRNL; + t->c_oflag = OPOST; + t->c_cflag |= (CS8); + packet.request = DEVFS_PACKET_CREATE_IOCTL; - packet.create_ioctl.pointer = (uint64_t)memory::pmm::_virtual::alloc(4096); + packet.create_ioctl.pointer = (std::uint64_t)t; packet.create_ioctl.size = sizeof(termios_t); packet.create_ioctl.readreg = TCGETS; packet.create_ioctl.writereg = TCSETS; @@ -538,13 +621,25 @@ std::int64_t __pic_write(userspace_fd_t* fd, void* buffer, std::uint64_t size) { new_node->writering->setup_bytelen(1); new_node->readring->setup_bytelen(1); - arch::x86_64::interrupts::irq::create(irq_num,IRQ_TYPE_LEGACY_USERSPACE,0,0,ioapic_flags); + arch::x86_64::interrupts::irq::create(irq_num,IRQ_TYPE_LEGACY_USERSPACE,0,0,ioapic_flags); + drivers::ioapic::unmask(irq_num); vfs::vfs::unlock(); return 10; } +std::int64_t __zero_write(userspace_fd_t* fd, void* buffer, std::uint64_t size) { + vfs::vfs::unlock(); + return size; +} + +std::int64_t __zero_read(userspace_fd_t* fd, void* buffer, std::uint64_t count) { + vfs::vfs::unlock(); // dont waste time on this + memset(buffer,0,count); + return 0; +} + void vfs::devfs::mount(vfs_node_t* node) { __devfs_head = (devfs_node_t*)memory::pmm::_virtual::alloc(4096); node->open = __devfs__open; @@ -579,4 +674,16 @@ void vfs::devfs::mount(vfs_node_t* node) { __devfs_head->write = __pic_write; + + const char* name00 = "/null"; + + packet.size = 0; + packet.request = DEVFS_PACKET_CREATE_DEV; + packet.value = (std::uint64_t)name00; + + send_packet((char*)name00,&packet); + + __devfs_head->write = __zero_write; + __devfs_head->read = __zero_read; + }
\ No newline at end of file diff --git a/kernel/src/generic/vfs/tmpfs.cpp b/kernel/src/generic/vfs/tmpfs.cpp index a9acba2..2709f7a 100644 --- a/kernel/src/generic/vfs/tmpfs.cpp +++ b/kernel/src/generic/vfs/tmpfs.cpp @@ -200,10 +200,11 @@ std::int64_t __tmpfs__write(userspace_fd_t* fd, char* path, void* buffer, std::u __tmpfs__dealloc(node); } node->content = new_content; - node->size = new_size; node->real_size = new_content0.real_size; } + node->size = new_size; + memcpy(node->content + offset, buffer, size); fd->offset += size; diff --git a/kernel/src/generic/vfs/vfs.cpp b/kernel/src/generic/vfs/vfs.cpp index 55e8969..44eaa56 100644 --- a/kernel/src/generic/vfs/vfs.cpp +++ b/kernel/src/generic/vfs/vfs.cpp @@ -234,7 +234,7 @@ std::int64_t vfs::vfs::read(userspace_fd_t* fd, void* buffer, std::uint64_t coun fifo_node_t* fifo = fifo_get(out); vfs_lock->unlock(); asm volatile("sti"); - return fifo->main_pipe->read((char*)buffer,count); + return fifo->main_pipe->read(&fd->read_counter,(char*)buffer,count,(fd->flags & O_NONBLOCK) ? 1 : 0); } vfs_node_t* node = find_node(out); @@ -634,10 +634,20 @@ std::int64_t vfs::vfs::poll(userspace_fd_t* fd, int operation_type) { case POLLIN: ret = fifo->main_pipe->read_counter; + if(fifo->main_pipe->size != 0 && fd->read_counter == -1) + ret = 0; + if(fifo->main_pipe->size != 0 && ret == fd->read_counter) { + fifo->main_pipe->read_counter++; + ret = fifo->main_pipe->read_counter; + } break; case POLLOUT: ret = fifo->main_pipe->write_counter; + if(fifo->main_pipe->write_counter == ret && fifo->main_pipe->size != fifo->main_pipe->total_size) { + fifo->main_pipe->write_counter++; + ret = fifo->main_pipe->write_counter; + } break; default: @@ -652,11 +662,47 @@ std::int64_t vfs::vfs::poll(userspace_fd_t* fd, int operation_type) { case POLLIN: ret = fd->other_state == USERSPACE_FD_OTHERSTATE_MASTER ? fd->write_socket_pipe->read_counter : fd->read_socket_pipe->read_counter; + if(fd->other_state == USERSPACE_FD_OTHERSTATE_MASTER) + if(fd->write_socket_pipe->size != 0 && fd->read_counter == -1) + ret = 0; + if(fd->other_state == USERSPACE_FD_OTHERSTATE_SLAVE) + if(fd->read_socket_pipe->size != 0 && fd->read_counter == -1) + ret = 0; + + if(fd->other_state == USERSPACE_FD_OTHERSTATE_MASTER) { + if(fd->write_socket_pipe->read_counter == ret && fd->write_socket_pipe->size != 0) { + fd->write_socket_pipe->read_counter++; + } + } + + if(fd->other_state == USERSPACE_FD_OTHERSTATE_SLAVE) { + if(fd->read_socket_pipe->read_counter == ret && fd->read_socket_pipe->size != 0) { + fd->read_socket_pipe->read_counter++; + } + } + + ret = fd->other_state == USERSPACE_FD_OTHERSTATE_MASTER ? fd->write_socket_pipe->read_counter : fd->read_socket_pipe->read_counter; + break; case POLLOUT: ret = fd->other_state == USERSPACE_FD_OTHERSTATE_MASTER ? fd->read_socket_pipe->write_counter : fd->write_socket_pipe->write_counter; + + if(fd->other_state == USERSPACE_FD_OTHERSTATE_MASTER) { + if(fd->read_socket_pipe->write_counter == ret && fd->read_socket_pipe->size != fd->read_socket_pipe->total_size) { + fd->read_socket_pipe->write_counter++; + } + } + + if(fd->other_state == USERSPACE_FD_OTHERSTATE_SLAVE) { + if(fd->write_socket_pipe->write_counter == ret && fd->write_socket_pipe->size != fd->write_socket_pipe->total_size) { + fd->write_socket_pipe->write_counter++; + } + } + + ret = fd->other_state == USERSPACE_FD_OTHERSTATE_MASTER ? fd->read_socket_pipe->write_counter : fd->write_socket_pipe->write_counter; + break; default: @@ -666,16 +712,27 @@ std::int64_t vfs::vfs::poll(userspace_fd_t* fd, int operation_type) { vfs_lock->unlock(); return ret; } else if(fd->state == USERSPACE_FD_STATE_PIPE) { + std::int64_t ret = 0; switch (operation_type) { case POLLIN: ret = fd->pipe->read_counter; + if(fd->pipe->read_counter == -1 && fd->pipe->size != 0) + ret = 0; + if(fd->pipe->read_counter == ret && fd->pipe->size != 0) { + fd->pipe->read_counter++; + ret = fd->pipe->read_counter; + } break; case POLLOUT: ret = fd->pipe->write_counter; + if(fd->pipe->write_counter == ret && fd->pipe->size != fd->pipe->total_size) { + fd->pipe->write_counter++; + ret = fd->pipe->write_counter; + } break; default: @@ -13,14 +13,15 @@ Orange is my posix x86_64 os with microkernel features ## Devices which supported by orange -- [x] serial -- [x] cmos - [x] hpet - [x] pvclock - [x] ioapic -- [x] ps/2 Keyboard +- [x] ps/2 +- [x] ps/2 keyboard +- [x] ps/2 mouse - [x] xhci - [x] usb keyboard +- [x] usb mouse # Build @@ -49,7 +50,9 @@ make run - [x] Move XHCI driver from old kernel to userspace - [x] Implement IRQ userspace handling - [x] Port lua, fastfetch, doomgeneric, nano and etc. -- [ ] Improve XHCI driver -- [ ] Port Xorg +- [x] Improve XHCI driver +- [x] Port Xorg +- [ ] Port twm +- [ ] Port wine - [ ] Implement userspace disk drivers - [x] Improve kernel path resolver (add symlink support when trying to access another filesystem)
\ No newline at end of file diff --git a/tar-initrd.sh b/tar-initrd.sh index fa0e050..402d1b3 100755 --- a/tar-initrd.sh +++ b/tar-initrd.sh @@ -1,5 +1,5 @@ -rm -rf initrd +sudo rm -rf initrd export LIBTOOL="$HOME/opt/cross/orange/bin/libtool" export LIBTOOLIZE="$HOME/opt/cross/orange/bin/libtoolize" diff --git a/tools/base/etc/shells b/tools/base/etc/shells index 7a85f51..5d4150d 100644 --- a/tools/base/etc/shells +++ b/tools/base/etc/shells @@ -1,2 +1 @@ -/bin/sh /bin/bash
\ No newline at end of file diff --git a/tools/initbase/etc/X11/xinitrc b/tools/initbase/etc/X11/xinitrc new file mode 100644 index 0000000..59aeb73 --- /dev/null +++ b/tools/initbase/etc/X11/xinitrc @@ -0,0 +1,5 @@ + +st & +twm & +feh --bg-scale /etc/bg.jpg & +exit diff --git a/tools/initbase/var/run/utmp b/tools/initbase/var/run/utmp new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tools/initbase/var/run/utmp diff --git a/tools/pkg/2/init/src/include/etc.hpp b/tools/pkg/2/init/src/include/etc.hpp index 05db6eb..c153727 100644 --- a/tools/pkg/2/init/src/include/etc.hpp +++ b/tools/pkg/2/init/src/include/etc.hpp @@ -19,6 +19,8 @@ #include <string.h> #include <sys/types.h> +#include <pthread.h> + #include <orange/dev.h> #include <flanterm.h> @@ -140,222 +142,6 @@ const char en_layout_translation_shift[] = { #define CTRL_PRESSED 29 #define CTRL_RELEASED 157 -char* keybuffer; -int key_ptr = 0; - -int is_printable(char c) { - return (c >= 32 && c <= 126) || c == 10; -} - -class tty { -public: - - static void doKeyWork(uint8_t key,int master_fd) { - struct termios tty_termios; - tcgetattr(0,&tty_termios); - - if(key == SHIFT_PRESSED) { - is_shift_pressed = 1; - return; - } else if(key == SHIFT_RELEASED) { - is_shift_pressed = 0; - return; - } - - if(key == CTRL_PRESSED) { - is_ctrl_pressed = 1; - return; - } else if(key == CTRL_RELEASED) { - is_ctrl_pressed = 0; - return; - } - - if(!(key & (1 << 7))) { - char layout_key; - - if(!is_shift_pressed) - layout_key = en_layout_translation[key]; - else - layout_key = en_layout_translation_shift[key]; - - if(is_ctrl_pressed) - layout_key = en_layout_translation[key] - ASCII_CTRL_OFFSET; - - if((tty_termios.c_lflag & ECHO) && is_printable(layout_key)) - write(STDOUT_FILENO,&layout_key,1); - - if((tty_termios.c_lflag & ICANON) && (is_printable(layout_key) || layout_key == '\b') && layout_key != 0) { - - if(layout_key != '\b') { - keybuffer[key_ptr++] = layout_key; - if(layout_key == '\n') { - write(master_fd,keybuffer,key_ptr); - key_ptr = 0; - } - } else { - if(key_ptr) { - write(STDOUT_FILENO,"\b \b",sizeof("\b \b")); - keybuffer[key_ptr--] = '\0'; - } - } - - } else { - - if(layout_key == '\n') - layout_key = 13; - - keybuffer[key_ptr++] = layout_key; - - if(key_ptr >= tty_termios.c_cc[VMIN]) { - write(master_fd,keybuffer,key_ptr); - key_ptr = 0; - } - - } - } - } - - static void init() { - struct fb_var_screeninfo vinfo; - struct fb_fix_screeninfo finfo; - int fb0_dev = open("/dev/fb0", O_RDWR); - ioctl(fb0_dev, FBIOGET_VSCREENINFO, &vinfo); - ioctl(fb0_dev, FBIOGET_FSCREENINFO, &finfo); - - void* address = mmap(0, vinfo.yres_virtual * vinfo.xres_virtual * vinfo.bits_per_pixel / 8, - PROT_READ | PROT_WRITE, MAP_SHARED, fb0_dev, 0); - - uint32_t* test_canvas = (uint32_t*)malloc(vinfo.yres_virtual * vinfo.xres_virtual * sizeof(uint32_t)); - if (!test_canvas) { - exit(1); - } - - int img_w, img_h, img_channels; - unsigned char* img_data = stbi_load("/etc/bg.jpg", &img_w, &img_h, &img_channels, 3); - if (!img_data) { - exit(2); - } - - unsigned char* scaled_rgb = (unsigned char*)malloc(vinfo.xres * vinfo.yres * 3); - if (!scaled_rgb) { - exit(3); - } - - scale_image_nn(img_data, img_w, img_h, scaled_rgb, vinfo.xres, vinfo.yres, 3); - - for (int y = 0; y < vinfo.yres; y++) { - for (int x = 0; x < vinfo.xres; x++) { - int idx = (y * vinfo.xres + 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 * vinfo.xres + x] = rgb_to_pixel(r, g, b, - vinfo.red.length, vinfo.red.offset, - vinfo.green.length, vinfo.green.offset, - vinfo.blue.length, vinfo.blue.offset); - } - } - - stbi_image_free(img_data); - free(scaled_rgb); - - int margin = 64; - - draw_transparent_black_square(test_canvas, vinfo.xres, vinfo.yres, - vinfo.red.length, vinfo.red.offset, - vinfo.green.length, vinfo.green.offset, - vinfo.blue.length, vinfo.blue.offset, - margin - 1); - - struct flanterm_context *ft_ctx = flanterm_fb_init( - __flanterm_malloc, __flanterm_free, - (uint32_t*)address, vinfo.xres, vinfo.yres, - finfo.line_length, - vinfo.red.length, vinfo.red.offset, - vinfo.green.length, vinfo.green.offset, - vinfo.blue.length, vinfo.blue.offset, - test_canvas, - NULL, NULL, - NULL, &default_fg, - NULL, &default_fg_bright, - (void*)unifont_arr, FONT_WIDTH, FONT_HEIGHT, 0, - 1, 1, margin - ); - int master_fd = posix_openpt(O_RDWR | O_NOCTTY); - grantpt(master_fd); - unlockpt(master_fd); - char* name = ptsname(master_fd); - int slave_fd = open(name,O_RDWR); - int pid = fork(); - - if(pid == 0) { - char buffer[256]; - while(1) { - memset(buffer,0,256); - int count = read(master_fd,buffer,256); - if(count) { - flanterm_write(ft_ctx,buffer,count); - } - } - } - - dup2(slave_fd,STDOUT_FILENO); - dup2(slave_fd,STDIN_FILENO); - dup2(slave_fd,STDERR_FILENO); - - struct winsize buf; - - size_t cols = 0; - size_t rows = 0; - flanterm_get_dimensions(ft_ctx,&cols,&rows); - buf.ws_col = cols; - buf.ws_row = rows; - - ioctl(STDIN_FILENO,TIOCSWINSZ,&buf); - struct termios t; - - t.c_lflag |= (ICANON | ECHO); - - t.c_iflag = IGNPAR | ICRNL; - t.c_oflag = OPOST; - t.c_cflag |= (CS8); - - ioctl(STDIN_FILENO, TCSETS, &t); - - liborange_create_dev(((uint64_t)DEVFS_PACKET_CREATE_DEV << 32) | 0, "/ps2keyboard", "/masterps2keyboard"); - liborange_setup_ring_bytelen("/ps2keyboard0",1); - int master_input = open("/dev/masterps2keyboard0", O_RDWR); - int slave_input = open("/dev/ps2keyboard0", O_RDWR); - - keybuffer = (char*)malloc(1024); - - pid = fork(); - - if(pid == 0) { - struct pollfd pfd; - pfd.fd = slave_input; - pfd.events = POLLIN; - - while(1) { - int ret = poll(&pfd, 1, -1); - if(ret > 0) { - if(pfd.revents & POLLIN) { - char buffer[32]; - memset(buffer, 0, 32); - int count = read(slave_input, buffer, 32); - if(count > 0) { - for(int i = 0; i < count; i++) { - doKeyWork(buffer[i], master_fd); - } - } - } - } - - } - } - } -}; - #include <emmintrin.h> #define LEVEL_MESSAGE_OK 0 @@ -372,78 +158,5 @@ const char* level_messages[] = { #define log(level, format,...) printf("%s" format "\n", level_messages[level], ##__VA_ARGS__) -class fbdev { -public: - - static void refresh(void* ptr, void* a) { - struct limine_framebuffer fb; - liborange_access_framebuffer(&fb); - int buffer_in_use = 0; - void* real_fb = liborange_map_phys(fb.address, PTE_WC, fb.pitch * fb.height); - - while(1) { - memcpy(real_fb,ptr,fb.height * fb.pitch); - } - } - - static void setup_ioctl(int fb0_dev ,struct limine_framebuffer fb) { - struct fb_var_screeninfo vinfo; - struct fb_fix_screeninfo finfo; - vinfo.red.length = fb.red_mask_size; - vinfo.red.offset = fb.red_mask_shift; - vinfo.blue.offset = fb.blue_mask_shift; - vinfo.blue.length = fb.blue_mask_size; - vinfo.green.length = fb.green_mask_size; - vinfo.green.offset = fb.green_mask_shift; - vinfo.xres = fb.width; - vinfo.yres = fb.height; - vinfo.bits_per_pixel = fb.bpp < 5 ? (fb.bpp * 8) : fb.bpp; - vinfo.xres_virtual = fb.width; - vinfo.yres_virtual = fb.height; - vinfo.red.msb_right = 1; - vinfo.green.msb_right = 1; - vinfo.blue.msb_right = 1; - vinfo.transp.msb_right = 1; - vinfo.height = -1; - vinfo.width = -1; - finfo.line_length = fb.pitch; - finfo.smem_len = fb.pitch * fb.height; - finfo.visual = FB_VISUAL_TRUECOLOR; - finfo.type = FB_TYPE_PACKED_PIXELS; - finfo.mmio_len = fb.pitch * fb.height; - ioctl(fb0_dev,0x1,&vinfo); - ioctl(fb0_dev,0x2,&finfo); - } - - static void init() { - struct limine_framebuffer fb; - liborange_access_framebuffer(&fb); - liborange_create_dev(((uint64_t)DEVFS_PACKET_CREATE_PIPE_DEV << 32) | 0, "/fb", "/masterfb"); - liborange_create_dev(((uint64_t)DEVFS_PACKET_CREATE_PIPE_DEV << 32) | 0, "/vbe", "/mastervbe"); - - uint64_t doublebuffer_dma = liborange_alloc_dma(fb.pitch * fb.height); - void* mapped_dma = liborange_map_phys(doublebuffer_dma,0,fb.pitch * fb.height); - - void* a = aligned_alloc(4096,fb.pitch * fb.height); - void* b = aligned_alloc(4096,fb.pitch * fb.height); - - int pid = fork(); - if(pid == 0) { - refresh(mapped_dma,a); - } - - liborange_setup_mmap("/fb0",doublebuffer_dma,fb.pitch * fb.height,0); - - liborange_setup_ioctl("/fb0",sizeof(struct fb_var_screeninfo),FBIOGET_VSCREENINFO,0x1); - liborange_setup_ioctl("/fb0",sizeof(struct fb_fix_screeninfo),FBIOGET_FSCREENINFO,0x2); - int fb0_dev = open("/dev/fb0",O_RDWR); - - setup_ioctl(fb0_dev,fb); - - close(fb0_dev); - } - -}; - #define DIR_PATH "/etc/drivers/" #define EXT ".sys" diff --git a/tools/pkg/2/init/src/main.cpp b/tools/pkg/2/init/src/main.cpp index 5d94962..01674d3 100644 --- a/tools/pkg/2/init/src/main.cpp +++ b/tools/pkg/2/init/src/main.cpp @@ -45,7 +45,7 @@ void start_all_drivers() { } while ((entry = readdir(dir)) != NULL) { - if (ends_with(entry->d_name, ".sys")) { + if (ends_with(entry->d_name, ".wsys")) { char filepath[1024]; snprintf(filepath, sizeof(filepath), "%s%s", DIR_PATH, entry->d_name); @@ -57,7 +57,7 @@ void start_all_drivers() { } else if (pid == 0) { execl(filepath, filepath, (char *)NULL); } - } else if(ends_with(entry->d_name,".wsys")) { + } else if(ends_with(entry->d_name,".sys")) { char filepath[1024]; snprintf(filepath, sizeof(filepath), "%s%s", DIR_PATH, entry->d_name); @@ -80,12 +80,397 @@ void start_all_drivers() { closedir(dir); } +char* keybuffer; +int key_ptr = 0; + +int is_printable(char c) { + return (c >= 32 && c <= 126) || c == 10; +} + +static void doKeyWork(uint8_t key,int master_fd) { + struct termios tty_termios; + tcgetattr(0,&tty_termios); + + if(key == SHIFT_PRESSED) { + is_shift_pressed = 1; + return; + } else if(key == SHIFT_RELEASED) { + is_shift_pressed = 0; + return; + } + + if(key == CTRL_PRESSED) { + is_ctrl_pressed = 1; + return; + } else if(key == CTRL_RELEASED) { + is_ctrl_pressed = 0; + return; + } + + if(!(key & (1 << 7))) { + char layout_key; + + if(!is_shift_pressed) + layout_key = en_layout_translation[key]; + else + layout_key = en_layout_translation_shift[key]; + + if(is_ctrl_pressed) + layout_key = en_layout_translation[key] - ASCII_CTRL_OFFSET; + + write(master_fd,&layout_key,1); + + // if((tty_termios.c_lflag & ECHO) && is_printable(layout_key)) + // write(STDOUT_FILENO,&layout_key,1); + + // if((tty_termios.c_lflag & ICANON) && (is_printable(layout_key) || layout_key == '\b') && layout_key != 0) { + + // if(layout_key != '\b') { + // keybuffer[key_ptr++] = layout_key; + // if(layout_key == '\n') { + // write(master_fd,keybuffer,key_ptr); + // key_ptr = 0; + // } + // } else { + // if(key_ptr) { + // write(STDOUT_FILENO,"\b \b",sizeof("\b \b")); + + // keybuffer[key_ptr--] = '\0'; + // } + // } + // } else { + + // if(layout_key == '\n') + // layout_key = 13; + + // keybuffer[key_ptr++] = layout_key; + + // if(key_ptr >= tty_termios.c_cc[VMIN]) { + // write(master_fd,keybuffer,key_ptr); + // key_ptr = 0; + // } + // } + } +} + +int master_fd = 0; +int slave_fd = 0; +struct flanterm_context* ft_ctx; + +void* ptr; // fbdev target + +void* tty_work(void* arg) { + + dup2(slave_fd,STDOUT_FILENO); + dup2(slave_fd,STDIN_FILENO); + dup2(slave_fd,STDERR_FILENO); + + struct winsize buf; + + size_t cols = 0; + size_t rows = 0; + flanterm_get_dimensions(ft_ctx,&cols,&rows); + buf.ws_col = cols; + buf.ws_row = rows; + + ioctl(STDIN_FILENO,TIOCSWINSZ,&buf); + struct termios t; + + t.c_lflag |= (ICANON | ECHO); + + t.c_iflag = IGNPAR | ICRNL; + t.c_oflag = OPOST; + t.c_cflag |= (CS8); + + ioctl(STDIN_FILENO, TCSETS, &t); + + liborange_create_dev(((uint64_t)DEVFS_PACKET_CREATE_DEV << 32) | 0, "/ps2keyboard", "/masterps2keyboard"); + liborange_setup_ring_bytelen("/ps2keyboard0",1); + int master_input = open("/dev/masterps2keyboard0", O_RDWR); + int slave_input = open("/dev/ps2keyboard0", O_RDWR); + keybuffer = (char*)malloc(1024); + + struct pollfd pfd[2]; + pfd[0].fd = slave_input; + pfd[0].events = POLLIN; + pfd[1].fd = master_fd; + pfd[1].events = POLLIN; + + while(1) { + int ret = poll(pfd, 2, -1); + if(ret > 0) { + if(pfd[0].revents & POLLIN) { + char buffer[32]; + memset(buffer, 0, 32); + int count = read(slave_input, buffer, 32); + if(count > 0) { + for(int i = 0; i < count; i++) { + doKeyWork(buffer[i], master_fd); + } + } + } + + if(pfd[1].revents & POLLIN) { + char buffer[256]; + memset(buffer,0,256); + int count = read(master_fd,buffer,256); + if(count) flanterm_write(ft_ctx,buffer,count); + } + } + + } + +} + + +static void tty_init() { + struct fb_var_screeninfo vinfo; + struct fb_fix_screeninfo finfo; + int fb0_dev = open("/dev/fb0", O_RDWR); + ioctl(fb0_dev, FBIOGET_VSCREENINFO, &vinfo); + ioctl(fb0_dev, FBIOGET_FSCREENINFO, &finfo); + + void* address = mmap(0, vinfo.yres_virtual * vinfo.xres_virtual * vinfo.bits_per_pixel / 8, + PROT_READ | PROT_WRITE, MAP_SHARED, fb0_dev, 0); + + uint32_t* test_canvas = (uint32_t*)malloc(vinfo.yres_virtual * vinfo.xres_virtual * sizeof(uint32_t)); + if (!test_canvas) { + exit(1); + } + + int img_w, img_h, img_channels; + unsigned char* img_data = stbi_load("/etc/bg.jpg", &img_w, &img_h, &img_channels, 3); + if (!img_data) { + exit(2); + } + + unsigned char* scaled_rgb = (unsigned char*)malloc(vinfo.xres * vinfo.yres * 3); + if (!scaled_rgb) { + exit(3); + } + scale_image_nn(img_data, img_w, img_h, scaled_rgb, vinfo.xres, vinfo.yres, 3); + + for (int y = 0; y < vinfo.yres; y++) { + for (int x = 0; x < vinfo.xres; x++) { + int idx = (y * vinfo.xres + 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 * vinfo.xres + x] = rgb_to_pixel(r, g, b, + vinfo.red.length, vinfo.red.offset, + vinfo.green.length, vinfo.green.offset, + vinfo.blue.length, vinfo.blue.offset); + } + } + + stbi_image_free(img_data); + free(scaled_rgb); + + int margin = 64; + + draw_transparent_black_square(test_canvas, vinfo.xres, vinfo.yres, + vinfo.red.length, vinfo.red.offset, + vinfo.green.length, vinfo.green.offset, + vinfo.blue.length, vinfo.blue.offset, + margin - 1); + + ft_ctx = flanterm_fb_init( + __flanterm_malloc, __flanterm_free, + (uint32_t*)address, vinfo.xres, vinfo.yres, + finfo.line_length, + vinfo.red.length, vinfo.red.offset, + vinfo.green.length, vinfo.green.offset, + vinfo.blue.length, vinfo.blue.offset, + test_canvas, + NULL, NULL, + NULL, &default_fg, + NULL, &default_fg_bright, + (void*)unifont_arr, FONT_WIDTH, FONT_HEIGHT, 0, + 1, 1, margin + ); + master_fd = posix_openpt(O_RDWR | O_NOCTTY); + master_fd = posix_openpt(O_RDWR | O_NOCTTY); + master_fd = posix_openpt(O_RDWR | O_NOCTTY); + grantpt(master_fd); + unlockpt(master_fd); + char* name = ptsname(master_fd); + slave_fd = open(name,O_RDWR); + + dup2(slave_fd,STDOUT_FILENO); + dup2(slave_fd,STDIN_FILENO); + dup2(slave_fd,STDERR_FILENO); + + struct winsize buf; + + size_t cols = 0; + size_t rows = 0; + flanterm_get_dimensions(ft_ctx,&cols,&rows); + buf.ws_col = cols; + buf.ws_row = rows; + + ioctl(STDIN_FILENO,TIOCSWINSZ,&buf); + struct termios t; + + t.c_lflag |= (ICANON | ECHO); + + t.c_iflag = IGNPAR | ICRNL; + t.c_oflag = OPOST; + t.c_cflag |= (CS8); + + ioctl(STDIN_FILENO, TCSETS, &t); + + liborange_create_dev(((uint64_t)DEVFS_PACKET_CREATE_DEV << 32) | 0, "/ps2keyboard", "/masterps2keyboard"); + liborange_setup_ring_bytelen("/ps2keyboard0",1); + + liborange_create_dev(((uint64_t)DEVFS_PACKET_CREATE_DEV << 32) | 0, "/mouse", "/mastermouse"); + liborange_setup_ring_bytelen("/mouse0",4); + + int master_input = open("/dev/masterps2keyboard0", O_RDWR); + int slave_input = open("/dev/ps2keyboard0", O_RDWR); + keybuffer = (char*)malloc(1024); + pthread_t pth; + pthread_create(&pth,NULL,tty_work,0); + +} + +static inline void rep_movsb(void* dest, const void* src, size_t count) { + asm volatile( + "mov %0, %%rdi\n\t" + "mov %1, %%rsi\n\t" + "mov %2, %%rcx\n\t" + "rep movsb\n\t" + : + : "r"(dest), "r"(src), "r"(count) + : "%rdi", "%rsi", "%rcx", "memory"); +} + +inline void __cpuid(int code, int code2, uint32_t *a, uint32_t *b, uint32_t *c , uint32_t *d) { + __asm__ volatile("cpuid":"=a"(*a),"=b"(*b),"=c"(*c),"=d"(*d):"a"(code),"c"(code2)); +} + +int is_running_on_real_hw() { + int regs[4]; + + __asm__ volatile ( + "cpuid" + : "=a"(regs[0]), "=b"(regs[1]), "=c"(regs[2]), "=d"(regs[3]) + : "a"(0) + ); + + char vendor_id[13]; + *(uint32_t*)(vendor_id + 0) = regs[1]; + *(uint32_t*)(vendor_id + 4) = regs[3]; + *(uint32_t*)(vendor_id + 8) = regs[2]; + vendor_id[12] = '\0'; + + int is_vendor_virt = strncmp(vendor_id, "AuthenticAMD", 12) == 0 || + strncmp(vendor_id, "GenuineIntel", 12) == 0; + + if(is_vendor_virt) { + uint32_t a,b,c,d = 0; + __cpuid(0x40000000,0,&a,&b,&c,&d); + if(b != 0x4b4d564b || d != 0x4d || c != 0x564b4d56) + return 1; + + __cpuid(0x40000001,0,&a,&b,&c,&d); + if(!(a & (1 << 3))) + return 1; + is_vendor_virt = 0; + } + return is_vendor_virt; + +} + +void get_cpu(char* out) { + int regs[4]; + + __asm__ volatile ( + "cpuid" + : "=a"(regs[0]), "=b"(regs[1]), "=c"(regs[2]), "=d"(regs[3]) + : "a"(0) + ); + + char vendor_id[13]; + *(uint32_t*)(vendor_id + 0) = regs[1]; + *(uint32_t*)(vendor_id + 4) = regs[3]; + *(uint32_t*)(vendor_id + 8) = regs[2]; + vendor_id[12] = '\0'; + memcpy(out,vendor_id,13); +} + +void* refresh(void * arg) { + exit(0); + struct limine_framebuffer fb; + liborange_access_framebuffer(&fb); + void* real_fb = liborange_map_phys(fb.address, PTE_WC, fb.pitch * fb.height); + + while(1) { + memcpy(real_fb,ptr,fb.pitch * fb.height); + } +} + +void init_fbdev() { + struct limine_framebuffer fb; + liborange_access_framebuffer(&fb); + liborange_create_dev(((uint64_t)DEVFS_PACKET_CREATE_PIPE_DEV << 32) | 0, "/fb", "/masterfb"); + + uint64_t doublebuffer_dma = liborange_alloc_dma(fb.pitch * fb.height); + void* mapped_dma = liborange_map_phys(doublebuffer_dma,0,fb.pitch * fb.height); + + ptr = mapped_dma; + + liborange_setup_mmap("/fb0",fb.address,fb.pitch * fb.height,PTE_WC); + struct fb_var_screeninfo vinfo; + struct fb_fix_screeninfo finfo; + liborange_setup_ioctl("/fb0",sizeof(struct fb_var_screeninfo),FBIOGET_VSCREENINFO,0x1); + liborange_setup_ioctl("/fb0",sizeof(struct fb_fix_screeninfo),FBIOGET_FSCREENINFO,0x2); + int fb0_dev = open("/dev/fb0",O_RDWR); + vinfo.red.length = fb.red_mask_size; + vinfo.red.offset = fb.red_mask_shift; + vinfo.blue.offset = fb.blue_mask_shift; + vinfo.blue.length = fb.blue_mask_size; + vinfo.green.length = fb.green_mask_size; + vinfo.green.offset = fb.green_mask_shift; + vinfo.xres = fb.width; + vinfo.yres = fb.height; + vinfo.bits_per_pixel = fb.bpp < 5 ? (fb.bpp * 8) : fb.bpp; + vinfo.xres_virtual = fb.width; + vinfo.yres_virtual = fb.height; + vinfo.red.msb_right = 1; + vinfo.green.msb_right = 1; + vinfo.blue.msb_right = 1; + vinfo.transp.msb_right = 1; + vinfo.height = -1; + vinfo.width = -1; + finfo.line_length = fb.pitch; + finfo.smem_len = fb.pitch * fb.height; + finfo.visual = FB_VISUAL_TRUECOLOR; + finfo.type = FB_TYPE_PACKED_PIXELS; + finfo.mmio_len = fb.pitch * fb.height; + + ioctl(fb0_dev,0x1,&vinfo); + ioctl(fb0_dev,0x2,&finfo); + close(fb0_dev); +} + int main() { - fbdev::init(); - tty::init(); + init_fbdev(); + tty_init(); + + char cpu[13]; + get_cpu(cpu); + + log(LEVEL_MESSAGE_INFO,"Current vendor: %s",cpu); log(LEVEL_MESSAGE_OK,"Trying to start drivers"); start_all_drivers(); log(LEVEL_MESSAGE_OK,"Initialization done"); printf("\n"); - execl("/usr/bin/bash",NULL); + int pid = fork(); + if(pid == 0) + execl("/usr/bin/bash",NULL); + else { + while(1) { + asm volatile("nop"); // nothing + } + } }
\ No newline at end of file diff --git a/tools/pkg/2/ps2_driver/pkg.sh b/tools/pkg/2/ps2_driver/pkg.sh index 1a68b39..e3bfc76 100644 --- a/tools/pkg/2/ps2_driver/pkg.sh +++ b/tools/pkg/2/ps2_driver/pkg.sh @@ -1,4 +1,4 @@ mkdir -p "$1/etc/drivers/" -x86_64-orange-mlibc-gcc -o "$1/etc/drivers/ps2driver.sys" src/main.c
\ No newline at end of file +x86_64-orange-mlibc-gcc -o "$1/etc/drivers/i8042controller.sys" src/main.c
\ No newline at end of file diff --git a/tools/pkg/2/ps2_driver/src/main.c b/tools/pkg/2/ps2_driver/src/main.c index 78fadd7..6f7acdc 100644 --- a/tools/pkg/2/ps2_driver/src/main.c +++ b/tools/pkg/2/ps2_driver/src/main.c @@ -1,40 +1,307 @@ #include <orange/dev.h> #include <orange/io.h> +#include <orange/log.h> #include <stdio.h> -#include <unistd.h> #include <fcntl.h> +#include <poll.h> + +#include <stdlib.h> #include <stdint.h> #include <string.h> +#include <unistd.h> + +#define STATUS 0x64 +#define COMMAND 0x64 +#define DATA 0x60 +#define RESEND 0xFE +#define ACK 0xFA +#define ECHO 0xEE + +static inline char ps2_isfull() { + return (inb(0x64) & 2) == 2; +} + +static inline char ps2_wait() { + return (inb(0x64) & 1) == 0; +} + +void ps2_writecmd(uint8_t cmd) { + while(ps2_isfull()); + outb(0x64,cmd); +} + +void ps2_writedata(uint8_t cmd) { + while(ps2_isfull()); + outb(0x60,cmd); +} + +void ps2_flush() { + int timeout = 1000; + while((inb(STATUS) & 1) && --timeout > 0) inb(DATA); +} + +uint8_t ps2_read() { + while(ps2_wait()); + return inb(0x60); +} + +uint8_t ps2_readtimeout() { + int timeout = 100; + while(ps2_wait() && --timeout > 0) usleep(100); + if(timeout <= 0) + return 0; + return inb(0x60); +} + +uint8_t ps2_readlongtimeout() { + int timeout = 100; + while(ps2_wait() && --timeout > 0) usleep(1000); + if(timeout <= 0) + return 0; + return inb(0x60); +} + + + +void ps2_writeport(uint8_t port, uint8_t cmd) { + if(port == 2) + ps2_writecmd(0xD4); + + ps2_writedata(cmd); +} + +int dual_channel = 0; + +void ps2_disableport(uint8_t port) { + ps2_writeport(port,0xF5); + int retry = 0; + while(1) { + uint8_t response = ps2_readtimeout(); + if(!response) + break; + else if(response == RESEND) { + if(++retry == 10) + break; + ps2_writeport(port,0xF5); + } + } + ps2_flush(); +} + +void ps2_enableport(uint8_t port) { + ps2_writeport(port,0xF4); + int retry = 0; + while(1) { + uint8_t response = ps2_readtimeout(); + if(!response) + break; + else if(response == ACK) + break; + else if(response == RESEND) { + if(++retry == 10) + break; + ps2_writeport(port,0xF4); + } + } + ps2_flush(); +} + +char ps2_selftest(uint8_t port) { + ps2_disableport(port); + ps2_writeport(port,0xFF); + int retry = 0; + while(1) { + uint8_t response = ps2_readtimeout(); + if(!response) + break; + else if(response == RESEND) { + if(++retry == 10) + break; + ps2_writeport(port,0xFF); + } else if(response == ACK) + break; + } + + while(1) { + uint8_t response = ps2_readlongtimeout(); + if(!response) + break; + else if(response == 0xAA) + break; + else if(response == 0xFC) { + log(LEVEL_MESSAGE_FAIL,"Failed to test PS/2 port %d\n",port); + return 0; + } + } + + // used from astral src + while(1) { + if(!ps2_readtimeout()) + break; + } + + ps2_flush(); + return 1; +} + +#define MOUSE_LB (1 << 0) +#define MOUSE_RB (1 << 1) +#define MOUSE_MB (1 << 2) +#define MOUSE_B4 (1 << 3) +#define MOUSE_B5 (1 << 4) + +typedef struct { + unsigned char buttons; + unsigned char x; + unsigned char y; + unsigned char z; +} __attribute__((packed)) mouse_packet_t; + int main() { + + int pid = fork(); + + if(pid > 0) + exit(0); + int masterinput = open("/dev/masterps2keyboard",O_RDWR); + int mastermouse = open("/dev/mastermouse",O_RDWR); + + if(mastermouse < 0) { + perror("Can't open /dev/mastermouse device"); + exit(-1); + } + + if(masterinput < 0) { + perror("Can't open /dev/masterkeyboard device"); + exit(-1); + } liborange_setup_iopl_3(); int pic = open("/dev/pic",O_RDWR); + if(pic < 0) { + perror("Can't open /dev/pic device"); + exit(-1); + } + + ps2_writecmd(0xAD); + ps2_writecmd(0xA7); + + ps2_writecmd(0x20); + uint8_t config = ps2_read(); + config |= (1 << 0) | (1 << 1) | (1 << 6); + ps2_writecmd(0x60); + ps2_writedata(config); + + ps2_enableport(1); + ps2_enableport(2); + + // dont need identify just know what port 1 is kbd port 2 is mouse + liborange_pic_create_t irq_create_request; irq_create_request.flags = 0; + + ps2_writecmd(0xAE); + irq_create_request.irq = 1; + write(pic,&irq_create_request,sizeof(liborange_pic_create_t)); + ps2_writecmd(0xA8); + + irq_create_request.irq = 12; write(pic,&irq_create_request,sizeof(liborange_pic_create_t)); - close(pic); + + ps2_flush(); + + int irq1 = open("/dev/irq1",O_RDWR); + int irq12 = open("/dev/irq12",O_RDWR); + + struct pollfd irq_fds[2]; + + irq_fds[0].events = POLLIN; + irq_fds[0].fd = irq1; + irq_fds[1].events = POLLIN; + irq_fds[1].fd = irq12; + + int mouse_seq = 0; - int kbd_irq = open("/dev/irq1",O_RDWR); - char val = 0; - while(1) { - int count = read(kbd_irq,&val,1); - if(count && val == 1) { - write(kbd_irq,&val,1); /* Ask kernel to unmask this irq */ - while((inb(0x64) & 1)) { - uint8_t scancode = inb(0x60); - write(masterinput,&scancode,1); + if(1) { + + uint8_t mouse_buffer[4] = {0,0,0,0}; + + while(1) { + int num_events = poll(irq_fds,2,500); + if(num_events < 0) { + perror("Failed to poll irq fds"); + exit(-1); + } + + if(num_events == 0) { + mouse_seq = 0; + ps2_flush(); + int val = 1; + write(irq1,&val,1); + write(irq12,&val,1); } + + if(irq_fds[1].revents & POLLIN) { + char val = 0; + int count = read(irq12,&val,1); + if(count && val == 1) { + + mouse_buffer[mouse_seq++] = inb(DATA); + + if(mouse_seq != 3) { + write(irq1,&val,1); + write(irq12,&val,1); + continue; } + + mouse_packet_t packet = {0,0,0,0}; + + packet.x = mouse_buffer[1] - (mouse_buffer[0] & 0x10 ? 0x100 : 0); + packet.y = mouse_buffer[2] - (mouse_buffer[0] & 0x20 ? 0x100 : 0); + packet.z = (mouse_buffer[3] & 0x7) * (mouse_buffer[3] & 0x8 ? -1 : 1); + + packet.buttons |= (mouse_buffer[0] & 1) ? MOUSE_LB : 0; + packet.buttons |= (mouse_buffer[0] & 2) ? MOUSE_RB : 0; + packet.buttons |= (mouse_buffer[0] & 4) ? MOUSE_MB : 0; + + packet.buttons |= (mouse_buffer[0] & 0x10) ? MOUSE_B4 : 0; + packet.buttons |= (mouse_buffer[0] & 0x20) ? MOUSE_B5 : 0; + + write(mastermouse,&packet,4); + + mouse_seq = 0; + + write(irq1,&val,1); + write(irq12,&val,1); + + } + } + + if(irq_fds[0].revents & POLLIN) { + char val = 0; + int count = read(irq1,&val,1); + if(count && val == 1) { + while((inb(0x64) & 1)) { + uint8_t scancode = inb(0x60); + write(masterinput,&scancode,1); + } + write(irq1,&val,1); /* Ask kernel to unmask this irq */ + write(irq12,&val,1); /* irq 12 and irq 1 are connected */ + } + } + } } + exit(0); + }
\ No newline at end of file diff --git a/tools/pkg/2/xhci_driver/pkg.sh b/tools/pkg/2/xhci_driver/pkg.sh index 7e52716..2f5eddb 100644 --- a/tools/pkg/2/xhci_driver/pkg.sh +++ b/tools/pkg/2/xhci_driver/pkg.sh @@ -1,4 +1,4 @@ mkdir -p "$1/etc/drivers/" -x86_64-orange-mlibc-g++ -o "$1/etc/drivers/xhcidriver.wsys" src/main.cpp -Iinclude -std=c++17
\ No newline at end of file +x86_64-orange-mlibc-g++ -o "$1/etc/drivers/xhcidriver.sys" src/main.cpp -Iinclude -std=c++17
\ No newline at end of file diff --git a/tools/pkg/2/xhci_driver/src/main.cpp b/tools/pkg/2/xhci_driver/src/main.cpp index 30bdbc3..3def71b 100644 --- a/tools/pkg/2/xhci_driver/src/main.cpp +++ b/tools/pkg/2/xhci_driver/src/main.cpp @@ -336,7 +336,7 @@ int __xhci_enable_slot(xhci_device_t* dev, int portnum) { xhci_slot_trb_t* slot_ret = (xhci_slot_trb_t*)&ret; if(slot_ret->ret_code != 1) - log(LEVEL_MESSAGE_FAIL,"Can't allocate slot for port %d (ret %d)\n",portnum,ret.status & 0xFF); + log(LEVEL_MESSAGE_FAIL,"Can't allocate slot for port %d (ret %d)\n",portnum,ret.ret_code); return slot_ret->info_s.slotid; @@ -344,6 +344,7 @@ int __xhci_enable_slot(xhci_device_t* dev, int portnum) { int __xhci_set_addr(xhci_device_t* dev,uint64_t addr,uint32_t id,char bsr) { xhci_set_addr_trb_t trb; + memset(&trb,0,sizeof(trb)); trb.base = addr; trb.info_s.bsr = 0; trb.info_s.type = TRB_ADDRESSDEVICECOMMAND_TYPE; @@ -351,14 +352,18 @@ int __xhci_set_addr(xhci_device_t* dev,uint64_t addr,uint32_t id,char bsr) { __xhci_clear_event(dev); + usleep(20000); + + __xhci_clear_event(dev); + __xhci_command_ring_queue(dev,dev->com_ring,(xhci_trb_t*)&trb); __xhci_doorbell(dev,0); - usleep(10000); + usleep(20000); xhci_trb_t ret = __xhci_event_wait(dev,TRB_COMMANDCOMPLETIONEVENT_TYPE); if(ret.ret_code != 1) - log(LEVEL_MESSAGE_FAIL,"Can't set XHCI port address (ret %d)\n",ret.status & 0xFF); + log(LEVEL_MESSAGE_FAIL,"Can't set XHCI port address (ret %d)\n",ret.ret_code); return ret.ret_code; @@ -423,7 +428,6 @@ xhci_trb_t __xhci_send_usb_request_packet(xhci_device_t* dev,xhci_usb_device_t* xhci_trb_t ret = __xhci_event_wait(dev,TRB_TRANSFEREVENT_TYPE); if(ret.base == 0xDEAD) { - log(LEVEL_MESSAGE_FAIL,"Timeout on port %d\n",usbdev->portnum); ret.ret_code = 0; return ret; } @@ -705,6 +709,18 @@ void __xhci_get_hid_report(xhci_device_t* dev,xhci_usb_device_t* usbdev,uint8_t __xhci_send_usb_request_packet(dev,usbdev,cmd,data,len); } +void __xhci_set_boot_protocol(xhci_device_t* dev, xhci_usb_device_t* usbdev, int internum) { + xhci_usb_command_t cmd; + cmd.index = internum; + cmd.request = 0x0B; + cmd.type = 0x21; + cmd.len = 0; + cmd.value = 0; + + char data[4096]; + __xhci_send_usb_request_packet(dev,usbdev,cmd,data,0); +} + int __xhci_ep_to_type(xhci_endpoint_descriptor_t* desc) { uint8_t direction = (desc->endpointaddr & 0x80) ? 1 : 0; uint8_t type = desc->attributes & 3; @@ -755,6 +771,15 @@ const char* __xhci_usb_type_to_str(int type) { }; } +int log2(unsigned int x) { + int result = -1; + while (x) { + x >>= 1; + result++; + } + return result; +} + void __xhci_init_dev(xhci_device_t* dev,int portnum) { volatile uint32_t* portsc = __xhci_portsc(dev,portnum); @@ -839,6 +864,8 @@ void __xhci_init_dev(xhci_device_t* dev,int portnum) { } + + if(__xhci_set_addr(dev,addr,id,0) != 1) return; @@ -945,6 +972,7 @@ void __xhci_init_dev(xhci_device_t* dev,int portnum) { xhci_interface_descriptor_t* interface = (xhci_interface_descriptor_t*)need_interface; + __xhci_set_boot_protocol(dev,usb_dev,interface->num); __xhci_get_hid_report(dev,usb_dev,0,interface->num,need_interface->buffer,need_interface->len); } @@ -981,17 +1009,21 @@ void __xhci_init_dev(xhci_device_t* dev,int portnum) { ep1->maxburstsize = 0; ep1->averagetrblen = ep->maxpacketsize; ep1->base = usb_dev->ep_ctx[idx]->phys | usb_dev->ep_ctx[idx]->cycle; - if((load_portsc & 0x3C00) >> 10 == 4 || (load_portsc & 0x3C00) >> 10 == 3) { - ep1->interval = ep->interval - 1; - } else { - ep1->interval = ep->interval; - if(ep1->endpointtype == 7 || ep1->endpointtype == 3 || ep1->endpointtype == 5 || ep1->endpointtype == 1) { - if(ep1->interval < 3) - ep1->interval = 3; - else if(ep1->interval > 18) - ep1->interval = 18; - } + uint8_t port_speed = (load_portsc & 0x3C00) >> 10; + uint8_t interval = ep->interval; + uint8_t epty = ep1->endpointtype; + + /* thanks n00byedge for tips */ + + if(port_speed == XHCI_USB_SPEED_HIGH_SPEED || port_speed == XHCI_USB_SPEED_SUPER_SPEED || port_speed == XHCI_USB_SPEED_SUPER_SPEED_PLUS) + ep1->interval = interval - 1; + else if(port_speed == XHCI_USB_SPEED_FULL_SPEED && (epty == XHCI_ENDPOINTTYPE_ISOCHRONOUS_IN || epty == XHCI_ENDPOINTTYPE_ISOCHRONOUS_OUT)) + ep1->interval = interval + 2; + else if((port_speed == XHCI_USB_SPEED_FULL_SPEED || port_speed == XHCI_USB_SPEED_LOW_SPEED) && (epty == XHCI_ENDPOINTTYPE_INTERRUPT_IN || epty == XHCI_ENDPOINTTYPE_INTERRUPT_OUT)) { + ep1->interval = log2(interval) + 4; } + + } else { xhci_input_ctx64_t* input = (xhci_input_ctx64_t*)liborange_map_phys(addr,0,4096); xhci_endpoint_ctx_t* ep1 = (xhci_endpoint_ctx_t*)(&input->ep[idx]); @@ -1007,16 +1039,16 @@ void __xhci_init_dev(xhci_device_t* dev,int portnum) { ep1->maxburstsize = 0; ep1->averagetrblen = ep->maxpacketsize; ep1->base = (uint64_t)usb_dev->ep_ctx[idx]->phys | usb_dev->ep_ctx[idx]->cycle; - if((load_portsc & 0x3C00) >> 10 == 4 || (load_portsc & 0x3C00) >> 10 == 3) { - ep1->interval = ep->interval - 1; - } else { - ep1->interval = ep->interval; - if(ep1->endpointtype == 7 || ep1->endpointtype == 3 || ep1->endpointtype == 5 || ep1->endpointtype == 1) { - if(ep1->interval < 3) - ep1->interval = 3; - else if(ep1->interval > 18) - ep1->interval = 18; - } + uint8_t port_speed = (load_portsc & 0x3C00) >> 10; + uint8_t interval = ep->interval; + uint8_t epty = ep1->endpointtype; + + if(port_speed == XHCI_USB_SPEED_HIGH_SPEED || port_speed == XHCI_USB_SPEED_SUPER_SPEED || port_speed == XHCI_USB_SPEED_SUPER_SPEED_PLUS) + ep1->interval = interval - 1; + else if(port_speed == XHCI_USB_SPEED_FULL_SPEED && (epty == XHCI_ENDPOINTTYPE_ISOCHRONOUS_IN || epty == XHCI_ENDPOINTTYPE_ISOCHRONOUS_OUT)) + ep1->interval = interval + 2; + else if((port_speed == XHCI_USB_SPEED_FULL_SPEED || port_speed == XHCI_USB_SPEED_LOW_SPEED) && (epty == XHCI_ENDPOINTTYPE_INTERRUPT_IN || epty == XHCI_ENDPOINTTYPE_INTERRUPT_OUT)) { + ep1->interval = log2(interval) + 4; } } @@ -1248,6 +1280,7 @@ pci_driver_t pci_drivers[256]; char hid_to_ps2_layout[0x48]; int input0_fd = 0; +int mouse_fd = 0; void hid_layout_init() { hid_to_ps2_layout[0x04] = 0x1E; @@ -1377,14 +1410,49 @@ void __usbkeyboard_handler(xhci_usb_device_t* usbdev, xhci_done_trb_t* trb) { memcpy(usbdev->add_buffer, data, 8); } +#define MOUSE_LB (1 << 0) +#define MOUSE_RB (1 << 1) +#define MOUSE_MB (1 << 2) +#define MOUSE_B4 (1 << 3) +#define MOUSE_B5 (1 << 4) + +typedef struct { + unsigned char buttons; + unsigned char x; + unsigned char y; + unsigned char z; +} __attribute__((packed)) mouse_packet_t; + +void __usbmouse_handler(xhci_usb_device_t* usbdev, xhci_done_trb_t* trb) { + uint8_t* data = usbdev->buffers[trb->info_s.ep_id - 2]; + + mouse_packet_t packet; + + packet.buttons = 0; + + packet.buttons |= (data[0] & (1 << 0)) ? MOUSE_LB : 0; + packet.buttons |= (data[0] & (1 << 1)) ? MOUSE_RB : 0; + packet.buttons |= (data[0] & (1 << 2)) ? MOUSE_MB : 0; + + packet.x = data[1]; + packet.y = -data[2]; + packet.z = 0; // todo: figure out how to get mouse scroll wheel data + + + write(mouse_fd,&packet,4); +} + int main() { liborange_setup_iopl_3(); input0_fd = open("/dev/masterps2keyboard",O_RDWR); + mouse_fd = open("/dev/mastermouse",O_RDWR); log(LEVEL_MESSAGE_WARN,"XHCI Driver is currently under development so it's unstable\n"); xhci_hid_register(__usbkeyboard_handler,USB_TYPE_KEYBOARD); + xhci_hid_register(__usbmouse_handler,USB_TYPE_MOUSE); + hid_layout_init(); memset(pci_drivers,0,sizeof(pci_drivers)); diff --git a/tools/pkg/3/coreutils/pkg.sh b/tools/pkg/3/coreutils/pkg.sh index 5e10aaf..983648e 100644 --- a/tools/pkg/3/coreutils/pkg.sh +++ b/tools/pkg/3/coreutils/pkg.sh @@ -20,4 +20,4 @@ cd coreutils-build ../coreutils-9.7/configure --host=x86_64-orange-mlibc --prefix="/usr" make install-strip -j$(nproc) DESTDIR="$1" -cd ..
\ No newline at end of file +cd .. diff --git a/tools/pkg/3/mouse_test/info.txt b/tools/pkg/3/mouse_test/info.txt new file mode 100644 index 0000000..c50b1e4 --- /dev/null +++ b/tools/pkg/3/mouse_test/info.txt @@ -0,0 +1 @@ +mousetest
\ No newline at end of file diff --git a/tools/pkg/3/mouse_test/main.c b/tools/pkg/3/mouse_test/main.c new file mode 100644 index 0000000..51f6c4b --- /dev/null +++ b/tools/pkg/3/mouse_test/main.c @@ -0,0 +1,194 @@ +#include <stdio.h> +#include <poll.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <sys/ioctl.h> +#include <linux/fb.h> +#include <stdlib.h> +#include <string.h> + +#define MOUSE_LB (1 << 0) +#define MOUSE_RB (1 << 1) +#define MOUSE_MB (1 << 2) +#define MOUSE_B4 (1 << 3) +#define MOUSE_B5 (1 << 4) + +typedef struct { + unsigned char buttons; + unsigned char x; + unsigned char y; + unsigned char z; +} __attribute__((packed)) mouse_packet_t; + +typedef struct { + int fd; + char *fbp; + struct fb_fix_screeninfo finfo; + struct fb_var_screeninfo vinfo; + long int screensize; + int cursor_x, cursor_y; + int cursor_visible; +} fb_info_t; + +int init_fb(fb_info_t *fb) { + fb->fd = open("/dev/fb0", O_RDWR); + if (fb->fd == -1) { + perror("Error: cannot open framebuffer device"); + return -1; + } + + if (ioctl(fb->fd, FBIOGET_FSCREENINFO, &fb->finfo)) { + perror("Error reading fixed information"); + close(fb->fd); + return -1; + } + + if (ioctl(fb->fd, FBIOGET_VSCREENINFO, &fb->vinfo)) { + perror("Error reading variable information"); + close(fb->fd); + return -1; + } + + fb->screensize = fb->vinfo.yres_virtual * fb->finfo.line_length; + + fb->fbp = (char *)mmap(0, fb->screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fb->fd, 0); + if ((long)fb->fbp == -1) { + perror("Error: failed to map framebuffer device to memory"); + close(fb->fd); + return -1; + } + + fb->cursor_x = fb->vinfo.xres / 2; + fb->cursor_y = fb->vinfo.yres / 2; + fb->cursor_visible = 1; + + printf("Framebuffer initialized: %dx%d, %dbpp\n", + fb->vinfo.xres, fb->vinfo.yres, fb->vinfo.bits_per_pixel); + + return 0; +} + +void put_pixel(fb_info_t *fb, int x, int y, unsigned int color) { + if (x < 0 || x >= fb->vinfo.xres || y < 0 || y >= fb->vinfo.yres) + return; + + long location = (x + fb->vinfo.xoffset) * (fb->vinfo.bits_per_pixel / 8) + + (y + fb->vinfo.yoffset) * fb->finfo.line_length; + + if (fb->vinfo.bits_per_pixel == 32) { + *((unsigned int *)(fb->fbp + location)) = color; + } else if (fb->vinfo.bits_per_pixel == 16) { + *((unsigned short *)(fb->fbp + location)) = color & 0xFFFF; + } else { + *((unsigned char *)(fb->fbp + location)) = color & 0xFF; + } +} + +void draw_cursor(fb_info_t *fb) { + int x = fb->cursor_x; + int y = fb->cursor_y; + unsigned int color = 0xFFFFFF; + + for (int i = -5; i <= 5; i++) { + if (i != 0) { + put_pixel(fb, x, y + i, color); + } + } + + for (int i = -5; i <= 5; i++) { + if (i != 0) { + put_pixel(fb, x + i, y, color); + } + } + + put_pixel(fb, x, y, 0xFF0000); +} + +void clear_cursor_area(fb_info_t *fb) { + int size = 10; + for (int i = -size; i <= size; i++) { + for (int j = -size; j <= size; j++) { + put_pixel(fb, fb->cursor_x + i, fb->cursor_y + j, 0x000000); + } + } +} + +void update_cursor(fb_info_t *fb, int dx, int dy) { + + if (fb->cursor_visible) { + clear_cursor_area(fb); + } + + fb->cursor_x += dx; + fb->cursor_y += dy; + + if (fb->cursor_x < 0) fb->cursor_x = 0; + if (fb->cursor_x >= fb->vinfo.xres) fb->cursor_x = fb->vinfo.xres - 1; + if (fb->cursor_y < 0) fb->cursor_y = 0; + if (fb->cursor_y >= fb->vinfo.yres) fb->cursor_y = fb->vinfo.yres - 1; + + draw_cursor(fb); +} + +void clear_screen(fb_info_t *fb) { + memset(fb->fbp, 0, fb->screensize); +} + +int main() { + int mouse_fd = open("/dev/mouse", O_RDWR); + if (mouse_fd == -1) { + perror("Error: cannot open mouse device"); + return 1; + } + + fb_info_t fb; + if (init_fb(&fb) == -1) { + close(mouse_fd); + return 1; + } + + clear_screen(&fb); + + draw_cursor(&fb); + + struct pollfd fd; + fd.events = POLLIN; + fd.fd = mouse_fd; + + while(1) { + int num = poll(&fd, 1, -1); + if (num > 0 && (fd.revents & POLLIN)) { + mouse_packet_t packets[256]; + memset(packets,0,sizeof(mouse_packet_t) * 256); + int bytes_read = read(mouse_fd, &packets, sizeof(mouse_packet_t) * 256); + + for(int i = 0; i < bytes_read / (sizeof(mouse_packet_t));i++) { + mouse_packet_t packet = packets[i]; + if (1) { + + int dx = (signed char)packet.x; + int dy = (signed char)packet.y; + + + update_cursor(&fb, dx, -dy); + if(packet.buttons & MOUSE_LB) { + printf("pressed left button\n"); + } + + if(packet.buttons & MOUSE_RB) { + printf("pressed right button\n"); + } + + if(packet.buttons & MOUSE_MB) { + printf("pressed middle button\n"); + } + + } + } + + } + } + + return 0; +}
\ No newline at end of file diff --git a/tools/pkg/3/mouse_test/pkg.sh b/tools/pkg/3/mouse_test/pkg.sh new file mode 100644 index 0000000..b2d8efe --- /dev/null +++ b/tools/pkg/3/mouse_test/pkg.sh @@ -0,0 +1,2 @@ + +x86_64-orange-mlibc-gcc main.c -o "$1/usr/bin/mouse_test"
\ No newline at end of file diff --git a/tools/pkg/4/xorg-server/pkg.sh b/tools/pkg/4/xorg-server/pkg.sh index fcd1d84..70759b1 100644 --- a/tools/pkg/4/xorg-server/pkg.sh +++ b/tools/pkg/4/xorg-server/pkg.sh @@ -118,7 +118,7 @@ popd cd xkeyboard-config-2.36 mkdir -p build -meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix="/usr" build +meson --cross-file="$1/../tools/pkg/x86_64-orange.crossfile" --prefix="/usr" build -Dxorg-rules-symlinks=true cd build ninja @@ -126,13 +126,7 @@ sudo DESTDIR="$1" ninja install cd ../.. -rm -rf "$1/usr/share/X11/xkb" - -ooo="$(pwd)" -cd "$1/usr/share/X11" -ln -s ../xkeyboard-config-2 xkb - -cd "$ooo" +sudo chmod 777 -R "$1/usr/share/X11/xkb" fast_install "$1" https://www.x.org/releases/individual/xserver/xorg-server-21.1.4.tar.gz "--with-xkb-bin-directory=/usr/bin --disable-pciaccess --disable-libdrm --disable-glx --disable-int10-module --disable-glamor --disable-vgahw --disable-dri3 --disable-dri2 --disable-dri --disable-xephyr --disable-xwayland --disable-xnest --disable-dmx --with-fontrootdir=/usr/share/fonts/X11 --disable-strict-compilation" "../../diff/xorgserver.diff" diff --git a/tools/pkg/5/orangex/info.txt b/tools/pkg/5/orangex/info.txt new file mode 100644 index 0000000..e5c9be7 --- /dev/null +++ b/tools/pkg/5/orangex/info.txt @@ -0,0 +1 @@ +orangeX - x start script for orange
\ No newline at end of file diff --git a/tools/pkg/5/orangex/main.sh b/tools/pkg/5/orangex/main.sh new file mode 100644 index 0000000..3adaa85 --- /dev/null +++ b/tools/pkg/5/orangex/main.sh @@ -0,0 +1,4 @@ + +stty -echo +xinit /etc/X11/xinitrc > /dev/null 2> /dev/null +stty +echo
\ No newline at end of file diff --git a/tools/pkg/5/orangex/pkg.sh b/tools/pkg/5/orangex/pkg.sh new file mode 100644 index 0000000..62ddf7c --- /dev/null +++ b/tools/pkg/5/orangex/pkg.sh @@ -0,0 +1,3 @@ + +cp -rf main.sh "$1/usr/bin/orangeX" +chmod +x "$1/usr/bin/orangeX"
\ No newline at end of file diff --git a/tools/pkg/5/twm/pkg.sh b/tools/pkg/5/twm/pkg.sh index 8a59848..fd025b0 100644 --- a/tools/pkg/5/twm/pkg.sh +++ b/tools/pkg/5/twm/pkg.sh @@ -26,7 +26,6 @@ fast_install "$1" https://www.x.org/releases/individual/lib/libXft-2.3.4.tar.gz fast_install "$1" https://www.x.org/releases/individual/lib/libXi-1.8.1.tar.gz fast_install "$1" https://www.x.org/pub/individual/app/xclock-1.1.1.tar.xz -fast_install "$1" https://invisible-mirror.net/archives/xterm/xterm-390.tgz "--disable-tcap-fkeys --disable-tcap-query --enable-256-color" "../../diff/xterm.diff" fast_install "$1" https://www.x.org/releases/individual/app/xeyes-1.2.0.tar.gz fast_install "$1" https://www.x.org/releases/individual/app/xinit-1.4.1.tar.gz
\ No newline at end of file diff --git a/tools/pkg/5/xorg-modules/diff/xmouse.diff b/tools/pkg/5/xorg-modules/diff/xmouse.diff new file mode 100644 index 0000000..82e8e37 --- /dev/null +++ b/tools/pkg/5/xorg-modules/diff/xmouse.diff @@ -0,0 +1,154 @@ +diff -Naur xf86-input-mouse-1.9.5/configure xf86-input-mouse-patched/configure +--- xf86-input-mouse-1.9.5/configure 2023-05-05 03:25:26.000000000 +0300 ++++ xf86-input-mouse-patched/configure 2025-11-07 16:18:50.878312976 +0300 +@@ -19591,7 +19591,7 @@ + + # X Server SDK location is required to install xf86-mouse-properties.h + # This location is also relayed in the xorg-mouse.pc file +-sdkdir=`$PKG_CONFIG --variable=sdkdir xorg-server` ++sdkdir="$includedir" + + # Workaround overriding sdkdir to be able to create a tarball when user has no + # write permission in sdkdir. See DISTCHECK_CONFIGURE_FLAGS in Makefile.am +@@ -19619,6 +19619,9 @@ + gnu*) + OS_MOUSE_NAME=hurd + ;; ++ orange*) ++ OS_MOUSE_NAME=orange ++ ;; + esac + + +diff -Naur xf86-input-mouse-1.9.5/src/orange_mouse.c xf86-input-mouse-patched/src/orange_mouse.c +--- xf86-input-mouse-1.9.5/src/orange_mouse.c 1970-01-01 03:00:00.000000000 +0300 ++++ xf86-input-mouse-patched/src/orange_mouse.c 2025-11-08 17:39:27.721764644 +0300 +@@ -0,0 +1,128 @@ ++#ifdef HAVE_XORG_CONFIG_H ++#include <xorg-config.h> ++#endif ++ ++#include <xorg-server.h> ++#include <X11/X.h> ++#include <X11/Xproto.h> ++#include "inputstr.h" ++#include "scrnintstr.h" ++#include "mipointer.h" ++ ++#include "xf86.h" ++#include "xf86Xinput.h" ++#include "mouse.h" ++#include "xf86_OSlib.h" ++#include "xisb.h" ++ ++#include <stdio.h> ++#include <errno.h> ++#include <stdbool.h> ++#include <stdint.h> ++#include <string.h> ++ ++#include <sys/stat.h> ++ ++#define MOUSE_LB (1 << 0) ++#define MOUSE_RB (1 << 1) ++#define MOUSE_MB (1 << 2) ++#define MOUSE_B4 (1 << 3) ++#define MOUSE_B5 (1 << 4) ++ ++typedef struct { ++ unsigned char buttons; ++ unsigned char x; ++ unsigned char y; ++ unsigned char z; ++} __attribute__((packed)) mouse_packet_t; ++ ++static void orangeReadInput(InputInfoPtr pInfo) { ++ MouseDevPtr mouse = pInfo->private; ++ mouse_packet_t packet; ++ int x = 0; ++ int y = 0; ++ int z = 0; ++ unsigned char buttons = 0; ++ while(read(pInfo->fd, &packet, sizeof(packet)) == sizeof(packet)){ ++ x += (char)packet.x; ++ y += (char)packet.y; ++ z += (char)packet.z; ++ buttons |= packet.buttons; ++ ++ } ++ ++ int b = mouse->lastButtons; ++ b &= ~0x7; ++b |= (buttons & MOUSE_RB) ? 1 : 0; ++ b |= (buttons & MOUSE_MB) ? 2 : 0; ++ b |= (buttons & MOUSE_LB) ? 4 : 0; ++ ++ mouse->PostEvent(pInfo, b, x, -y, z, 0); ++ ++ ++ ++} ++ ++static Bool orangePreInit(InputInfoPtr pInfo, const char *proto, int flag) { ++ MouseDevPtr mouse; ++ ++ mouse = pInfo->private; ++ ++ mouse->protocol = proto; ++ ++ xf86ProcessCommonOptions(pInfo, pInfo->options); ++ ++ pInfo->fd = xf86OpenSerial(pInfo->options); ++ if (pInfo->fd == -1) { ++ xf86Msg(X_ERROR, "%s: cannot open mouse device!\n", pInfo->name); ++ return FALSE; ++ } ++ ++ mouse->CommonOptions(pInfo); ++ pInfo->read_input = orangeReadInput; ++ return true; ++} ++ ++#define DEVPATH "/dev/mouse" ++ ++static const char *getdevice(InputInfoPtr pInfo, const char *proto, int flag){ ++ pInfo->options = xf86AddNewOption(pInfo->options, "Device", DEVPATH); ++ return DEVPATH; ++} ++ ++static int interfacesupport() { ++ return MSE_PS2; ++} ++ ++static const char *names[] = { ++ "orangeMouseDev", NULL ++}; ++ ++static const char **protonames() { ++ return names; ++} ++ ++static const char *defaultproto() { ++ return "orangeMouseDev"; ++} ++ ++static Bool isdefault(const char *protocol) { ++ return strcmp(protocol, defaultproto()) == 0; ++} ++ ++OSMouseInfoPtr OSMouseInit(int flag) { ++ OSMouseInfoPtr p; ++ ++ p = calloc(sizeof(OSMouseInfoRec), 1); ++ ++ if (p == NULL) ++ return NULL; ++ ++ p->SupportedInterfaces = interfacesupport; ++ p->BuiltinNames = protonames; ++ p->FindDevice = getdevice; ++ p->DefaultProtocol = defaultproto; ++ p->CheckProtocol = isdefault; ++ p->PreInit = orangePreInit; ++ return p; ++} diff --git a/tools/pkg/5/xorg-modules/pkg.sh b/tools/pkg/5/xorg-modules/pkg.sh index 8f3811b..59dd75e 100644 --- a/tools/pkg/5/xorg-modules/pkg.sh +++ b/tools/pkg/5/xorg-modules/pkg.sh @@ -27,3 +27,4 @@ cp -rf etc/* "$1/etc" CFLAGS="-fPIC" SYSROOT="$1/" fast_install "$1" https://www.x.org/releases/individual/driver/xf86-video-fbdev-0.5.1.tar.gz "--disable-pciaccess --disable-static --enable-shared" "../../diff/xfbdev.diff" CFLAGS="-fPIC" SYSROOT="$1/" fast_install "$1" https://www.x.org/releases/individual/driver/xf86-input-keyboard-2.1.0.tar.gz "--disable-static --enable-shared" "../../diff/xkeyboard.diff" +CFLAGS="-fPIC" SYSROOT="$1/" fast_install "$1" https://xorg.freedesktop.org/archive/individual/driver/xf86-input-mouse-1.9.5.tar.gz "--enable-shared" "../../diff/xmouse.diff"
\ No newline at end of file diff --git a/tools/pkg/5/twm/diff/xterm.diff b/tools/pkg/6/terms/diff/xterm.diff index c2d2714..c2d2714 100644 --- a/tools/pkg/5/twm/diff/xterm.diff +++ b/tools/pkg/6/terms/diff/xterm.diff diff --git a/tools/pkg/6/terms/info.txt b/tools/pkg/6/terms/info.txt new file mode 100644 index 0000000..60d89d6 --- /dev/null +++ b/tools/pkg/6/terms/info.txt @@ -0,0 +1 @@ +xterms
\ No newline at end of file diff --git a/tools/pkg/6/terms/pkg.sh b/tools/pkg/6/terms/pkg.sh new file mode 100644 index 0000000..ae28abe --- /dev/null +++ b/tools/pkg/6/terms/pkg.sh @@ -0,0 +1,22 @@ +. ../../pkg-lib.sh + +rm -rf pack +mkdir -p pack + +cd pack + +git clone https://github.com/Shourai/st.git +cd st + +mkdir build + +CC=x86_64-orange-mlibc-gcc CXX=x86_64-orange-mlibc-g++ CPP=x86_64-orange-mlibc-g++ LD=x86_64-orange-mlibc-ld PKGCONFIG=x86_64-orange-mlibc-pkg-config PKG_CONFIG=x86_64-orange-mlibc-pkg-config make -j$(nproc) CFLAGS="-Wno-implicit-function-declaration -fPIC" +CC=x86_64-orange-mlibc-gcc CXX=x86_64-orange-mlibc-g++ CPP=x86_64-orange-mlibc-g++ LD=x86_64-orange-mlibc-ld PKGCONFIG=x86_64-orange-mlibc-pkg-config PKG_CONFIG=x86_64-orange-mlibc-pkg-config make install DESTDIR="$(realpath build)" + +cp -rf build/usr/local/* "$1/usr/" + +cd .. + +fast_install "$1" https://invisible-mirror.net/archives/xterm/xterm-390.tgz "--disable-tcap-fkeys --disable-tcap-query --enable-256-color" "../../diff/xterm.diff" +fast_install "$1" https://www.x.org/archive/individual/lib/libXrandr-1.5.3.tar.gz +fast_install "$1" https://www.x.org/archive/individual/app/xev-1.2.5.tar.gz
\ No newline at end of file diff --git a/tools/pkg/toolchain.cmake b/tools/pkg/toolchain.cmake index eca7a3b..f347207 100644 --- a/tools/pkg/toolchain.cmake +++ b/tools/pkg/toolchain.cmake @@ -5,5 +5,7 @@ set(CMAKE_SYSTEM_PROCESSOR x86_64) set(CMAKE_C_COMPILER x86_64-orange-mlibc-gcc) set(CMAKE_LINKER x86_64-orange-mlibc-ld) +set(CMAKE_POSITION_INDEPENDENT_CODE ON) + set(CMAKE_CXX_EXTENSIONS ON) set(CMAKE_C_EXTENSIONS ON)
\ No newline at end of file diff --git a/tools/toolchain-build.sh b/tools/toolchain-build.sh index 8c5890c..dd8c22a 100644 --- a/tools/toolchain-build.sh +++ b/tools/toolchain-build.sh @@ -1,5 +1,9 @@ set -e +export CFLAGS="-fPIC" +export CXXFLAGS="-fPIC" +export CPPFLAGS="-fPIC" + GNU_MIRROR=https://mirror.dogado.de/ CURRENT_DIR="$(realpath .)" |
