Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions xv6-riscv/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
*~
_*
*.o
*.d
*.asm
*.sym
*.img
vectors.S
bootblock
entryother
initcode
initcode.out
kernelmemfs
mkfs
kernel/kernel
user/usys.S
.gdbinit
5 changes: 5 additions & 0 deletions xv6-riscv/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"files.associations": {
"stat.h": "c"
}
}
2 changes: 2 additions & 0 deletions xv6-riscv/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
11 changes: 11 additions & 0 deletions xv6-riscv/kernel/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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]))
12 changes: 8 additions & 4 deletions xv6-riscv/kernel/file.h
Original file line number Diff line number Diff line change
@@ -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)
Expand Down Expand Up @@ -38,3 +39,6 @@ struct devsw {
extern struct devsw devsw[];

#define CONSOLE 1

// Add a new file type for sockets
#define T_SOCKET 4
129 changes: 129 additions & 0 deletions xv6-riscv/kernel/socket.c
Original file line number Diff line number Diff line change
@@ -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);
}
}
8 changes: 8 additions & 0 deletions xv6-riscv/kernel/socket.h
Original file line number Diff line number Diff line change
@@ -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
};
17 changes: 17 additions & 0 deletions xv6-riscv/kernel/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -101,6 +107,12 @@ 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);
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.
Expand All @@ -126,6 +138,10 @@ static uint64 (*syscalls[])(void) = {
[SYS_link] sys_link,
[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
Expand All @@ -145,3 +161,4 @@ syscall(void)
p->trapframe->a0 = -1;
}
}

4 changes: 4 additions & 0 deletions xv6-riscv/kernel/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@
#define SYS_link 19
#define SYS_mkdir 20
#define SYS_close 21
#define SYS_socketalloc 22
#define SYS_socketread 23
#define SYS_socketwrite 24
#define SYS_socketclose 25
64 changes: 64 additions & 0 deletions xv6-riscv/kernel/sysfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -503,3 +503,67 @@ 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;
}

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;
}
49 changes: 49 additions & 0 deletions xv6-riscv/user/sockettest.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user.h"

#define BUFFER_SIZE 64

int
main(int argc, char *argv[])
{
int sockfd;
char buf[BUFFER_SIZE];
int n;

// Create a socket
sockfd = socketalloc();
if(sockfd < 0){
printf("socketalloc failed\n");
exit(1);
}
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);
}
Loading