まだ格闘しているが、なんかうまく行かないなあ。
まず、システムコールあたりは正しく動作しないのは当然だ。bare-metalでコンパイルしているため、mallocでメモリを獲得したくたって、そもそも下にOSが存在しない。 よって、独自のライブラリを作るか、そこら辺をソースコードで全部カットしてしまうか...
後者はソースの改造が大変なため、なんとかダミーのライブラリを実装して事を済ませたい。 つまりは、こういうエラーメッセージが出る、ということである。
(.text+0x1f0): undefined reference to `stat' /usr/local/lib/gcc/mipsel-unknown-elf/5.1.0/../../../../mipsel-unknown-elf/lib/libc.a(lib_a-exit.o): In function `exit': (.text+0x38): undefined reference to `_exit' /usr/local/lib/gcc/mipsel-unknown-elf/5.1.0/../../../../mipsel-unknown-elf/lib/libc.a(lib_a-sbrkr.o): In function `_sbrk_r': (.text+0x14): undefined reference to `sbrk' /usr/local/lib/gcc/mipsel-unknown-elf/5.1.0/../../../../mipsel-unknown-elf/lib/libc.a(lib_a-writer.o): In function `_write_r': (.text+0x20): undefined reference to `write' /usr/local/lib/gcc/mipsel-unknown-elf/5.1.0/../../../../mipsel-unknown-elf/lib/libc.a(lib_a-closer.o): In function `_close_r': (.text+0x14): undefined reference to `close' /usr/local/lib/gcc/mipsel-unknown-elf/5.1.0/../../../../mipsel-unknown-elf/lib/libc.a(lib_a-lseekr.o): In function `_lseek_r': (.text+0x20): undefined reference to `lseek' /usr/local/lib/gcc/mipsel-unknown-elf/5.1.0/../../../../mipsel-unknown-elf/lib/libc.a(lib_a-readr.o): In function `_read_r': (.text+0x20): undefined reference to `read' /usr/local/lib/gcc/mipsel-unknown-elf/5.1.0/../../../../mipsel-unknown-elf/lib/libc.a(lib_a-strtoll_r.o): In function `_strtoll_r': (.text+0xc0): undefined reference to `__umoddi3' /usr/local/lib/gcc/mipsel-unknown-elf/5.1.0/../../../../mipsel-unknown-elf/lib/libc.a(lib_a-strtoll_r.o): In function `_strtoll_r': (.text+0xe0): undefined reference to `__udivdi3' /usr/local/lib/gcc/mipsel-unknown-elf/5.1.0/../../../../mipsel-unknown-elf/lib/libc.a(lib_a-strtoull_r.o): In function `_strtoull_r': (.text+0xa4): undefined reference to `__udivdi3' /usr/local/lib/gcc/mipsel-unknown-elf/5.1.0/../../../../mipsel-unknown-elf/lib/libc.a(lib_a-strtoull_r.o): In function `_strtoull_r': (.text+0xc0): undefined reference to `__umoddi3' /usr/local/lib/gcc/mipsel-unknown-elf/5.1.0/../../../../mipsel-unknown-elf/lib/libc.a(lib_a-svfprintf.o): In function `_svfprintf_r': (.text+0x8c8): undefined reference to `__umoddi3' /usr/local/lib/gcc/mipsel-unknown-elf/5.1.0/../../../../mipsel-unknown-elf/lib/libc.a(lib_a-svfprintf.o): In function `_svfprintf_r': (.text+0x8e8): undefined reference to `__udivdi3' /usr/local/lib/gcc/mipsel-unknown-elf/5.1.0/../../../../mipsel-unknown-elf/lib/libc.a(lib_a-vfprintf.o): In function `_vfprintf_r': (.text+0x4ec): undefined reference to `__umoddi3' /usr/local/lib/gcc/mipsel-unknown-elf/5.1.0/../../../../mipsel-unknown-elf/lib/libc.a(lib_a-vfprintf.o): In function `_vfprintf_r': (.text+0x50c): undefined reference to `__udivdi3' /usr/local/lib/gcc/mipsel-unknown-elf/5.1.0/../../../../mipsel-unknown-elf/lib/libc.a(lib_a-svfiprintf.o): In function `_svfiprintf_r': (.text+0x88c): undefined reference to `__umoddi3' /usr/local/lib/gcc/mipsel-unknown-elf/5.1.0/../../../../mipsel-unknown-elf/lib/libc.a(lib_a-svfiprintf.o): In function `_svfiprintf_r': (.text+0x8ac): undefined reference to `__udivdi3' /usr/local/lib/gcc/mipsel-unknown-elf/5.1.0/../../../../mipsel-unknown-elf/lib/libc.a(lib_a-vfiprintf.o): In function `_vfiprintf_r': (.text+0x8d0): undefined reference to `__umoddi3' /usr/local/lib/gcc/mipsel-unknown-elf/5.1.0/../../../../mipsel-unknown-elf/lib/libc.a(lib_a-vfiprintf.o): In function `_vfiprintf_r': (.text+0x8f0): undefined reference to `__udivdi3' /usr/local/lib/gcc/mipsel-unknown-elf/5.1.0/../../../../mipsel-unknown-elf/lib/libc.a(lib_a-fstatr.o): In function `_fstat_r': (.text+0x1c): undefined reference to `fstat' /usr/local/lib/gcc/mipsel-unknown-elf/5.1.0/../../../../mipsel-unknown-elf/lib/libc.a(lib_a-isattyr.o): In function `_isatty_r': (.text+0x14): undefined reference to `isatty'
まあexitとか、sbrkとか無いのは当然だよね、ってかLinuxも乗ってないのに、そんなものがうまく動くはずがない。
いろいろ調べてみて、まずは以下を参考にしてみた。
Using Newlib in ARM bare metal programsbalau82.wordpress.com
独自にsbrkなどの関数を実装してみる。ちなみに、各システムコールの意味は、MITのxv6の教科書に概要が書いてある。
sbrkはメモリ領域を拡張する関数だ。実装を見てみると、
caddr_t _sbrk(int incr) { extern char heap_low; /* Defined by the linker */ extern char heap_top; /* Defined by the linker */ char *prev_heap_end; if (heap_end == 0) { heap_end = &heap_low; } prev_heap_end = heap_end; if (heap_end + incr > &heap_top) { /* Heap and stack collision */ return (caddr_t)0; } heap_end += incr; return (caddr_t) prev_heap_end; }
あー、やりたいことは何となく分かった気がする。 しかし、このコードはコンパイルできても、また正しくリンクしてバイナリファイルが出来ていない! もうちょっと頑張る...