第 5 章後半に突入。
何も考えずに day05d
をコンパイルすると
ld.lld: error: undefined symbol: sprintf
と。なるほど、#include <cstdio>
はしているが、libc
はリンクしていないのでそうなるか・・・。ここで NewLib
というやつの出番になるのだな。このライブラリのミラーリポジトリは https://github.com/mirror/newlib-cygwin らしい。sprintf
の実装は https://github.com/mirror/newlib-cygwin/blob/master/newlib/libc/stdio/sprintf.c になる。これをビルドしたものが既に devenv/x86_64-elf/lib/libc.a
として置いてあるのでリンカに -lc
を追加すると静的リンクされる。Makefile
には
CC = clang CFLAGS += -O2 -Wall -g --target=x86_64-elf -ffreestanding -mno-red-zone ... $(TARGET): $(OBJS) $(LD) $(LDFLAGS) -o $@ $(OBJS) -lc ... %.c.o: $(CC) $(CPPFLAGS) $(CFLAGS) -c $<
くらいを追加しておけば良い。また本の通りにやらないと
ld.lld: error: undefined symbol: sbrk
>>> referenced by sbrkr.c
が出るので、本の通りにスタブ実装を追加してカーネルをビルドする。
まだまだだけど、画面がどんどんできてくる感じはある。libc
とかよそから持ってきたり色々思うところはあるけど、フルスクラッチは流石にきついわな・・・。
sprintf
とかはユーザーランドで使える関数という思い込みがあってしまうが、コンパイルされたら単なる ELF フォーマットの機械語のバイナリなので、メモリ管理のような OS の機能とかを使わないなら動くんだな〜と言うのがある意味で新鮮。
day05d(〜p.128)は終わり。
*****
写経をミスって文字列が全然コンソールに表示されなかった。単に書き出す部分の写経が抜けていただけだが、デバッガでアタッチして、などの方法がとれないので動かない場合にコードを見直すくらいしかできないな・・・。
day05e(〜p.131)は終わり。
*****
淡々と写経。
QEMU の起動に失敗(?)してドキドキした・・・。問題時の切り分け難しいなぁ・・・。
day05f(〜p.134)は終わり。