Smaller CでFreeDOS用プログラムの作成
はじめに
Smaller Cを使用して
FreeDOSのプログラムの作成をしてみます。
Smaller Cについて
詳細は以下
プリプロセッサ、コンパイラ、リンカが提供されているようです。
アセンブラは別途用意する必要があります(nasmなど)
Smaller のビルド
ドキュメントを見ると、
How do I compile Smaller C on/for x86?
With 32-bit gcc in Linux:gcc -Wall -Wextra -O2 smlrc.c -o smlrc
と、あるのでgccでビルドができるようです。
ver9.3.0でビルドができました。(Ubuntu上で実行)
$ gcc --version
gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
make時の出力は以下。
$ make
gcc -pipe -Wall -O2 -DPATH_PREFIX='"/usr/local"' -DHOST_LINUX /home/USERNAME/freedos/SmallerC/v0100/smlrc.c -o smlrc
gcc -pipe -Wall -O2 -DPATH_PREFIX='"/usr/local"' -DHOST_LINUX /home/USERNAME/freedos/SmallerC/v0100/smlrl.c -o smlrl
/home/USERNAME/freedos/SmallerC/v0100/smlrl.c: In function ‘RwPe’:
/home/USERNAME/freedos/SmallerC/v0100/smlrl.c:3134:105: warning: suggest parentheses around ‘-’ in operand of ‘&’ [-Wparentheses]
3134 | ((pSectDescrs[textSectCnt + roDataSectCnt + impDataSectCnt - 1].Stop + 0xFFF) & 0xFFFFF000) -
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
3135 | pSectDescrs[textSectCnt + roDataSectCnt].Start & 0xFFFFF000;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/USERNAME/freedos/SmallerC/v0100/smlrl.c:3262:20: warning: variable ‘sectNameLen’ set but not used [-Wunused-but-set-variable]
3262 | size_t sectNameLen;
| ^~~~~~~~~~~
gcc -pipe -Wall -O2 -DPATH_PREFIX='"/usr/local"' -DHOST_LINUX /home/USERNAME/freedos/SmallerC/v0100/smlrcc.c -o smlrcc
/home/USERNAME/freedos/SmallerC/v0100/smlrcc.c: In function ‘Archive’:
/home/USERNAME/freedos/SmallerC/v0100/smlrcc.c:1029:15: warning: ‘%lu’ directive writing between 2 and 19 bytes into a region of size 13 [-Wformat-overflow=]
1029 | fh.name[sprintf(fh.name, "#1/%lu", l)] = ' '; // Use BSD(in-place) format for long names
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/USERNAME/freedos/SmallerC/v0100/smlrcc.c:1029:15: note: directive argument in the range [16, 9223372036854775805]
In file included from /usr/include/stdio.h:867,
from /home/USERNAME/freedos/SmallerC/v0100/smlrcc.c:69:
/usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 6 and 23 bytes into a destination of size 16
36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37 | __bos (__s), __fmt, __va_arg_pack ());
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/USERNAME/freedos/SmallerC/v0100/smlrcc.c:1044:15: warning: ‘%lu’ directive writing between 2 and 19 bytes into a region of size 10 [-Wformat-overflow=]
1044 | fh.size[sprintf(fh.size, "%lu", l)] = ' ';
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
/home/USERNAME/freedos/SmallerC/v0100/smlrcc.c:1044:15: note: directive argument in the range [16, 9223372037391646717]
In file included from /usr/include/stdio.h:867,
from /home/USERNAME/freedos/SmallerC/v0100/smlrcc.c:69:
/usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 3 and 20 bytes into a destination of size 10
36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37 | __bos (__s), __fmt, __va_arg_pack ());
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gcc -pipe -Wall -O2 -DPATH_PREFIX='"/usr/local"' -DHOST_LINUX -o smlrpp -DSTAND_ALONE -DUCPP_CONFIG \
/home/USERNAME/freedos/SmallerC/v0100/ucpp/arith.c \
/home/USERNAME/freedos/SmallerC/v0100/ucpp/assert.c \
/home/USERNAME/freedos/SmallerC/v0100/ucpp/cpp.c \
/home/USERNAME/freedos/SmallerC/v0100/ucpp/eval.c \
/home/USERNAME/freedos/SmallerC/v0100/ucpp/lexer.c \
/home/USERNAME/freedos/SmallerC/v0100/ucpp/macro.c \
/home/USERNAME/freedos/SmallerC/v0100/ucpp/mem.c \
/home/USERNAME/freedos/SmallerC/v0100/ucpp/nhash.c
gcc -pipe -Wall -O2 -DPATH_PREFIX='"/usr/local"' -DHOST_LINUX /home/USERNAME/freedos/SmallerC/v0100/n2f.c -o n2f
/usr/bin/ld: /tmp/ccowDKSK.o: in function `convert':
n2f.c:(.text+0xcb3): 警告: the use of `tmpnam' is dangerous, better use `mkstemp'
awk -v l=/home/USERNAME/freedos/SmallerC/v0100/srclib/ '/[.](c|asm)$/{$0=l$0}{print}' /home/USERNAME/freedos/SmallerC/v0100/srclib/lcdh.txt > lcdh.op
./smlrcc -SI /home/USERNAME/freedos/SmallerC/v0100/include -I /home/USERNAME/freedos/SmallerC/v0100/srclib @lcdh.op
awk -v l=/home/USERNAME/freedos/SmallerC/v0100/srclib/ '/[.](c|asm)$/{$0=l$0}{print}' /home/USERNAME/freedos/SmallerC/v0100/srclib/lcdu.txt > lcdu.op
./smlrcc -SI /home/USERNAME/freedos/SmallerC/v0100/include -I /home/USERNAME/freedos/SmallerC/v0100/srclib @lcdu.op
awk -v l=/home/USERNAME/freedos/SmallerC/v0100/srclib/ '/[.](c|asm)$/{$0=l$0}{print}' /home/USERNAME/freedos/SmallerC/v0100/srclib/lcds.txt > lcds.op
./smlrcc -SI /home/USERNAME/freedos/SmallerC/v0100/include -I /home/USERNAME/freedos/SmallerC/v0100/srclib @lcds.op
awk -v l=/home/USERNAME/freedos/SmallerC/v0100/srclib/ '/[.](c|asm)$/{$0=l$0}{print}' /home/USERNAME/freedos/SmallerC/v0100/srclib/lcw.txt > lcw.op
./smlrcc -SI /home/USERNAME/freedos/SmallerC/v0100/include -I /home/USERNAME/freedos/SmallerC/v0100/srclib @lcw.op
awk -v l=/home/USERNAME/freedos/SmallerC/v0100/srclib/ '/[.](c|asm)$/{$0=l$0}{print}' /home/USERNAME/freedos/SmallerC/v0100/srclib/lcl.txt > lcl.op
./smlrcc -SI /home/USERNAME/freedos/SmallerC/v0100/include -I /home/USERNAME/freedos/SmallerC/v0100/srclib @lcl.op
awk -v l=/home/USERNAME/freedos/SmallerC/v0100/srclib/ '/[.](c|asm)$/{$0=l$0}{print}' /home/USERNAME/freedos/SmallerC/v0100/srclib/lcdp.txt > lcdp.op
./smlrcc -SI /home/USERNAME/freedos/SmallerC/v0100/include -I /home/USERNAME/freedos/SmallerC/v0100/srclib @lcdp.op
awk -v l=/home/USERNAME/freedos/SmallerC/v0100/srclib/ '/[.](c|asm)$/{$0=l$0}{print}' /home/USERNAME/freedos/SmallerC/v0100/srclib/lcm.txt > lcm.op
./smlrcc -SI /home/USERNAME/freedos/SmallerC/v0100/include -I /home/USERNAME/freedos/SmallerC/v0100/srclib @lcm.op
./smlrcc -small /home/USERNAME/freedos/SmallerC/v0100/srclib/dpstub.asm -o dpstub.exe
rm lcl.op lcds.op lcw.op lcdh.op lcdp.op lcdu.op lcm.op
FreeDOS版Hello world
以下のようなファイルを用意します。
#include <stdio.h>
int main(){
printf("Hello FreeDOS\n");
return 0;
}
先程ビルドしたコンパイラドライバ(smlrcc)で
ビルドしてみます。
オプションの詳細はドキュメントを参照してください。
$ smlrcc -v -dost -o hello.com hello.c
smlrpp -U __STDC_VERSION__ -zI -D _DOS -D __SMALLER_C__ -D __SMALLER_C_16__ -D __SMALLER_C_SCHAR__ -D __SMALLER_C_UWCHAR__ -D __SMALLER_C_WCHAR16__ -D __SMALLER_PP__ -o hello.i hello.c
hello.c: line 1: file 'stdio.h' not found
Executed command failed
ヘッダが無いよ、と言われてしまいました。
-I
オプションを指定してヘッダファイルのパスを指定する必要があります。
インクルードファイルのパスを追加してもう一度ビルドしてみます。
$ smlrcc -v -dost -IPATH/SmallerC/v0100/include -o hello.com hello.c
smlrpp -U __STDC_VERSION__ -zI -D _DOS -I PATH/SmallerC/v0100/include -D __SMALLER_C__ -D __SMALLER_C_16__ -D __SMALLER_C_SCHAR__ -D __SMALLER_C_UWCHAR__ -D __SMALLER_C_WCHAR16__ -D __SMALLER_PP__ -o hello.i hello.c
smlrc -seg16 -nopp hello.i hello.asm
nasm -f elf hello.asm -o hello.o
smlrl -tiny hello.o -o hello.com
Symbol '__start' not found
Executed command failed
今度はリンクで失敗しました。
-SL
オプションでライブラリのパスを設定する必要があります。
$ smlrcc -v -dost -IPATH/SmallerC/v0100/include -SLPATH/SmallerC/v0100/lib -o hello.com hello.c
smlrpp -U __STDC_VERSION__ -zI -D _DOS -I PATH/SmallerC/v0100/include -D __SMALLER_C__ -D __SMALLER_C_16__ -D __SMALLER_C_SCHAR__ -D __SMALLER_C_UWCHAR__ -D __SMALLER_C_WCHAR16__ -D __SMALLER_PP__ -o hello.i hello.c
smlrc -seg16 -nopp hello.i hello.asm
nasm -f elf hello.asm -o hello.o
smlrl -tiny hello.o PATH/SmallerC/v0100/lib/lcds.a -o hello.com
これでhello.com
が作成されました。
$ file hello.com
hello.com: DOS executable (COM)
FreeDOSで実行
Linux(Ubuntu)上でhello.com
が作成できたので、
FreeDOSにhello.com
ファイルを持っていって実行すると、実行できました。
C:\>hello
Hello FreeDOS
まとめ
今回は、Linux上でFreeDOS用のプログラムのビルドをしてみました。
gccもあるのですが、
ちょっと違うコンパイラを使うのも楽しいかなと思い書いてみました。
補足:ファイルをlinux環境からFreeDOS環境に移動
今回は Linux(Virtual box)上でFreeDOS用のプログラムの作成、
作成したプログラムを
FreeDOS(Virtual box)上で実行、ということをしました。
ファイルのコピーが面倒です。今回はこのようにしました。
Linux(Virtual box)からホスト(win)にコピー
Virtual boxの共有の設定で適当なフォルダを設定します。
これで、linux上からホスト側にファイルのコピーができます。
コピー例は以下。
$ sudo cp hello.com /media/sf_VirtualBox_share
ホスト(win)からFreeDOS(Virtual box)にコピー
ディスクの管理からVHDの接続
を選択して、
FreeDOSをインストールしたディスクイメージ(*.VHD)を選択します。
そうすると、エクスプローラーからディスクの中が見れるので、
先程Linuxからコピーしたファイルをコピーします。
Discussion