5.2. ソケット層の移植
micropsのソケット層(sock.c/sock.h)をxv6へ移植します。ソケット層は独自のディスクリプタ表(socks[])でソケットを管理し、sock_open()はその添字を返します。この添字を、5.1でstruct fileに追加したsockメンバに保持します。
ソケット層のコードのコピー
ソケット層のコードをmicropsからコピーします。修正は不要で、そのまま利用できます。
$ cp $MICROPS/sock.{h,c} kernel/net/
sock.hには、ソケットAPIのアドレスファミリ(AF_INETなど)やソケット種別(SOCK_DGRAMなど)の定数と、struct sockaddr/struct sockaddr_in、そしてソケット層の関数プロトタイプが定義されています。
プロトタイプ宣言の追加
カーネルから呼び出すソケット層の関数をkernel/defs.hに宣言します。あわせて、struct sockaddrの前方宣言と、次の5.3でシステムコールから使うsysfile.cのargfd()/fdalloc()の宣言も追加します(これらはstaticを外して公開します)。
📝 kernel/defs.h
...
struct stat;
struct superblock;
struct net_device;
+struct sockaddr;
struct timeval;
struct tm;
...
int strncmp(const char*, const char*, uint);
char* strncpy(char*, const char*, int);
+// sysfile.c
+int argfd(int, int*, struct file**);
+int fdalloc(struct file*);
+
// syscall.c
...
int net_init(void);
int net_run(void);
+// net/sock.c
+int sock_open(int, int, int);
+int sock_close(int);
+ssize_t sock_recvfrom(int, void*, size_t, struct sockaddr*, int*);
+ssize_t sock_sendto(int, const void*, size_t, const struct sockaddr*, int);
+int sock_bind(int, const struct sockaddr*, int);
+
// net/platform/xv6-riscv/intr.c
...
sysfile.cのargfd()とfdalloc()からstaticを外します。
📝 kernel/sysfile.c
...
// Fetch the nth word-sized system call argument as a file descriptor
// and return both the descriptor and the corresponding struct file.
-static int
+int
argfd(int n, int *pfd, struct file **pf)
{
...
// Allocate a file descriptor for the given file.
// Takes over file reference from caller on success.
-static int
+int
fdalloc(struct file *f)
{
...
Makefileの修正
sock.oをビルド対象に追加します。
📝 Makefile
...
$N/udp.o \
$N/tcp.o \
+ $N/sock.o \
$P/platform.o \
...
一旦、この状態でビルドが通ることを確認しておきましょう。
$ make