Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

3.2. Ethernetモジュール

自作プロトコルスタックのEthernetモジュールを移植します。

Ethernetモジュールのコードのコピー

Ethernetモジュールのコードをmicropsからコピーします。修正は不要で、そのまま利用できます。

$ cp $MICROPS/ether.{h,c} kernel/net/

不足しているlibc関数の追加

ether.cether_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.ostdlib.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