summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcpplover0 <osdev555@yandex.com>2025-11-11 07:22:26 +0300
committercpplover0 <osdev555@yandex.com>2025-11-11 07:22:26 +0300
commit165c5f2dbdb2a348266d0cc8ee20ced4d9fb1bdb (patch)
treee28a60e439c315a535940027f929d601687f0e4a
parent87e973d53cd59e5d578f594fd23fa6ee446c4aa3 (diff)
twm st port a lot of bug fixes and finally working xorg port
-rw-r--r--.gitignore1
-rw-r--r--GNUmakefile2
-rw-r--r--kernel/include/arch/x86_64/cpu/data.hpp1
-rw-r--r--kernel/include/arch/x86_64/interrupts/irq.hpp1
-rw-r--r--kernel/include/arch/x86_64/scheduling.hpp2
-rw-r--r--kernel/include/arch/x86_64/syscalls/syscalls.hpp3
-rw-r--r--kernel/include/etc/list.hpp14
-rw-r--r--kernel/include/generic/mm/pmm.hpp17
-rw-r--r--kernel/include/generic/mm/vmm.hpp29
-rw-r--r--kernel/include/generic/vfs/devfs.hpp23
-rw-r--r--kernel/include/generic/vfs/fd.hpp23
-rw-r--r--kernel/include/generic/vfs/vfs.hpp117
-rw-r--r--kernel/src/arch/x86_64/cpu/smp.cpp2
-rw-r--r--kernel/src/arch/x86_64/interrupts/irq.cpp16
-rw-r--r--kernel/src/arch/x86_64/interrupts/panic.cpp4
-rw-r--r--kernel/src/arch/x86_64/scheduling.cpp26
-rw-r--r--kernel/src/arch/x86_64/syscalls/file.cpp99
-rw-r--r--kernel/src/arch/x86_64/syscalls/futex.cpp4
-rw-r--r--kernel/src/arch/x86_64/syscalls/process.cpp66
-rw-r--r--kernel/src/arch/x86_64/syscalls/syscalls.cpp17
-rw-r--r--kernel/src/drivers/acpi.cpp2
-rw-r--r--kernel/src/generic/mm/pmm.cpp41
-rw-r--r--kernel/src/generic/vfs/devfs.cpp333
-rw-r--r--kernel/src/generic/vfs/tmpfs.cpp3
-rw-r--r--kernel/src/generic/vfs/vfs.cpp59
-rw-r--r--readme.md13
-rwxr-xr-xtar-initrd.sh2
-rw-r--r--tools/base/etc/shells1
-rw-r--r--tools/initbase/etc/X11/xinitrc5
-rw-r--r--tools/initbase/var/run/utmp0
-rw-r--r--tools/pkg/2/init/src/include/etc.hpp291
-rw-r--r--tools/pkg/2/init/src/main.cpp395
-rw-r--r--tools/pkg/2/ps2_driver/pkg.sh2
-rw-r--r--tools/pkg/2/ps2_driver/src/main.c289
-rw-r--r--tools/pkg/2/xhci_driver/pkg.sh2
-rw-r--r--tools/pkg/2/xhci_driver/src/main.cpp116
-rw-r--r--tools/pkg/3/coreutils/pkg.sh2
-rw-r--r--tools/pkg/3/mouse_test/info.txt1
-rw-r--r--tools/pkg/3/mouse_test/main.c194
-rw-r--r--tools/pkg/3/mouse_test/pkg.sh2
-rw-r--r--tools/pkg/4/xorg-server/pkg.sh10
-rw-r--r--tools/pkg/5/orangex/info.txt1
-rw-r--r--tools/pkg/5/orangex/main.sh4
-rw-r--r--tools/pkg/5/orangex/pkg.sh3
-rw-r--r--tools/pkg/5/twm/pkg.sh1
-rw-r--r--tools/pkg/5/xorg-modules/diff/xmouse.diff154
-rw-r--r--tools/pkg/5/xorg-modules/pkg.sh1
-rw-r--r--tools/pkg/6/terms/diff/xterm.diff (renamed from tools/pkg/5/twm/diff/xterm.diff)0
-rw-r--r--tools/pkg/6/terms/info.txt1
-rw-r--r--tools/pkg/6/terms/pkg.sh22
-rw-r--r--tools/pkg/toolchain.cmake2
-rw-r--r--tools/toolchain-build.sh4
52 files changed, 1829 insertions, 594 deletions
diff --git a/.gitignore b/.gitignore
index 361dc84..2100be2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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:
diff --git a/readme.md b/readme.md
index 408a10b..cc90ba2 100644
--- a/readme.md
+++ b/readme.md
@@ -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 .)"