From 8a3e760e1b1555f38d0682cc50441f6158a69706 Mon Sep 17 00:00:00 2001 From: Adipks Date: Sat, 9 Nov 2024 17:17:04 +0530 Subject: [PATCH 1/3] Socket Test --- xv6-riscv/.gitignore | 17 +++++ xv6-riscv/Makefile | 2 + xv6-riscv/kernel/defs.h | 11 +++ xv6-riscv/kernel/file.h | 12 ++-- xv6-riscv/kernel/socket.c | 129 ++++++++++++++++++++++++++++++++++++ xv6-riscv/kernel/socket.h | 8 +++ xv6-riscv/kernel/syscall.c | 9 +++ xv6-riscv/kernel/syscall.h | 1 + xv6-riscv/kernel/sysfile.c | 20 ++++++ xv6-riscv/user/sockettest.c | 19 ++++++ xv6-riscv/user/user.h | 11 +-- xv6-riscv/user/usys.pl | 1 + 12 files changed, 231 insertions(+), 9 deletions(-) create mode 100644 xv6-riscv/.gitignore create mode 100644 xv6-riscv/kernel/socket.c create mode 100644 xv6-riscv/kernel/socket.h create mode 100644 xv6-riscv/user/sockettest.c diff --git a/xv6-riscv/.gitignore b/xv6-riscv/.gitignore new file mode 100644 index 0000000..07216f3 --- /dev/null +++ b/xv6-riscv/.gitignore @@ -0,0 +1,17 @@ +*~ +_* +*.o +*.d +*.asm +*.sym +*.img +vectors.S +bootblock +entryother +initcode +initcode.out +kernelmemfs +mkfs +kernel/kernel +user/usys.S +.gdbinit diff --git a/xv6-riscv/Makefile b/xv6-riscv/Makefile index f8c820e..1528618 100644 --- a/xv6-riscv/Makefile +++ b/xv6-riscv/Makefile @@ -26,6 +26,7 @@ OBJS = \ $K/pipe.o \ $K/exec.o \ $K/sysfile.o \ + $K/socket.o \ $K/kernelvec.o \ $K/plic.o \ $K/virtio_disk.o @@ -139,6 +140,7 @@ UPROGS=\ $U/_grind\ $U/_wc\ $U/_zombie\ + $U/_sockettest\ fs.img: mkfs/mkfs README $(UPROGS) mkfs/mkfs fs.img README $(UPROGS) diff --git a/xv6-riscv/kernel/defs.h b/xv6-riscv/kernel/defs.h index d1b6bb9..7317350 100644 --- a/xv6-riscv/kernel/defs.h +++ b/xv6-riscv/kernel/defs.h @@ -185,5 +185,16 @@ void virtio_disk_init(void); void virtio_disk_rw(struct buf *, int); void virtio_disk_intr(void); + +//socket + +struct file; +struct socket; +struct file* socketalloc(void); +int socketread(struct file*, uint64, int); +int socketwrite(struct file*, uint64, int); +void socketclose(struct file*); + + // number of elements in fixed-size array #define NELEM(x) (sizeof(x)/sizeof((x)[0])) diff --git a/xv6-riscv/kernel/file.h b/xv6-riscv/kernel/file.h index b076d1d..863de0e 100644 --- a/xv6-riscv/kernel/file.h +++ b/xv6-riscv/kernel/file.h @@ -1,12 +1,13 @@ struct file { - enum { FD_NONE, FD_PIPE, FD_INODE, FD_DEVICE } type; - int ref; // reference count + enum { FD_NONE, FD_PIPE, FD_INODE, FD_DEVICE, FD_SOCKET } type; + int ref; char readable; char writable; struct pipe *pipe; // FD_PIPE struct inode *ip; // FD_INODE and FD_DEVICE - uint off; // FD_INODE - short major; // FD_DEVICE + uint off; // FD_INODE + short major; // FD_DEVICE + struct socket *sock; // FD_SOCKET }; #define major(dev) ((dev) >> 16 & 0xFFFF) @@ -38,3 +39,6 @@ struct devsw { extern struct devsw devsw[]; #define CONSOLE 1 + +// Add a new file type for sockets +#define T_SOCKET 4 diff --git a/xv6-riscv/kernel/socket.c b/xv6-riscv/kernel/socket.c new file mode 100644 index 0000000..7f6f69b --- /dev/null +++ b/xv6-riscv/kernel/socket.c @@ -0,0 +1,129 @@ +#include "types.h" +#include "riscv.h" +#include "defs.h" +#include "param.h" +#include "spinlock.h" +#include "proc.h" +#include "fs.h" +#include "sleeplock.h" +#include "file.h" +#include "socket.h" + +struct file* +socketalloc(void) +{ + struct file *f; + struct socket *s; + + f = filealloc(); + if(f == 0) + return 0; + + s = kalloc(); + if(s == 0){ + fileclose(f); + return 0; + } + + initlock(&s->lock, "socket"); + s->refs = 1; + s->read_ptr = 0; + s->write_ptr = 0; + s->connected = 0; + + f->type = FD_SOCKET; + f->readable = 1; + f->writable = 1; + f->sock = s; + f->ref = 1; + + return f; +} + +int +socketread(struct file *f, uint64 addr, int n) +{ + struct socket *s = f->sock; + int r; + + if(n < 0) + return -1; + + acquire(&s->lock); + + while(s->read_ptr == s->write_ptr && s->connected){ + if(myproc()->killed){ + release(&s->lock); + return -1; + } + sleep(&s->read_ptr, &s->lock); + } + + r = 0; + while(r < n && s->read_ptr != s->write_ptr){ + if(copyout(myproc()->pagetable, addr + r, &s->data[s->read_ptr], 1) == -1) + break; + s->read_ptr = (s->read_ptr + 1) % sizeof(s->data); + r++; + } + + if(r > 0) + wakeup(&s->write_ptr); + + release(&s->lock); + return r; +} + +int +socketwrite(struct file *f, uint64 addr, int n) +{ + struct socket *s = f->sock; + int w; + + if(n < 0) + return -1; + + acquire(&s->lock); + + w = 0; + while(w < n){ + while(((s->write_ptr + 1) % sizeof(s->data)) == s->read_ptr){ + if(myproc()->killed){ + release(&s->lock); + return -1; + } + wakeup(&s->read_ptr); + sleep(&s->write_ptr, &s->lock); + } + + if(copyin(myproc()->pagetable, &s->data[s->write_ptr], addr + w, 1) == -1) + break; + + s->write_ptr = (s->write_ptr + 1) % sizeof(s->data); + w++; + } + + if(w > 0) + wakeup(&s->read_ptr); + + release(&s->lock); + return w; +} + +void +socketclose(struct file *f) +{ + struct socket *s = f->sock; + + acquire(&s->lock); + s->refs--; + if(s->refs == 0){ + s->connected = 0; + wakeup(&s->read_ptr); + wakeup(&s->write_ptr); + release(&s->lock); + kfree(s); + } else { + release(&s->lock); + } +} \ No newline at end of file diff --git a/xv6-riscv/kernel/socket.h b/xv6-riscv/kernel/socket.h new file mode 100644 index 0000000..a37c293 --- /dev/null +++ b/xv6-riscv/kernel/socket.h @@ -0,0 +1,8 @@ +struct socket { + struct spinlock lock; + int refs; // reference count + char data[512]; // socket buffer + uint read_ptr; // read pointer + uint write_ptr; // write pointer + int connected; // connection status +}; \ No newline at end of file diff --git a/xv6-riscv/kernel/syscall.c b/xv6-riscv/kernel/syscall.c index ed65409..4f21a56 100644 --- a/xv6-riscv/kernel/syscall.c +++ b/xv6-riscv/kernel/syscall.c @@ -7,6 +7,12 @@ #include "syscall.h" #include "defs.h" +// Add the system call number +#define SYS_socket 22 + + + + // Fetch the uint64 at addr from the current process. int fetchaddr(uint64 addr, uint64 *ip) @@ -101,6 +107,7 @@ extern uint64 sys_unlink(void); extern uint64 sys_link(void); extern uint64 sys_mkdir(void); extern uint64 sys_close(void); +extern uint64 sys_socketalloc(void); // An array mapping syscall numbers from syscall.h // to the function that handles the system call. @@ -126,6 +133,7 @@ static uint64 (*syscalls[])(void) = { [SYS_link] sys_link, [SYS_mkdir] sys_mkdir, [SYS_close] sys_close, +[SYS_socketalloc] sys_socketalloc, }; void @@ -145,3 +153,4 @@ syscall(void) p->trapframe->a0 = -1; } } + diff --git a/xv6-riscv/kernel/syscall.h b/xv6-riscv/kernel/syscall.h index bc5f356..699f7a2 100644 --- a/xv6-riscv/kernel/syscall.h +++ b/xv6-riscv/kernel/syscall.h @@ -20,3 +20,4 @@ #define SYS_link 19 #define SYS_mkdir 20 #define SYS_close 21 +#define SYS_socketalloc 22 \ No newline at end of file diff --git a/xv6-riscv/kernel/sysfile.c b/xv6-riscv/kernel/sysfile.c index 16b668c..d9ba01b 100644 --- a/xv6-riscv/kernel/sysfile.c +++ b/xv6-riscv/kernel/sysfile.c @@ -503,3 +503,23 @@ sys_pipe(void) } return 0; } + + + +uint64 +sys_socketalloc(void) +{ + struct file *f; + int fd; + + f = socketalloc(); + if(f == 0) + return -1; + + if((fd = fdalloc(f)) < 0){ + fileclose(f); + return -1; + } + + return fd; +} diff --git a/xv6-riscv/user/sockettest.c b/xv6-riscv/user/sockettest.c new file mode 100644 index 0000000..b804072 --- /dev/null +++ b/xv6-riscv/user/sockettest.c @@ -0,0 +1,19 @@ +//#include "types.h" +//#include "stat.h" +#include "user.h" + +int +main(int argc, char *argv[]) +{ + int fd; + + fd = socketalloc(); + if(fd < 0){ + printf("socketalloc failed\n"); + exit(1); + } + + printf("socket created: fd=%d\n", fd); + close(fd); + exit(0); +} \ No newline at end of file diff --git a/xv6-riscv/user/user.h b/xv6-riscv/user/user.h index f16fe27..086f694 100644 --- a/xv6-riscv/user/user.h +++ b/xv6-riscv/user/user.h @@ -22,6 +22,7 @@ int getpid(void); char* sbrk(int); int sleep(int); int uptime(void); +int socketalloc(void); // ulib.c int stat(const char*, struct stat*); @@ -32,12 +33,12 @@ int strcmp(const char*, const char*); void fprintf(int, const char*, ...) __attribute__ ((format (printf, 2, 3))); void printf(const char*, ...) __attribute__ ((format (printf, 1, 2))); char* gets(char*, int max); -uint strlen(const char*); -void* memset(void*, int, uint); +unsigned int strlen(const char*); +void* memset(void*, int, unsigned int); int atoi(const char*); -int memcmp(const void *, const void *, uint); -void *memcpy(void *, const void *, uint); +int memcmp(const void *, const void *, unsigned int); +void *memcpy(void *, const void *, unsigned int); // umalloc.c -void* malloc(uint); +void* malloc(unsigned int); void free(void*); diff --git a/xv6-riscv/user/usys.pl b/xv6-riscv/user/usys.pl index 01e426e..713acb7 100755 --- a/xv6-riscv/user/usys.pl +++ b/xv6-riscv/user/usys.pl @@ -36,3 +36,4 @@ sub entry { entry("sbrk"); entry("sleep"); entry("uptime"); +entry("socketalloc"); \ No newline at end of file From 574c03d7b75a6261908ca557e08314f6557c7fc5 Mon Sep 17 00:00:00 2001 From: Adipks Date: Wed, 13 Nov 2024 23:35:41 +0530 Subject: [PATCH 2/3] Updated socket functions --- xv6-riscv/.vscode/settings.json | 5 +++ xv6-riscv/kernel/syscall.c | 8 ++++ xv6-riscv/kernel/syscall.h | 5 ++- xv6-riscv/kernel/sysfile.c | 44 ++++++++++++++++++++++ xv6-riscv/user/sockettest.c | 66 +++++++++++++++++++++++++++++---- xv6-riscv/user/user.h | 3 ++ xv6-riscv/user/usys.pl | 5 ++- 7 files changed, 126 insertions(+), 10 deletions(-) create mode 100644 xv6-riscv/.vscode/settings.json diff --git a/xv6-riscv/.vscode/settings.json b/xv6-riscv/.vscode/settings.json new file mode 100644 index 0000000..64c7ab7 --- /dev/null +++ b/xv6-riscv/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "files.associations": { + "stat.h": "c" + } +} \ No newline at end of file diff --git a/xv6-riscv/kernel/syscall.c b/xv6-riscv/kernel/syscall.c index 4f21a56..a1c0ce8 100644 --- a/xv6-riscv/kernel/syscall.c +++ b/xv6-riscv/kernel/syscall.c @@ -108,6 +108,11 @@ extern uint64 sys_link(void); extern uint64 sys_mkdir(void); extern uint64 sys_close(void); extern uint64 sys_socketalloc(void); +extern uint64 sys_socketread(void); +extern uint64 sys_socketwrite(void); +extern uint64 sys_socketclose(void); + + // An array mapping syscall numbers from syscall.h // to the function that handles the system call. @@ -134,6 +139,9 @@ static uint64 (*syscalls[])(void) = { [SYS_mkdir] sys_mkdir, [SYS_close] sys_close, [SYS_socketalloc] sys_socketalloc, +[SYS_socketread] sys_socketread, +[SYS_socketwrite] sys_socketwrite, +[SYS_socketclose] sys_socketclose, }; void diff --git a/xv6-riscv/kernel/syscall.h b/xv6-riscv/kernel/syscall.h index 699f7a2..e2e69a3 100644 --- a/xv6-riscv/kernel/syscall.h +++ b/xv6-riscv/kernel/syscall.h @@ -20,4 +20,7 @@ #define SYS_link 19 #define SYS_mkdir 20 #define SYS_close 21 -#define SYS_socketalloc 22 \ No newline at end of file +#define SYS_socketalloc 22 +#define SYS_socketread 23 +#define SYS_socketwrite 24 +#define SYS_socketclose 25 \ No newline at end of file diff --git a/xv6-riscv/kernel/sysfile.c b/xv6-riscv/kernel/sysfile.c index d9ba01b..46877ac 100644 --- a/xv6-riscv/kernel/sysfile.c +++ b/xv6-riscv/kernel/sysfile.c @@ -523,3 +523,47 @@ sys_socketalloc(void) return fd; } + +uint64 sys_socketread(void) { + int fd; + struct file* f; + uint64 addr; + int n; + + if (argfd(0, &fd, &f) < 0) { + return -1; + } + + argaddr(1, &addr); + argint(2, &n); + + return socketread(f, addr, n); +} + +uint64 sys_socketwrite(void) { + int fd; + struct file* f; + uint64 addr; + int n; + + if (argfd(0, &fd, &f) < 0) { + return -1; + } + + argaddr(1, &addr); + argint(2, &n); + + return socketwrite(f, addr, n); +} + +uint64 sys_socketclose(void) { + int fd; + struct file* f; + + if (argfd(0, &fd, &f) < 0) { + return -1; + } + + socketclose(f); + return 0; +} \ No newline at end of file diff --git a/xv6-riscv/user/sockettest.c b/xv6-riscv/user/sockettest.c index b804072..d1fe8b1 100644 --- a/xv6-riscv/user/sockettest.c +++ b/xv6-riscv/user/sockettest.c @@ -1,19 +1,69 @@ -//#include "types.h" -//#include "stat.h" +// #include "kernel/types.h" +// #include "kernel/stat.h" +// #include "user.h" + +// int +// main(int argc, char *argv[]) +// { +// int fd; + +// fd = socketalloc(); +// if(fd < 0){ +// printf("socketalloc failed\n"); +// exit(1); +// } + +// printf("socket created: fd=%d\n", fd); +// close(fd); +// exit(0); +// } + +#include "kernel/types.h" +#include "kernel/stat.h" #include "user.h" +#define BUFFER_SIZE 64 + int main(int argc, char *argv[]) { - int fd; + int sockfd; + char buf[BUFFER_SIZE]; + int n; - fd = socketalloc(); - if(fd < 0){ + // Create a socket + sockfd = socketalloc(); + if(sockfd < 0){ printf("socketalloc failed\n"); exit(1); } - - printf("socket created: fd=%d\n", fd); - close(fd); + printf("Socket created: fd=%d\n", sockfd); + + // Write some data to the socket + const char* msg = "Hello from sockettest!"; + if(socketwrite(sockfd, msg, strlen(msg)) < 0){ + printf("socketwrite failed\n"); + socketclose(sockfd); + exit(1); + } + printf("Wrote data to socket\n"); + + // Read data from the socket + n = socketread(sockfd, buf, BUFFER_SIZE-1); + if(n < 0){ + printf("socketread failed\n"); + socketclose(sockfd); + exit(1); + } + buf[n] = '\0'; + printf("Read from socket: %s\n", buf); + + // Close the socket + if(socketclose(sockfd) < 0){ + printf("socketclose failed\n"); + exit(1); + } + printf("Socket closed\n"); + exit(0); } \ No newline at end of file diff --git a/xv6-riscv/user/user.h b/xv6-riscv/user/user.h index 086f694..f2663d8 100644 --- a/xv6-riscv/user/user.h +++ b/xv6-riscv/user/user.h @@ -23,6 +23,9 @@ char* sbrk(int); int sleep(int); int uptime(void); int socketalloc(void); +int socketread(int, void*, int); +int socketwrite(int, const void*, int); +int socketclose(int); // ulib.c int stat(const char*, struct stat*); diff --git a/xv6-riscv/user/usys.pl b/xv6-riscv/user/usys.pl index 713acb7..f14d4fa 100755 --- a/xv6-riscv/user/usys.pl +++ b/xv6-riscv/user/usys.pl @@ -36,4 +36,7 @@ sub entry { entry("sbrk"); entry("sleep"); entry("uptime"); -entry("socketalloc"); \ No newline at end of file +entry("socketalloc"); +entry("socketread"); +entry("socketwrite"); +entry("socketclose"); \ No newline at end of file From 41d4c23cd4ff54a1f5f117943209f5d8bdeee651 Mon Sep 17 00:00:00 2001 From: Adipks Date: Wed, 13 Nov 2024 23:43:10 +0530 Subject: [PATCH 3/3] Updated socket functions --- xv6-riscv/user/sockettest.c | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/xv6-riscv/user/sockettest.c b/xv6-riscv/user/sockettest.c index d1fe8b1..1e8b162 100644 --- a/xv6-riscv/user/sockettest.c +++ b/xv6-riscv/user/sockettest.c @@ -1,23 +1,3 @@ -// #include "kernel/types.h" -// #include "kernel/stat.h" -// #include "user.h" - -// int -// main(int argc, char *argv[]) -// { -// int fd; - -// fd = socketalloc(); -// if(fd < 0){ -// printf("socketalloc failed\n"); -// exit(1); -// } - -// printf("socket created: fd=%d\n", fd); -// close(fd); -// exit(0); -// } - #include "kernel/types.h" #include "kernel/stat.h" #include "user.h"