add system calls to map the user-level socket library to LwIP sockets
This commit is contained in:
parent
8e317a5a20
commit
5d9f361174
4 changed files with 156 additions and 5 deletions
|
@ -48,6 +48,7 @@
|
|||
|
||||
void echo_init(void);
|
||||
void ping_init(void);
|
||||
void netio_init(void);
|
||||
int test_init(void);
|
||||
|
||||
/*
|
||||
|
@ -158,6 +159,7 @@ int network_init(void)
|
|||
// start echo and ping server
|
||||
echo_init();
|
||||
//ping_init();
|
||||
netio_init();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
|
144
kernel/syscall.c
144
kernel/syscall.c
|
@ -24,6 +24,27 @@
|
|||
#include <metalsvm/errno.h>
|
||||
#include <metalsvm/spinlock.h>
|
||||
#include <metalsvm/time.h>
|
||||
#include <lwip/opt.h>
|
||||
|
||||
#if defined(CONFIG_LWIP) && LWIP_SOCKET
|
||||
#include <lwip/mem.h>
|
||||
#include <lwip/raw.h>
|
||||
#include <lwip/icmp.h>
|
||||
#include <lwip/netif.h>
|
||||
#include <lwip/sys.h>
|
||||
#include <lwip/timers.h>
|
||||
#include <lwip/inet_chksum.h>
|
||||
#include <lwip/ip.h>
|
||||
#include <lwip/sockets.h>
|
||||
#include <lwip/inet.h>
|
||||
#include <lwip/err.h>
|
||||
|
||||
/*
|
||||
* We set the a bit LWIP_FD_BIT to determine,
|
||||
* if the descriptor belongs to LwIP or MetalSVM.
|
||||
*/
|
||||
#define LWIP_FD_BIT (1 << 28)
|
||||
#endif
|
||||
|
||||
static int sys_write(int fildes, const char *buf, size_t len)
|
||||
{
|
||||
|
@ -85,15 +106,33 @@ int syscall_handler(uint32_t sys_nr, ...)
|
|||
const char* buf = va_arg(vl, const char*);
|
||||
size_t len = va_arg(vl, size_t);
|
||||
|
||||
#if defined(CONFIG_LWIP) && LWIP_SOCKET
|
||||
if (fildes & LWIP_FD_BIT) {
|
||||
ret = lwip_write(fildes & ~LWIP_FD_BIT, buf, len);
|
||||
if (ret < 0)
|
||||
ret = -errno;
|
||||
} else ret = sys_write(fildes, buf, len);
|
||||
#else
|
||||
ret = sys_write(fildes, buf, len);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case __NR_open:
|
||||
ret = 1;
|
||||
break;
|
||||
case __NR_close:
|
||||
case __NR_close: {
|
||||
#if defined(CONFIG_LWIP) && LWIP_SOCKET
|
||||
int s = va_arg(vl, int);
|
||||
if (s & LWIP_FD_BIT) {
|
||||
ret = lwip_close(s & ~LWIP_FD_BIT);
|
||||
if (ret < 0)
|
||||
ret = -errno;
|
||||
} else ret = 0;
|
||||
#else
|
||||
ret = 0;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case __NR_sbrk: {
|
||||
int incr = va_arg(vl, int);
|
||||
|
||||
|
@ -127,6 +166,109 @@ int syscall_handler(uint32_t sys_nr, ...)
|
|||
ret = sys_times(buffer, clock);
|
||||
break;
|
||||
}
|
||||
#if defined(CONFIG_LWIP) && LWIP_SOCKET
|
||||
case __NR_read: {
|
||||
int s = va_arg(vl, int);
|
||||
void* mem = va_arg(vl, void*);
|
||||
size_t len = va_arg(vl, size_t);
|
||||
|
||||
if (!(s & LWIP_FD_BIT)) {
|
||||
ret = -ENOTSOCK;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = lwip_read(s & ~LWIP_FD_BIT, mem, len);
|
||||
if (ret < 0)
|
||||
ret = -errno;
|
||||
break;
|
||||
}
|
||||
case __NR_closesocket: {
|
||||
int s = va_arg(vl, int);
|
||||
|
||||
if (BUILTIN_EXPECT(!(s & LWIP_FD_BIT), 0)) {
|
||||
ret = -ENOTSOCK;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = lwip_close(s & ~LWIP_FD_BIT);
|
||||
if (ret < 0)
|
||||
ret = -errno;
|
||||
break;
|
||||
}
|
||||
case __NR_socket: {
|
||||
int domain = va_arg(vl, int);
|
||||
int type = va_arg(vl, int);
|
||||
int protocol = va_arg(vl, int);
|
||||
|
||||
ret = lwip_socket(domain, type, protocol);
|
||||
if (ret >= 0)
|
||||
ret |= LWIP_FD_BIT;
|
||||
else
|
||||
ret = -errno;
|
||||
break;
|
||||
}
|
||||
case __NR_connect: {
|
||||
int s = va_arg(vl, int);
|
||||
const struct sockaddr* name = va_arg(vl, const struct sockaddr*);
|
||||
socklen_t namelen = va_arg(vl, socklen_t);
|
||||
|
||||
if (BUILTIN_EXPECT(!(s & LWIP_FD_BIT), 0)) {
|
||||
ret = -ENOTSOCK;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = lwip_connect(s & ~LWIP_FD_BIT, name, namelen);
|
||||
if (ret < 0)
|
||||
ret = -errno;
|
||||
break;
|
||||
}
|
||||
case __NR_bind: {
|
||||
int s = va_arg(vl, int);
|
||||
const struct sockaddr* name = va_arg(vl, const struct sockaddr*);
|
||||
socklen_t namelen = va_arg(vl, socklen_t);
|
||||
|
||||
if (BUILTIN_EXPECT(!(s & LWIP_FD_BIT), 0)) {
|
||||
ret = -ENOTSOCK;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = lwip_bind(s & ~LWIP_FD_BIT, name, namelen);
|
||||
if (ret < 0)
|
||||
ret = -errno;
|
||||
break;
|
||||
}
|
||||
case __NR_listen:{
|
||||
int s = va_arg(vl, int);
|
||||
int backlog = va_arg(vl, int);
|
||||
|
||||
if (BUILTIN_EXPECT(!(s & LWIP_FD_BIT), 0)) {
|
||||
ret = -ENOTSOCK;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = lwip_listen(s & ~LWIP_FD_BIT, backlog);
|
||||
if (ret < 0)
|
||||
ret = -errno;
|
||||
break;
|
||||
}
|
||||
case __NR_accept: {
|
||||
int s = va_arg(vl, int);
|
||||
struct sockaddr* addr = va_arg(vl, struct sockaddr*);
|
||||
socklen_t* addrlen = va_arg(vl, socklen_t*);
|
||||
|
||||
if (BUILTIN_EXPECT(!(s & LWIP_FD_BIT), 0)) {
|
||||
ret = -ENOTSOCK;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = lwip_accept(s & ~LWIP_FD_BIT, addr, addrlen);
|
||||
if (ret >= 0)
|
||||
ret |= LWIP_FD_BIT;
|
||||
else
|
||||
ret = -errno;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
kputs("invalid system call\n");
|
||||
ret = -ENOSYS;
|
||||
|
|
|
@ -47,8 +47,8 @@
|
|||
* A task's id will be its position in this array.
|
||||
*/
|
||||
static task_t task_table[MAX_TASKS] = { \
|
||||
[0] = {0, TASK_IDLE, 0, 0, 0, ATOMIC_INIT(0), SPINLOCK_INIT, NULL, SPINLOCK_INIT, NULL, 0, 0, 0}, \
|
||||
[1 ... MAX_TASKS-1] = {0, TASK_INVALID, 0, 0, 0, ATOMIC_INIT(0), SPINLOCK_INIT, NULL, SPINLOCK_INIT, NULL, 0, 0, 0}};
|
||||
[0] = {0, TASK_IDLE, 0, 0, 0, ATOMIC_INIT(0), SPINLOCK_INIT, NULL, SPINLOCK_INIT, NULL, 0, 0, 0, 0}, \
|
||||
[1 ... MAX_TASKS-1] = {0, TASK_INVALID, 0, 0, 0, ATOMIC_INIT(0), SPINLOCK_INIT, NULL, SPINLOCK_INIT, NULL, 0, 0, 0, 0}};
|
||||
static spinlock_irqsave_t table_lock = SPINLOCK_IRQSAVE_INIT;
|
||||
|
||||
DEFINE_PER_CORE(task_t*, current_task, task_table+0);
|
||||
|
@ -243,6 +243,7 @@ static int create_task(tid_t* id, internal_entry_point_t ep, void* arg)
|
|||
|
||||
task_table[i].start_heap = 0;
|
||||
task_table[i].end_heap = 0;
|
||||
task_table[i].lwip_err = 0;
|
||||
task_table[i].start_tick = get_clock_tick();
|
||||
break;
|
||||
}
|
||||
|
@ -308,6 +309,7 @@ int sys_fork(void)
|
|||
task_table[i].start_tick = get_clock_tick();
|
||||
task_table[i].start_heap = 0;
|
||||
task_table[i].end_heap = 0;
|
||||
task_table[i].lwip_err = 0;
|
||||
|
||||
ret = arch_fork(task_table+i);
|
||||
|
||||
|
|
|
@ -253,6 +253,8 @@ void* client_task(void* e)
|
|||
int test_init(void)
|
||||
{
|
||||
char* argv[] = {"/bin/tests", NULL};
|
||||
char* server_argv[] = {"/bin/server", "6789", NULL};
|
||||
char* client_argv[] = {"/bin/client", "127.0.0.1", "6789", NULL};
|
||||
|
||||
sem_init(&producing, 1);
|
||||
sem_init(&consuming, 0);
|
||||
|
@ -272,14 +274,17 @@ int test_init(void)
|
|||
#endif
|
||||
|
||||
create_kernel_task(NULL, foo, "Hello from foo1");
|
||||
create_kernel_task(NULL, join_test, NULL);
|
||||
//create_kernel_task(NULL, join_test, NULL);
|
||||
//create_kernel_task(NULL, producer, NULL);
|
||||
//create_kernel_task(NULL, consumer, NULL);
|
||||
//create_kernel_task(NULL, mail_ping, NULL);
|
||||
//create_user_task(NULL, "/bin/hello", argv);
|
||||
create_user_task(NULL, "/bin/hello", argv);
|
||||
create_user_task(NULL, "/bin/tests", argv);
|
||||
//create_user_task(NULL, "/bin/jacobi", argv);
|
||||
//create_user_task(NULL, "/bin/jacobi", argv);
|
||||
create_user_task(NULL, "/bin/server", server_argv);
|
||||
//sleep(5);
|
||||
//create_user_task(NULL, "/bin/client", client_argv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue