3.2. Ethernetモジュール
自作プロトコルスタックのEthernetモジュールを移植します。
Ethernetモジュールのコードのコピー
Ethernetモジュールのコードをmicropsからコピーします。修正は不要で、そのまま利用できます。
$ cp $MICROPS/ether.{h,c} kernel/net/
不足しているlibc関数の追加
ether.cのether_addr_pton()は、MACアドレスの文字列(xx:xx:xx:xx:xx:xx)の解析にstrtol()を使用しています。簡易libcにはまだこの関数がないため、stdlib.cを作成してstdlib.hにプロトタイプ宣言を追加します。
📝 kernel/net/platform/xv6-riscv/libc/stdlib.c
#include <stdlib.h>
long
strtol(const char *s, char **endptr, int base)
{
int neg = 0;
long val = 0;
// gobble initial whitespace
while (*s == ' ' || *s == '\t')
s++;
// plus/minus sign
if (*s == '+')
s++;
else if (*s == '-')
s++, neg = 1;
// hex or octal base prefix
if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x'))
s += 2, base = 16;
else if (base == 0 && s[0] == '0')
s++, base = 8;
else if (base == 0)
base = 10;
// digits
while (1) {
int dig;
if (*s >= '0' && *s <= '9')
dig = *s - '0';
else if (*s >= 'a' && *s <= 'z')
dig = *s - 'a' + 10;
else if (*s >= 'A' && *s <= 'Z')
dig = *s - 'A' + 10;
else
break;
if (dig >= base)
break;
s++, val = (val * base) + dig;
// we don't properly detect overflow!
}
if (endptr)
*endptr = (char *) s;
return (neg ? -val : val);
}
📝 kernel/net/platform/xv6-riscv/libc/stdlib.h
#ifndef STDLIB_H
#define STDLIB_H
#include <sys/types.h>
+extern long
+strtol(const char *s, char **endptr, int base);
+
#endif
Makefileの修正
ether.oとstdlib.oをビルド対象に追加します。
📝 Makefile
OBJS = \
...
$N/util.o \
$N/net.o \
+ $N/ether.o \
$P/platform.o \
$P/intr.o \
- $L/stdio.o
+ $L/stdio.o \
+ $L/stdlib.o
一旦、この状態でビルドが通ることを確認しておきましょう。
$ make