diff options
author | Anton Kling <anton@kling.gg> | 2024-03-17 20:55:34 +0100 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2024-03-17 20:55:34 +0100 |
commit | 0dccff86e50dfe1555b8bc29862dba2b972a3705 (patch) | |
tree | 8d0c354c65278afdc3427bb52e1e63900ccdbc05 | |
parent | 2e8b474d4219e7faaac3823e73c8d528c2698a37 (diff) |
stuff
31 files changed, 186 insertions, 223 deletions
diff --git a/kernel/cpu/arch_inst.h b/kernel/cpu/arch_inst.h index 54faffb..3d4e1c5 100644 --- a/kernel/cpu/arch_inst.h +++ b/kernel/cpu/arch_inst.h @@ -9,3 +9,4 @@ void set_sbp(uintptr_t); void set_cr3(uintptr_t); uintptr_t get_cr3(void); void enable_paging(void); +void wait_for_interrupt(void); diff --git a/kernel/cpu/arch_inst.s b/kernel/cpu/arch_inst.s index aaf34b6..a993172 100644 --- a/kernel/cpu/arch_inst.s +++ b/kernel/cpu/arch_inst.s @@ -9,6 +9,7 @@ .global set_cr3 .global get_cr3 .global enable_paging +.global wait_for_interrupt get_current_sp: mov eax, esp @@ -30,6 +31,11 @@ set_sbp: mov ebp, eax ret +wait_for_interrupt: + sti + hlt + ret + halt: hlt jmp $ diff --git a/kernel/cpu/syscall.c b/kernel/cpu/syscall.c index c982648..6b260d3 100644 --- a/kernel/cpu/syscall.c +++ b/kernel/cpu/syscall.c @@ -53,13 +53,13 @@ int syscall_pread(SYS_PREAD_PARAMS *args) { return vfs_pread(args->fd, args->buf, args->count, args->offset); } -int syscall_read(SYS_READ_PARAMS *args) { - vfs_fd_t *fd = get_vfs_fd(args->fd); - if (!fd) { +int syscall_mread(int fd, void *buf, size_t count, int blocking) { + vfs_fd_t *fd_ptr = get_vfs_fd(fd, NULL); + if (!fd_ptr) { return -EBADF; } - int rc = vfs_pread(args->fd, args->buf, args->count, fd->offset); - fd->offset += rc; + int rc = vfs_pmread(fd, buf, count, blocking, fd_ptr->offset); + fd_ptr->offset += rc; return rc; } @@ -152,7 +152,7 @@ int syscall_tcp_read(u32 socket, u8 *buffer, u32 buffer_size, u64 *out) { int (*syscall_functions[])() = { (void(*))syscall_open, - (void(*))syscall_read, + (void(*))syscall_mread, (void(*))syscall_write, (void(*))syscall_pread, (void(*))syscall_pwrite, diff --git a/kernel/drivers/ahci.c b/kernel/drivers/ahci.c index 5a65408..f655709 100644 --- a/kernel/drivers/ahci.c +++ b/kernel/drivers/ahci.c @@ -2,6 +2,7 @@ #include <drivers/pci.h> #include <fs/devfs.h> #include <fs/vfs.h> +#include <math.h> #include <mmu.h> #include <stdio.h> @@ -312,7 +313,7 @@ u8 ahci_perform_command(volatile struct HBA_PORT *port, u32 startl, u32 starth, u8 err; u32 command_slot = get_free_command_slot(port, &err); if (err) { - klog("No command slot found", LOG_WARN); + klog("AHCI No command slot found", LOG_WARN); return 0; } struct HBA_CMD_HEADER *cmdheader = @@ -372,7 +373,7 @@ u8 ahci_perform_command(volatile struct HBA_PORT *port, u32 startl, u32 starth, spin++; } if (spin == 10000) { - kprintf("Port is hung\n"); + klog("AHCI port is hung", LOG_ERROR); return 0; } @@ -385,16 +386,15 @@ u8 ahci_perform_command(volatile struct HBA_PORT *port, u32 startl, u32 starth, if ((port->ci & (1 << command_slot)) == 0) { break; } - if (port->is & HBA_PxIS_TFES) // Task file error - { - kprintf("Read disk error\n"); + if (port->is & HBA_PxIS_TFES) { + klog("AHCI command failed", LOG_ERROR); return 0; } } // Check again if (port->is & HBA_PxIS_TFES) { - kprintf("Read disk error\n"); + klog("AHCI command failed", LOG_ERROR); return 0; } @@ -417,21 +417,37 @@ int ahci_write(u8 *buffer, u64 offset, u64 len, vfs_fd_t *fd) { assert(port == 0); u32 lba = offset / 512; offset %= 512; - int rc = len; + const int rc = len; u32 sector_count = len / 512; if (len % 512 != 0) { sector_count++; } + + if (offset > 0) { + u8 tmp_buffer[512]; + ahci_raw_read(&hba->ports[port], lba, 0, 1, (u16 *)tmp_buffer); + + int left = 512 - offset; + int write = min(left, len); + + memcpy(tmp_buffer + offset, buffer, write); + ahci_raw_write(&hba->ports[port], lba, 0, 1, (u16 *)tmp_buffer); + + offset = 0; + len -= write; + sector_count--; + lba++; + } + for (; sector_count >= num_prdt; lba++) { ahci_raw_write(&hba->ports[port], lba, 0, num_prdt, (u16 *)buffer); - offset = 0; buffer += num_prdt * 512; len -= num_prdt * 512; sector_count -= num_prdt; } - if (sector_count > 0) { + if (sector_count > 0 && len > 0) { u8 tmp_buffer[512 * num_prdt]; ahci_raw_read(&hba->ports[port], lba, 0, sector_count, (u16 *)tmp_buffer); memcpy(tmp_buffer + offset, buffer, len); diff --git a/kernel/drivers/keyboard.c b/kernel/drivers/keyboard.c index ec87390..7d35dc1 100644 --- a/kernel/drivers/keyboard.c +++ b/kernel/drivers/keyboard.c @@ -185,7 +185,6 @@ int keyboard_read(u8 *buffer, u64 offset, u64 len, vfs_fd_t *fd) { } void add_keyboard(void) { - kprintf("very important"); kb_inode = devfs_add_file("/keyboard", keyboard_read, NULL, NULL, 0, 0, FS_TYPE_CHAR_DEVICE); } diff --git a/kernel/drivers/mouse.c b/kernel/drivers/mouse.c index a829318..7096ae9 100644 --- a/kernel/drivers/mouse.c +++ b/kernel/drivers/mouse.c @@ -42,7 +42,7 @@ void add_mouse(void) { mouse_inode->internal_object = create_fifo_object(); // Don't look at this int fd = vfs_open("/dev/mouse", O_RDWR, 0); - mouse_fd = get_vfs_fd(fd); + mouse_fd = get_vfs_fd(fd, NULL); current_task->file_descriptors[fd] = NULL; } diff --git a/kernel/drivers/pst.c b/kernel/drivers/pst.c index f8a0414..77b1b8b 100644 --- a/kernel/drivers/pst.c +++ b/kernel/drivers/pst.c @@ -12,8 +12,8 @@ int openpty(int *amaster, int *aslave, char *name, pipe(fd); // This depends upon that pipe will support read and write // through the same fd. In reality this should not be the // case. - get_vfs_fd(fd[0])->is_tty = 1; - get_vfs_fd(fd[1])->is_tty = 1; + get_vfs_fd(fd[0], NULL)->is_tty = 1; + get_vfs_fd(fd[1], NULL)->is_tty = 1; *amaster = fd[0]; *aslave = fd[1]; return 0; diff --git a/kernel/fs/vfs.c b/kernel/fs/vfs.c index 76e6778..6a8dfd1 100644 --- a/kernel/fs/vfs.c +++ b/kernel/fs/vfs.c @@ -8,7 +8,10 @@ vfs_inode_t *root_dir; vfs_mounts_t mounts[10]; int num_mounts = 0; -vfs_fd_t *get_vfs_fd(int fd) { +vfs_fd_t *get_vfs_fd(int fd, process_t *p) { + if (!p) { + p = current_task; + } if (fd >= 100) { klog("get_vfs_fd(): Tried to get out of range fd", LOG_WARN); dump_backtrace(12); @@ -19,7 +22,7 @@ vfs_fd_t *get_vfs_fd(int fd) { dump_backtrace(12); return NULL; } - return current_task->file_descriptors[fd]; + return p->file_descriptors[fd]; } vfs_inode_t *vfs_create_inode( @@ -206,7 +209,7 @@ char *vfs_resolve_path(const char *file, char *resolved_path) { } int vfs_fstat(int fd, struct stat *buf) { - vfs_fd_t *fd_ptr = get_vfs_fd(fd); + vfs_fd_t *fd_ptr = get_vfs_fd(fd, NULL); if (!fd_ptr) { return -EBADF; } @@ -290,7 +293,7 @@ int vfs_open(const char *file, int flags, int mode) { } int vfs_close(int fd) { - vfs_fd_t *fd_ptr = get_vfs_fd(fd); + vfs_fd_t *fd_ptr = get_vfs_fd(fd, NULL); if (NULL == fd_ptr) { return -1; } @@ -316,7 +319,7 @@ int raw_vfs_pread(vfs_fd_t *vfs_fd, void *buf, u64 count, u64 offset) { return vfs_fd->inode->read(buf, offset, count, vfs_fd); } -int vfs_pread(int fd, void *buf, u64 count, u64 offset) { +int vfs_pmread(int fd, void *buf, u64 count, int blocking, u64 offset) { if (fd >= 100) { kprintf("EBADF : %x\n", fd); return -EBADF; @@ -332,7 +335,7 @@ int vfs_pread(int fd, void *buf, u64 count, u64 offset) { } int rc = raw_vfs_pread(vfs_fd, buf, count, offset); if (-EAGAIN == rc && count > 0) { - if (!(vfs_fd->flags & O_NONBLOCK)) { + if (!(vfs_fd->flags & O_NONBLOCK) && blocking) { struct pollfd fds; do { fds.fd = fd; @@ -349,6 +352,10 @@ int vfs_pread(int fd, void *buf, u64 count, u64 offset) { return rc; } +int vfs_pread(int fd, void *buf, u64 count, u64 offset) { + return vfs_pmread(fd, buf, count, 1, offset); +} + int raw_vfs_pwrite(vfs_fd_t *vfs_fd, void *buf, u64 count, u64 offset) { assert(vfs_fd); assert(vfs_fd->inode); @@ -357,7 +364,7 @@ int raw_vfs_pwrite(vfs_fd_t *vfs_fd, void *buf, u64 count, u64 offset) { } int vfs_pwrite(int fd, void *buf, u64 count, u64 offset) { - vfs_fd_t *vfs_fd = get_vfs_fd(fd); + vfs_fd_t *vfs_fd = get_vfs_fd(fd, NULL); if (!vfs_fd) { return -EBADF; } @@ -368,7 +375,7 @@ int vfs_pwrite(int fd, void *buf, u64 count, u64 offset) { } vfs_vm_object_t *vfs_get_vm_object(int fd, u64 length, u64 offset) { - vfs_fd_t *vfs_fd = get_vfs_fd(fd); + vfs_fd_t *vfs_fd = get_vfs_fd(fd, NULL); if (!vfs_fd) { return NULL; } @@ -384,7 +391,7 @@ int vfs_dup2(int org_fd, int new_fd) { } int vfs_ftruncate(int fd, size_t length) { - vfs_fd_t *fd_ptr = get_vfs_fd(fd); + vfs_fd_t *fd_ptr = get_vfs_fd(fd, NULL); if (!fd_ptr) { return -EBADF; } diff --git a/kernel/fs/vfs.h b/kernel/fs/vfs.h index 77d9efd..bee3179 100644 --- a/kernel/fs/vfs.h +++ b/kernel/fs/vfs.h @@ -1,9 +1,9 @@ +#ifndef VFS_H +#define VFS_H typedef struct vfs_fd vfs_fd_t; typedef struct vfs_inode vfs_inode_t; typedef struct vfs_vm_object vfs_vm_object_t; typedef struct vfs_mounts vfs_mounts_t; -#ifndef VFS_H -#define VFS_H #include <dirent.h> #include <limits.h> #include <sched/scheduler.h> @@ -70,12 +70,13 @@ struct vfs_inode { }; int vfs_close(int fd); -vfs_fd_t *get_vfs_fd(int fd); +vfs_fd_t *get_vfs_fd(int fd, process_t *p); int vfs_open(const char *file, int flags, int mode); void vfs_mount(char *path, vfs_inode_t *local_root); int vfs_pwrite(int fd, void *buf, u64 count, u64 offset); int raw_vfs_pwrite(vfs_fd_t *vfs_fd, void *buf, u64 count, u64 offset); int raw_vfs_pread(vfs_fd_t *vfs_fd, void *buf, u64 count, u64 offset); +int vfs_pmread(int fd, void *buf, u64 count, int blocking, u64 offset); int vfs_pread(int fd, void *buf, u64 count, u64 offset); vfs_vm_object_t *vfs_get_vm_object(int fd, u64 length, u64 offset); int vfs_dup2(int org_fd, int new_fd); diff --git a/kernel/init/kernel.c b/kernel/init/kernel.c index edff4f1..db7fb27 100644 --- a/kernel/init/kernel.c +++ b/kernel/init/kernel.c @@ -1,4 +1,5 @@ #include <assert.h> +#include <cpu/arch_inst.h> #include <cpu/gdt.h> #include <cpu/idt.h> #include <cpu/spinlock.h> @@ -121,35 +122,13 @@ void kernel_main(u32 kernel_end, unsigned long magic, unsigned long addr, */ ipv4_t gateway; - gateway.d = gen_ipv4(10, 0, 2, 2); + gen_ipv4(&gateway, 10, 0, 2, 2); ipv4_t bitmask; - bitmask.d = gen_ipv4(255, 255, 255, 0); + gen_ipv4(&bitmask, 255, 255, 255, 0); setup_network(gateway, bitmask); - /* - // u32 ip = gen_ipv4(10, 0, 2, 2); - u32 ip = gen_ipv4(93, 184, 216, 34); - int err; - u32 socket = tcp_connect_ipv4(ip, 80, &err); - assert(!err); - kprintf("socket: %x\n", socket); - u64 out; - char *http_request = "GET /\r\n\r\n"; - assert(tcp_write(socket, http_request, strlen(http_request), &out)); - kprintf("sent: %x over the tcp socket\n", out); - - for (;;) { - char buffer[256]; - assert(tcp_read(socket, buffer, 256, &out)); - kprintf("got %x bytes\n", out); - for (int i = 0; i < out; i++) { - kprintf("%c", buffer[i]); - } - } + gen_ipv4(&ip_address, 10, 0, 2, 15); - for (;;) - ; - */ display_driver_init(mb); add_vbe_device(); int pid; @@ -161,7 +140,6 @@ void kernel_main(u32 kernel_end, unsigned long magic, unsigned long addr, } for (;;) { current_task->sleep_until = pit_num_ms() + 100000000; - // enable_interrupts(); - switch_task(); + wait_for_interrupt(); } } diff --git a/kernel/network/arp.c b/kernel/network/arp.c index 576a09a..d4cf0dd 100644 --- a/kernel/network/arp.c +++ b/kernel/network/arp.c @@ -1,11 +1,11 @@ #include <assert.h> #include <drivers/rtl8139.h> +#include <interrupts.h> #include <network/arp.h> #include <network/bytes.h> #include <network/ethernet.h> #include <stdio.h> #include <string.h> -#include <interrupts.h> ipv4_t gateway; ipv4_t bitmask; @@ -38,7 +38,7 @@ struct ARP_TABLE_ENTRY { struct ARP_TABLE_ENTRY arp_table[10] = {0}; // FIXME: This is hardcoded, don't do this. -u8 ip_address[4] = {10, 0, 2, 15}; +ipv4_t ip_address; struct ARP_TABLE_ENTRY *find_arp_entry_to_use(void) { // This does not need to find a "free" entry as a ARP table is @@ -73,7 +73,7 @@ void print_ip(const char *str, const u8 *ip) { kprintf("\n"); } -void send_arp_request(const u8 ip[4]) { +void send_arp_request(const ipv4_t ip) { struct ARP_DATA data; data.htype = htons(1); data.ptype = htons(0x0800); @@ -83,10 +83,10 @@ void send_arp_request(const u8 ip[4]) { data.opcode = htons(0x0001); get_mac_address(data.srchw); - memcpy(data.srcpr, ip_address, sizeof(u8[4])); + memcpy(data.srcpr, &ip_address, sizeof(ipv4_t)); memset(data.dsthw, 0, sizeof(u8[6])); - memcpy(data.dstpr, ip, sizeof(u8[4])); + memcpy(data.dstpr, &ip, sizeof(ipv4_t)); u8 broadcast[6]; memset(broadcast, 0xFF, sizeof(broadcast)); @@ -100,15 +100,13 @@ int ip_inside_network(const ipv4_t ip) { return 0; } -int get_mac_from_ip(const u8 ip[4], u8 mac[6]) { - ipv4_t tmp_ip; - memcpy(tmp_ip.a, ip, sizeof(u8[4])); - if (!ip_inside_network(tmp_ip)) { - return get_mac_from_ip(gateway.a, mac); +int get_mac_from_ip(const ipv4_t ip, u8 mac[6]) { + if (!ip_inside_network(ip)) { + return get_mac_from_ip(gateway, mac); } for (int i = 0; i < 10; i++) { - if (0 != memcmp(arp_table[i].ip, ip, sizeof(u8[4]))) { + if (0 != memcmp(arp_table[i].ip, &ip, sizeof(u8[4]))) { continue; } memcpy(mac, arp_table[i].mac, sizeof(u8[6])); @@ -119,7 +117,7 @@ int get_mac_from_ip(const u8 ip[4], u8 mac[6]) { send_arp_request(ip); // TODO: Maybe wait a bit? for (int i = 0; i < 10; i++) { - if (0 != memcmp(arp_table[i].ip, ip, sizeof(u8[4]))) { + if (0 != memcmp(arp_table[i].ip, &ip, sizeof(u8[4]))) { continue; } memcpy(mac, arp_table[i].mac, sizeof(u8[6])); @@ -142,10 +140,10 @@ void handle_arp(const u8 *payload) { if (0x0001 /*arp_request*/ == ntohs(data->opcode)) { struct ARP_TABLE_ENTRY *entry = find_arp_entry_to_use(); entry->is_used = 1; - memcpy(entry->mac, data->srchw, sizeof(uint8_t[6])); - memcpy(entry->ip, data->srcpr, sizeof(uint8_t[4])); + memcpy(entry->mac, data->srchw, sizeof(u8[6])); + memcpy(entry->ip, data->srcpr, sizeof(u8[4])); - assert(0 == memcmp(data->dstpr, ip_address, sizeof(uint8_t[4]))); + assert(0 == memcmp(data->dstpr, &ip_address, sizeof(u8[4]))); // Now we have to construct a ARP response struct ARP_DATA response; @@ -155,7 +153,7 @@ void handle_arp(const u8 *payload) { response.hlen = 6; response.plen = 4; get_mac_address(response.srchw); - memcpy(response.srcpr, ip_address, sizeof(u8[4])); + memcpy(response.srcpr, &ip_address, sizeof(u8[4])); memcpy(response.dsthw, data->srchw, sizeof(u8[6])); memcpy(response.dstpr, data->srcpr, sizeof(u8[4])); diff --git a/kernel/network/arp.h b/kernel/network/arp.h index 3795a62..e2d2fe1 100644 --- a/kernel/network/arp.h +++ b/kernel/network/arp.h @@ -1,6 +1,7 @@ #include <typedefs.h> +extern ipv4_t ip_address; void setup_network(ipv4_t _gateway, ipv4_t _bitmask); -int get_mac_from_ip(const u8 ip[4], u8 mac[6]); -void send_arp_request(const u8 ip[4]); +int get_mac_from_ip(const ipv4_t ip, u8 mac[6]); +void send_arp_request(const ipv4_t ip); void handle_arp(const u8 *payload); diff --git a/kernel/network/ipv4.c b/kernel/network/ipv4.c index 6335a09..4fe3799 100644 --- a/kernel/network/ipv4.c +++ b/kernel/network/ipv4.c @@ -40,16 +40,15 @@ u16 ip_checksum(void *vdata, size_t length) { return htons(~acc); } -extern u8 ip_address[4]; -void send_ipv4_packet(u32 ip, u8 protocol, const u8 *payload, u16 length) { +void send_ipv4_packet(ipv4_t ip, u8 protocol, const u8 *payload, u16 length) { u8 header[20] = {0}; header[0] = (4 /*version*/ << 4) | (5 /*IHL*/); *((u16 *)(header + 2)) = htons(length + 20); header[8 /*TTL*/] = 0xF8; header[9] = protocol; - memcpy(header + 12 /*src_ip*/, ip_address, sizeof(u8[4])); - memcpy(header + 16, &ip, sizeof(u8[4])); + memcpy(header + 12 /*src_ip*/, &ip_address, sizeof(ipv4_t)); + memcpy(header + 16, &ip, sizeof(ipv4_t)); *((u16 *)(header + 10 /*checksum*/)) = ip_checksum(header, 20); u16 packet_length = length + 20; @@ -58,9 +57,7 @@ void send_ipv4_packet(u32 ip, u8 protocol, const u8 *payload, u16 length) { memcpy(packet + 20, payload, length); u8 mac[6]; - u8 ip_copy[4]; // TODO: Do I need to do this? - memcpy(ip_copy, &ip, sizeof(u8[4])); - for (; !get_mac_from_ip(ip_copy, mac);) + for (; !get_mac_from_ip(ip, mac);) ; send_ethernet_packet(mac, 0x0800, packet, packet_length); kfree(packet); @@ -86,8 +83,8 @@ void handle_ipv4(const u8 *payload, u32 packet_length) { // Make sure the ipv4 header is not trying to get uninitalized memory assert(ipv4_total_length <= packet_length); - u8 src_ip[4]; - memcpy(src_ip, payload + 12, sizeof(u8[4])); + ipv4_t src_ip; + memcpy(&src_ip, payload + 12, sizeof(u8[4])); u8 protocol = *(payload + 9); switch (protocol) { diff --git a/kernel/network/ipv4.h b/kernel/network/ipv4.h index 002aaa7..7b44eb1 100644 --- a/kernel/network/ipv4.h +++ b/kernel/network/ipv4.h @@ -1,4 +1,4 @@ #include <typedefs.h> void handle_ipv4(const u8 *payload, u32 packet_length); -void send_ipv4_packet(u32 ip, u8 protocol, const u8 *payload, u16 length); +void send_ipv4_packet(ipv4_t ip, u8 protocol, const u8 *payload, u16 length); diff --git a/kernel/network/tcp.c b/kernel/network/tcp.c index fb3c052..b929005 100644 --- a/kernel/network/tcp.c +++ b/kernel/network/tcp.c @@ -1,9 +1,10 @@ #include <assert.h> +#include <cpu/arch_inst.h> #include <drivers/pit.h> +#include <network/arp.h> #include <network/bytes.h> #include <network/ipv4.h> #include <network/udp.h> -extern u8 ip_address[4]; #define CWR (1 << 7) #define ECE (1 << 6) @@ -53,8 +54,7 @@ void tcp_wait_reply(struct TcpConnection *con) { if (con->unhandled_packet) { return; } - // TODO: Make the scheduler halt the process - switch_task(); + wait_for_interrupt(); } } @@ -73,10 +73,10 @@ u16 tcp_checksum(u16 *buffer, int size) { return (u16)(~cksum); } -void tcp_calculate_checksum(u8 src_ip[4], u32 dst_ip, const u8 *payload, +void tcp_calculate_checksum(ipv4_t src_ip, u32 dst_ip, const u8 *payload, u16 payload_length, struct TCP_HEADER *header) { struct PSEUDO_TCP_HEADER ps = {0}; - memcpy(&ps.src_addr, src_ip, sizeof(u32)); + memcpy(&ps.src_addr, &src_ip.d, sizeof(u32)); memcpy(&ps.dst_addr, &dst_ip, sizeof(u32)); ps.protocol = 6; ps.tcp_length = htons(20 + payload_length); @@ -118,7 +118,7 @@ void tcp_send_empty_payload(struct TcpConnection *con, u8 flags) { memcpy(send_buffer, &header, sizeof(header)); memcpy(send_buffer + sizeof(header), payload, payload_length); - send_ipv4_packet(con->outgoing_ip, 6, send_buffer, send_len); + send_ipv4_packet((ipv4_t){.d = con->outgoing_ip}, 6, send_buffer, send_len); } void tcp_send_ack(struct TcpConnection *con) { @@ -130,8 +130,6 @@ void tcp_send_syn(struct TcpConnection *con) { con->seq++; } -// void send_tcp_packet(struct INCOMING_TCP_CONNECTION *inc, const u8 *payload, -// u16 payload_length) { void send_tcp_packet(struct TcpConnection *con, const u8 *payload, u16 payload_length) { if (payload_length > 1500 - 20 - sizeof(struct TCP_HEADER)) { @@ -156,12 +154,12 @@ void send_tcp_packet(struct TcpConnection *con, const u8 *payload, u8 send_buffer[send_len]; memcpy(send_buffer, &header, sizeof(header)); memcpy(send_buffer + sizeof(header), payload, payload_length); - send_ipv4_packet(con->outgoing_ip, 6, send_buffer, send_len); + send_ipv4_packet((ipv4_t){.d = con->outgoing_ip}, 6, send_buffer, send_len); con->seq += payload_length; } -void handle_tcp(u8 src_ip[4], const u8 *payload, u32 payload_length) { +void handle_tcp(ipv4_t src_ip, const u8 *payload, u32 payload_length) { const struct TCP_HEADER *header = (const struct TCP_HEADER *)payload; (void)header; u16 n_src_port = *(u16 *)(payload); @@ -180,9 +178,8 @@ void handle_tcp(u8 src_ip[4], const u8 *payload, u32 payload_length) { (void)ack_num; if (SYN == flags) { - u32 t; - memcpy(&t, src_ip, sizeof(u8[4])); - struct TcpConnection *con = internal_tcp_incoming(t, src_port, 0, dst_port); + struct TcpConnection *con = + internal_tcp_incoming(src_ip.d, src_port, 0, dst_port); assert(con); con->ack = seq_num + 1; tcp_send_empty_payload(con, SYN | ACK); @@ -191,6 +188,9 @@ void handle_tcp(u8 src_ip[4], const u8 *payload, u32 payload_length) { struct TcpConnection *incoming_connection = tcp_find_connection(dst_port); kprintf("dst_port: %d\n", dst_port); + if (!incoming_connection) { + kprintf("unable to find open port for incoming connection\n"); + } if (incoming_connection) { incoming_connection->unhandled_packet = 1; if (0 != (flags & RST)) { @@ -213,7 +213,6 @@ void handle_tcp(u8 src_ip[4], const u8 *payload, u32 payload_length) { tcp_send_ack(incoming_connection); } - // if (0 != (flags & PSH)) { u16 tcp_payload_length = payload_length - header->data_offset * sizeof(u32); if (tcp_payload_length > 0) { int len = fifo_object_write( @@ -236,83 +235,3 @@ void handle_tcp(u8 src_ip[4], const u8 *payload, u32 payload_length) { return; } } -/* -void handle_tcp(u8 src_ip[4], const u8 *payload, u32 payload_length) { - const struct TCP_HEADER *inc_header = (const struct TCP_HEADER *)payload; - u16 n_src_port = *(u16 *)(payload); - u16 n_dst_port = *(u16 *)(payload + 2); - u32 n_seq_num = *(u32 *)(payload + 4); - u32 n_ack_num = *(u32 *)(payload + 8); - - u8 flags = *(payload + 13); - - u16 src_port = htons(n_src_port); - (void)src_port; - u16 dst_port = htons(n_dst_port); - u32 seq_num = htonl(n_seq_num); - u32 ack_num = htonl(n_ack_num); - (void)ack_num; - - if (SYN == flags) { - struct INCOMING_TCP_CONNECTION *inc; - if (!(inc = handle_incoming_tcp_connection(src_ip, n_src_port, dst_port))) { - return; - } - memcpy(inc->ip, src_ip, sizeof(u8[4])); - inc->seq_num = 0; - inc->ack_num = seq_num + 1; - inc->connection_closed = 0; - inc->requesting_connection_close = 0; - send_empty_tcp_message(inc, SYN | ACK, seq_num, n_dst_port, n_src_port); - inc->seq_num++; - return; - } - struct INCOMING_TCP_CONNECTION *inc = - get_incoming_tcp_connection(src_ip, n_src_port); - if (!inc) { - return; - } - if (flags == (FIN | ACK)) { - if (inc->requesting_connection_close) { - send_empty_tcp_message(inc, ACK, seq_num, n_dst_port, n_src_port); - inc->connection_closed = 1; - } else { - send_empty_tcp_message(inc, FIN | ACK, seq_num, n_dst_port, n_src_port); - } - inc->seq_num++; - inc->connection_closed = 1; - return; - } - if (flags & ACK) { - // inc->seq_num = ack_num; - } - if (flags & PSH) { - kprintf("TCP: Got PSH\n"); - u16 tcp_payload_length = - payload_length - inc_header->data_offset * sizeof(u32); - int rc = fifo_object_write( - (u8 *)(payload + inc_header->data_offset * sizeof(u32)), 0, - tcp_payload_length, inc->data_file); - kprintf("fifo object write rc: %x\n", rc); - *inc->has_data_ptr = 1; - - // Send back a ACK - struct TCP_HEADER header = {0}; - header.src_port = n_dst_port; - header.dst_port = n_src_port; - header.seq_num = htonl(inc->seq_num); - inc->ack_num = seq_num + tcp_payload_length; - header.ack_num = htonl(seq_num + tcp_payload_length); - header.data_offset = 5; - header.reserved = 0; - header.flags = ACK; - header.window_size = htons(WINDOW_SIZE); - header.urgent_pointer = 0; - u32 dst_ip; - memcpy(&dst_ip, src_ip, sizeof(dst_ip)); - char payload[0]; - tcp_calculate_checksum(ip_address, dst_ip, (const u8 *)payload, 0, &header); - send_ipv4_packet(dst_ip, 6, (const u8 *)&header, sizeof(header)); - return; - } -}*/ diff --git a/kernel/network/tcp.h b/kernel/network/tcp.h index 0f9e818..0c53535 100644 --- a/kernel/network/tcp.h +++ b/kernel/network/tcp.h @@ -1,7 +1,8 @@ #include <socket.h> +#include <typedefs.h> void tcp_send_syn(struct TcpConnection *con); void tcp_wait_reply(struct TcpConnection *con); -void handle_tcp(u8 src_ip[4], const u8 *payload, u32 payload_length); +void handle_tcp(ipv4_t src_ip, const u8 *payload, u32 payload_length); void send_tcp_packet(struct TcpConnection *con, const u8 *payload, u16 payload_length); - void tcp_close_connection(struct INCOMING_TCP_CONNECTION * s); +void tcp_close_connection(struct INCOMING_TCP_CONNECTION *s); diff --git a/kernel/network/udp.c b/kernel/network/udp.c index 4f3848a..1112c3d 100644 --- a/kernel/network/udp.c +++ b/kernel/network/udp.c @@ -15,11 +15,11 @@ void send_udp_packet(struct sockaddr_in *src, const struct sockaddr_in *dst, u8 *packet = kmalloc(packet_length); memcpy(packet, header, sizeof(header)); memcpy(packet + sizeof(header), payload, payload_length); - send_ipv4_packet(dst->sin_addr.s_addr, 0x11, packet, packet_length); + send_ipv4_packet((ipv4_t){.d = dst->sin_addr.s_addr}, 0x11, packet, packet_length); kfree(packet); } -void handle_udp(u8 src_ip[4], const u8 *payload, u32 packet_length) { +void handle_udp(ipv4_t src_ip, const u8 *payload, u32 packet_length) { // TODO: Reimplement assert(NULL); } diff --git a/kernel/network/udp.h b/kernel/network/udp.h index fe21b0f..bcf31bc 100644 --- a/kernel/network/udp.h +++ b/kernel/network/udp.h @@ -1,6 +1,6 @@ #include <socket.h> #include <typedefs.h> -void handle_udp(u8 src_ip[4], const u8 *payload, u32 packet_length); +void handle_udp(ipv4_t src_ip, const u8 *payload, u32 packet_length); void send_udp_packet(struct sockaddr_in *src, const struct sockaddr_in *dst, const u8 *payload, u16 payload_length); diff --git a/kernel/poll.c b/kernel/poll.c index 8174657..7107646 100644 --- a/kernel/poll.c +++ b/kernel/poll.c @@ -18,7 +18,7 @@ int poll(struct pollfd *fds, size_t nfds, int timeout) { if (fds[i].fd < 0) { continue; } - vfs_fd_t *f = get_vfs_fd(fds[i].fd); + vfs_fd_t *f = get_vfs_fd(fds[i].fd, NULL); if (NULL == f) { continue; } @@ -51,7 +51,7 @@ int poll(struct pollfd *fds, size_t nfds, int timeout) { fds[i].revents = 0; continue; } - vfs_fd_t *f = get_vfs_fd(fds[i].fd); + vfs_fd_t *f = get_vfs_fd(fds[i].fd, NULL); if (!f) { if (fds[i].events & POLLHUP) { fds[i].revents |= POLLHUP; diff --git a/kernel/queue.c b/kernel/queue.c index 0f2f645..d77af85 100644 --- a/kernel/queue.c +++ b/kernel/queue.c @@ -1,11 +1,14 @@ +#include <assert.h> #include <kmalloc.h> #include <queue.h> #include <sched/scheduler.h> +#include <socket.h> #include <stdio.h> -int queue_create(u32 *id) { +int queue_create(u32 *id, process_t *p) { struct event_queue *q = kcalloc(1, sizeof(struct event_queue)); q->wait = 0; + q->p = p; list_init(&q->events); struct list *list = ¤t_task->event_queue; @@ -51,7 +54,7 @@ int queue_should_block(struct event_queue *q, int *is_empty) { *is_empty = 0; if (EVENT_TYPE_FD == ev->type) { kprintf("found fd: %d\n", ev->internal_id); - vfs_fd_t *fd = get_vfs_fd(ev->internal_id); + vfs_fd_t *fd = get_vfs_fd(ev->internal_id, q->p); kprintf("fd->inode->has_data: %x\n", fd->inode->has_data); if (!fd) { kprintf("queue: Invalid fd given\n"); @@ -62,8 +65,15 @@ int queue_should_block(struct event_queue *q, int *is_empty) { return 0; } } else if (EVENT_TYPE_TCP_SOCKET == ev->type) { - kprintf("tcp socket wait\n"); - return 0; + struct TcpConnection *con = tcp_get_connection(ev->internal_id, q->p); + assert(con); + assert(con->data_file); + if (con->data_file->has_data) { + kprintf("has data\n"); + return 0; + } else { + kprintf("blocking queue\n"); + } } } return 1; diff --git a/kernel/queue.h b/kernel/queue.h index 74c7ab8..38cd992 100644 --- a/kernel/queue.h +++ b/kernel/queue.h @@ -1,6 +1,7 @@ #ifndef QUEUE_H #define QUEUE_H #include <lib/list.h> +#include <sched/scheduler.h> #include <stddef.h> #include <string.h> #include <typedefs.h> @@ -16,9 +17,10 @@ struct event { struct event_queue { struct list events; int wait; + process_t *p; }; -int queue_create(u32 *id); +int queue_create(u32 *id, process_t *p); int queue_add(u32 queue_id, struct event *ev, u32 size); int queue_wait(u32 queue_id); int queue_should_block(struct event_queue *q, int *is_empty); diff --git a/kernel/sched/scheduler.c b/kernel/sched/scheduler.c index cbb28fa..e202be2 100644 --- a/kernel/sched/scheduler.c +++ b/kernel/sched/scheduler.c @@ -1,4 +1,5 @@ #include <assert.h> +#include <cpu/arch_inst.h> #include <cpu/io.h> #include <defs.h> #include <drivers/pit.h> @@ -433,6 +434,9 @@ process_t *next_task(process_t *s) { if (!c) { c = ready_queue; } + if (s == c) { + wait_for_interrupt(); + } if (c->sleep_until > pit_num_ms()) { continue; } @@ -547,7 +551,7 @@ void *mmap(void *addr, size_t length, int prot, int flags, int fd, *ptr = kmalloc(sizeof(MemoryMap)); MemoryMap *free_map = *ptr; - if (fd == -1) { + if (-1 == fd) { void *rc = allocate_virtual_user_memory(length, prot, flags); if ((void *)-1 == rc) { kprintf("ENOMEM\n"); diff --git a/kernel/socket.c b/kernel/socket.c index e13a845..36d0fcb 100644 --- a/kernel/socket.c +++ b/kernel/socket.c @@ -2,6 +2,7 @@ #include <errno.h> #include <fs/devfs.h> #include <fs/tmpfs.h> +#include <interrupts.h> #include <network/bytes.h> #include <network/tcp.h> #include <poll.h> @@ -14,15 +15,17 @@ OPEN_UNIX_SOCKET *un_sockets[100] = {0}; // struct TcpConnection *tcp_sockets[100]; // struct TcpListen *tcp_listen[100]; -u32 gen_ipv4(u8 i1, u8 i2, u8 i3, u8 i4) { - return i4 << (32 - 8) | i3 << (32 - 16) | i2 << (32 - 24) | i1 << (32 - 32); +void gen_ipv4(ipv4_t *ip, u8 i1, u8 i2, u8 i3, u8 i4) { + ip->a[0] = i1; + ip->a[1] = i2; + ip->a[2] = i3; + ip->a[3] = i4; } struct TcpConnection *tcp_find_connection(u16 port) { process_t *p = current_task; - process_t *s = p; p = p->next; - for (; p != s; p = p->next) { + for (int i = 0; i < 100; i++, p = p->next) { if (!p) { p = ready_queue; } @@ -101,8 +104,11 @@ u32 tcp_listen_ipv4(u32 ip, u16 port, int *error) { return index; } -struct TcpConnection *tcp_get_connection(u32 socket) { - const struct list *connections = ¤t_task->tcp_sockets; +struct TcpConnection *tcp_get_connection(u32 socket, process_t *p) { + if (!p) { + p = current_task; + } + const struct list *connections = &p->tcp_sockets; struct TcpConnection *con; if (!list_get(connections, socket, (void **)&con)) { return NULL; @@ -162,7 +168,7 @@ int tcp_write(u32 socket, const u8 *buffer, u64 len, u64 *out) { if (out) { *out = 0; } - struct TcpConnection *con = tcp_get_connection(socket); + struct TcpConnection *con = tcp_get_connection(socket, NULL); if (!con) { return 0; } @@ -181,7 +187,7 @@ int tcp_read(u32 socket, u8 *buffer, u64 buffer_size, u64 *out) { if (out) { *out = 0; } - struct TcpConnection *con = tcp_get_connection(socket); + struct TcpConnection *con = tcp_get_connection(socket, NULL); if (!con) { return 0; } @@ -192,8 +198,10 @@ int tcp_read(u32 socket, u8 *buffer, u64 buffer_size, u64 *out) { int rc = 0; for (; rc <= 0;) { rc = fifo_object_read(buffer, 0, buffer_size, con->data_file); - if(rc <= 0) { - switch_task(); + if (rc <= 0) { + enable_interrupts(); + rc = 0; + return 0; } } if (out) { @@ -274,7 +282,7 @@ int accept(int socket, struct sockaddr *address, socklen_t *address_len) { int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { (void)addrlen; - vfs_fd_t *fd = get_vfs_fd(sockfd); + vfs_fd_t *fd = get_vfs_fd(sockfd, NULL); if (!fd) { return -EBADF; } diff --git a/kernel/socket.h b/kernel/socket.h index 174ceb1..550b62b 100644 --- a/kernel/socket.h +++ b/kernel/socket.h @@ -18,7 +18,7 @@ #define MSG_WAITALL 1 -u32 gen_ipv4(u8 i1, u8 i2, u8 i3, u8 i4); +void gen_ipv4(ipv4_t *ip, u8 i1, u8 i2, u8 i3, u8 i4); u32 tcp_connect_ipv4(u32 ip, u16 port, int *error); u32 tcp_listen_ipv4(u32 ip, u16 port, int *error); @@ -49,6 +49,7 @@ struct TcpConnection { int handshake_state; }; +struct TcpConnection *tcp_get_connection(u32 socket, process_t *p); struct TcpConnection *internal_tcp_incoming(u32 src_ip, u16 src_port, u32 dst_ip, u16 dst_port); diff --git a/kernel/syscalls/isatty.c b/kernel/syscalls/isatty.c index 9f3cca1..de3e918 100644 --- a/kernel/syscalls/isatty.c +++ b/kernel/syscalls/isatty.c @@ -3,7 +3,7 @@ #include <syscalls.h> int syscall_isatty(int fd) { - vfs_fd_t *fd_ptr = get_vfs_fd(fd); + vfs_fd_t *fd_ptr = get_vfs_fd(fd, NULL); if (!fd_ptr) { return -EBADF; } diff --git a/kernel/syscalls/queue.c b/kernel/syscalls/queue.c index 94f7960..8cd043b 100644 --- a/kernel/syscalls/queue.c +++ b/kernel/syscalls/queue.c @@ -2,7 +2,7 @@ #include <syscalls.h> int syscall_queue_create(u32 *id) { - return queue_create(id); + return queue_create(id, current_task); } int syscall_queue_add(u32 queue_id, struct event *ev, u32 size) { diff --git a/kernel/syscalls/sendto.c b/kernel/syscalls/sendto.c index ffedd75..678b5b3 100644 --- a/kernel/syscalls/sendto.c +++ b/kernel/syscalls/sendto.c @@ -10,7 +10,7 @@ size_t syscall_sendto(int socket, const void *message, size_t length, const struct sockaddr *dest_addr = (const struct sockaddr *)extra_args->a; socklen_t dest_len = (socklen_t)extra_args->b; (void)dest_len; - vfs_fd_t *fd = get_vfs_fd(socket); + vfs_fd_t *fd = get_vfs_fd(socket, NULL); assert(fd); SOCKET *s = (SOCKET *)fd->inode->internal_object; OPEN_INET_SOCKET *inet = s->child; diff --git a/kernel/syscalls/write.c b/kernel/syscalls/write.c index 80c6e57..f88215d 100644 --- a/kernel/syscalls/write.c +++ b/kernel/syscalls/write.c @@ -3,7 +3,7 @@ #include <syscalls.h> int syscall_write(int fd, const char *buf, size_t count) { - vfs_fd_t *fd_ptr = get_vfs_fd(fd); + vfs_fd_t *fd_ptr = get_vfs_fd(fd, NULL); if (!fd_ptr) { return -EBADF; } diff --git a/userland/libc/include/stdio.h b/userland/libc/include/stdio.h index aebf086..b0bfbd1 100644 --- a/userland/libc/include/stdio.h +++ b/userland/libc/include/stdio.h @@ -68,6 +68,7 @@ int puts(const char *s); int brk(void *addr); void *sbrk(intptr_t increment); int printf(const char *format, ...); +int mread(int fd, void *buf, size_t count, int blocking); int pread(int fd, void *buf, size_t count, size_t offset); int read(int fd, void *buf, size_t count); int fork(void); diff --git a/userland/libc/include/syscall.h b/userland/libc/include/syscall.h index 5e0e567..d89ead5 100644 --- a/userland/libc/include/syscall.h +++ b/userland/libc/include/syscall.h @@ -6,7 +6,7 @@ #include <sys/types.h> #define SYS_OPEN 0 -#define SYS_READ 1 +#define SYS_MREAD 1 #define SYS_WRITE 2 #define SYS_PREAD 3 #define SYS_PWRITE 4 diff --git a/userland/libc/libc.c b/userland/libc/libc.c index ea097cb..70c7e70 100644 --- a/userland/libc/libc.c +++ b/userland/libc/libc.c @@ -143,7 +143,9 @@ void _libc_setup(void) { int syscall(uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx, uint32_t esi, uint32_t edi); -int pipe(int fd[2]) { return syscall(SYS_PIPE, (u32)fd, 0, 0, 0, 0); } +int pipe(int fd[2]) { + return syscall(SYS_PIPE, (u32)fd, 0, 0, 0, 0); +} // https://pubs.opengroup.org/onlinepubs/9699919799/functions/strerror.html char *strerror(int errnum) { @@ -172,7 +174,9 @@ void perror(const char *s) { printf("%s\n", strerror(errno)); } -int close(int fd) { return syscall(SYS_CLOSE, (u32)fd, 0, 0, 0, 0); } +int close(int fd) { + return syscall(SYS_CLOSE, (u32)fd, 0, 0, 0, 0); +} int execv(char *path, char **argv) { struct SYS_EXEC_PARAMS args = {.path = path, .argv = argv}; @@ -181,9 +185,13 @@ int execv(char *path, char **argv) { int s_syscall(int sys); -int wait(int *stat_loc) { return syscall(SYS_WAIT, (u32)stat_loc, 0, 0, 0, 0); } +int wait(int *stat_loc) { + return syscall(SYS_WAIT, (u32)stat_loc, 0, 0, 0, 0); +} -void exit(int status) { syscall(SYS_EXIT, (u32)status, 0, 0, 0, 0); } +void exit(int status) { + syscall(SYS_EXIT, (u32)status, 0, 0, 0, 0); +} int pread(int fd, void *buf, size_t count, size_t offset) { struct SYS_PREAD_PARAMS args = { @@ -195,13 +203,12 @@ int pread(int fd, void *buf, size_t count, size_t offset) { RC_ERRNO(syscall(SYS_PREAD, (u32)&args, 0, 0, 0, 0)); } +int mread(int fd, void *buf, size_t count, int blocking) { + RC_ERRNO(syscall(SYS_MREAD, fd, buf, count, blocking, 0)); +} + int read(int fd, void *buf, size_t count) { - struct SYS_READ_PARAMS args = { - .fd = fd, - .buf = buf, - .count = count, - }; - RC_ERRNO(syscall(SYS_READ, (u32)&args, 0, 0, 0, 0)); + return mread(fd, buf, count, 1); } int dup2(int org_fd, int new_fd) { @@ -212,11 +219,17 @@ int dup2(int org_fd, int new_fd) { RC_ERRNO(syscall(SYS_DUP2, (u32)&args, 0, 0, 0, 0)); } -int fork(void) { return s_syscall(SYS_FORK); } +int fork(void) { + return s_syscall(SYS_FORK); +} -void dputc(int fd, const char c) { pwrite(fd, &c, 1, 0); } +void dputc(int fd, const char c) { + pwrite(fd, &c, 1, 0); +} -int brk(void *addr) { return syscall(SYS_BRK, addr, 0, 0, 0, 0); } +int brk(void *addr) { + return syscall(SYS_BRK, addr, 0, 0, 0, 0); +} void *sbrk(intptr_t increment) { return (void *)syscall(SYS_SBRK, (void *)increment, 0, 0, 0, 0); |