NetBSD/x68k boot loader. The xxboot now can boot NetBSD from
1. >1GB SCSI disks, 2. any of the top 7 partitions on disks, and 3. any SCSI interface.
This commit is contained in:
parent
ecc30b1784
commit
f9175d6bc7
|
@ -0,0 +1,69 @@
|
||||||
|
# $NetBSD: Makefile,v 1.1 1998/09/01 20:02:32 itohy Exp $
|
||||||
|
|
||||||
|
BOOT= xxboot
|
||||||
|
VERSION=0.3
|
||||||
|
|
||||||
|
# text and bss addresses in hex
|
||||||
|
TEXT= 3f0000
|
||||||
|
BSS= 3f2000
|
||||||
|
|
||||||
|
PROG= $(BOOT)
|
||||||
|
BINDIR= /usr/mdec
|
||||||
|
PROGNAME= sdboot
|
||||||
|
LINKS= ${BINDIR}/sdboot ${BINDIR}/fdboot
|
||||||
|
STRIPFLAG=
|
||||||
|
BINMODE= 444
|
||||||
|
SCRIPTSMODE= 555
|
||||||
|
SCRIPTS= installboot.sh
|
||||||
|
NOMAN= noman
|
||||||
|
|
||||||
|
STRIP?= strip
|
||||||
|
|
||||||
|
SRCS= xxboot.S bootufs.c unzip.c
|
||||||
|
.PATH: ${.CURDIR}/gunzip
|
||||||
|
|
||||||
|
CFLAGS= -O -fomit-frame-pointer
|
||||||
|
CFLAGS+= -W -Wall -Wconversion -Wstrict-prototypes -Wmissing-prototypes
|
||||||
|
CFLAGS+= -DTEXTADDR="0x$(TEXT)" -DBOOT=\"$(BOOT)\" -DBOOT_VERS=\"$(VERSION)\"
|
||||||
|
CFLAGS+= -DGZIP -DSCSI_ADHOC_BOOTPART
|
||||||
|
CFLAGS+= -DTITLE_IMAGE -DIMAGE_EXTRA=100
|
||||||
|
#CFLAGS+= -DBOOT_DEBUG
|
||||||
|
AFLAGS= ${CFLAGS:M-[ID]*}
|
||||||
|
LDFLAGS=-n -Bstatic -T $(TEXT)
|
||||||
|
#LDADD= -lc
|
||||||
|
|
||||||
|
CLEANFILES= $(BOOT).x s.x x.s x.o
|
||||||
|
CLEANFILES+= ej2sjesc.lo ej2sjesc *.o.c *.o.s *.o.o
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
./ej2sjesc ${.IMPSRC} ${.TARGET}.c
|
||||||
|
@echo '${CC} -fall-bsr ${CFLAGS} ${CPPFLAGS} -o ${.TARGET} -c ${.TARGET}.c'
|
||||||
|
@${CC} ${CFLAGS} ${CPPFLAGS} -S ${.TARGET}.c -o ${.TARGET}.s
|
||||||
|
@${CC} -c -o ${.TARGET}.o ${.TARGET}.s
|
||||||
|
@${NM} ${.TARGET}.o | ${.CURDIR}/all_bsr.sh ${.TARGET}.s | ${AS} -o ${.TARGET}
|
||||||
|
@rm -f ${.TARGET}.c ${.TARGET}.s ${.TARGET}.o
|
||||||
|
|
||||||
|
$(BOOT): $(OBJS)
|
||||||
|
$(LD) $(LDFLAGS) -o $(BOOT).x $(OBJS) $(LDADD)
|
||||||
|
@$(NM) $(BOOT).x | sed -n '/T first_kbyte/p'
|
||||||
|
@if [ `(echo ibase=16; \
|
||||||
|
$(NM) $(BOOT).x | sed -n 's/T first_kbyte/-$(TEXT)-400/p' | \
|
||||||
|
tr a-f A-F) | bc` -gt 0 ];\
|
||||||
|
then echo '$(BOOT): first_kbyte exceeds the first killobyte'; exit 1; fi
|
||||||
|
@$(SIZE) $(BOOT).x
|
||||||
|
@if [ `(echo ibase=16; \
|
||||||
|
$(NM) $(BOOT).x | sed -n 's/D _edata/-$(BSS)/p' | tr a-f A-F) |\
|
||||||
|
bc` -gt 0 ];\
|
||||||
|
then echo '$(BOOT): text+data is too large'; exit 1; fi
|
||||||
|
@cp $(BOOT).x s.x
|
||||||
|
@$(STRIP) s.x
|
||||||
|
@dd bs=32 skip=1 count=256 if=s.x of=$(BOOT) 2>/dev/null
|
||||||
|
@rm s.x
|
||||||
|
|
||||||
|
bootufs.o unzip.o: ej2sjesc
|
||||||
|
|
||||||
|
# helper program running on the host
|
||||||
|
ej2sjesc: ej2sjesc.lo
|
||||||
|
${HOST_LINK.c} -o ${.TARGET} ${.ALLSRC}
|
||||||
|
|
||||||
|
.include <bsd.prog.mk>
|
|
@ -0,0 +1,58 @@
|
||||||
|
# $NetBSD: README.sdboot,v 1.1 1998/09/01 20:02:33 itohy Exp $
|
||||||
|
|
||||||
|
Mon Aug 1st 1994
|
||||||
|
README.sdboot (*euc-japan*)
|
||||||
|
author:chapuni
|
||||||
|
GBA02750@niftyserve.or.jp
|
||||||
|
|
||||||
|
|
||||||
|
久しくバージョンアップを怠っていた sdboot を、ちょっと使いやすくして
|
||||||
|
みました。sdboot とは、 NetBSD 用のブートプログラムで、これを HDD に書
|
||||||
|
き込むことにより、NetBSD を HDD より起動することが可能となります。
|
||||||
|
|
||||||
|
|
||||||
|
install
|
||||||
|
~~~~~~~~~
|
||||||
|
もし、御使用の HDD の SCSI ID が 0 であれば、
|
||||||
|
|
||||||
|
$ make install
|
||||||
|
|
||||||
|
でオーケーです。
|
||||||
|
|
||||||
|
そうでない場合は、Makefile の
|
||||||
|
|
||||||
|
$ cat sdboot > /dev/rsd0a
|
||||||
|
~
|
||||||
|
0 の部分を、インストール先の ID に修正してください。/kern を覗けばど
|
||||||
|
のデバイスから起動したのかがわかるので、これは手抜きですね。
|
||||||
|
|
||||||
|
|
||||||
|
usage
|
||||||
|
~~~~~~~
|
||||||
|
SHIFT キーを押しながら起動すると、カーネル選択の画面に移行します。こ
|
||||||
|
こでは、vmunix, netbsd で始まる名前のファイルが列挙されます。
|
||||||
|
|
||||||
|
カーネル選択の画面にて、さらに SHIFT キーを押すことによって、カーネ
|
||||||
|
ル起動時のシングルユーザ/マルチユーザ状態を制御することができます。カー
|
||||||
|
ソル上下キー、SHIFT キーで選択したら、リターンキーでカーネルの起動が行な
|
||||||
|
われます。
|
||||||
|
|
||||||
|
「ひらがな」LED が点灯している状態では、カーネルデバッガを起動しよう
|
||||||
|
とします。
|
||||||
|
|
||||||
|
progression
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
前回のバージョン(沖さんがリリースしたバージョン)からの改善点/改良
|
||||||
|
点は以下の通りです。
|
||||||
|
|
||||||
|
・起動するカーネルが選択できるようになりました。
|
||||||
|
・カーネルデバッガ(ふつうは ddb)の起動を指定できるようになりました。
|
||||||
|
・SHIFT キーの押下判定を緩めました。
|
||||||
|
・読み込み速度を高速にしました。
|
||||||
|
|
||||||
|
改悪点は以下の通りです。
|
||||||
|
|
||||||
|
・メッセージ「まじかよ?」その他がなくなった。
|
||||||
|
|
||||||
|
|
||||||
|
- 以上 -
|
|
@ -0,0 +1,301 @@
|
||||||
|
# $NetBSD: README.xxboot,v 1.1 1998/09/01 20:02:33 itohy Exp $
|
||||||
|
|
||||||
|
xxboot version 0.3
|
||||||
|
|
||||||
|
xxboot は:
|
||||||
|
|
||||||
|
NetBSD/x68k を起動するためのブートプログラムです。
|
||||||
|
次のデバイスからのブートに対応しています。
|
||||||
|
|
||||||
|
o SCSI ディスクの先頭 7 パーティション
|
||||||
|
o フロッピーディスクの次の物理フォーマットのもの
|
||||||
|
1232KB (1024byte/sector, 8sector/track): X68k 標準フォーマット
|
||||||
|
1200KB (512byte/sector, 15sector/track): 俗に 2HC とかいうやつ
|
||||||
|
|
||||||
|
注意: 現在のところ、1232KB フォーマットのディスク上には
|
||||||
|
正常にファイルシステムが構築できませんので、root ファイルシステム
|
||||||
|
などをこのフォーマットのディスクに置くことはできません。
|
||||||
|
ただし、ファイルシステムを一旦 vnode disk driver (vnd) 上に作成して
|
||||||
|
からフロッピーに書き込むことにより、memory disk (md) を root として
|
||||||
|
起動するブートディスクを作成することは可能です。
|
||||||
|
|
||||||
|
|
||||||
|
sdboot, fdboot との違い:
|
||||||
|
|
||||||
|
xxboot は、NetBSD 1.2 に含まれている sdboot (chapuni氏作) や fdboot と
|
||||||
|
同じような機能を持っています。主な機能的な違いは次のようなものです。
|
||||||
|
|
||||||
|
o SCSI ディスクとフロッピーとで同じバイナリを使う。
|
||||||
|
|
||||||
|
o gzip で圧縮されたカーネルを読み込むことができる。
|
||||||
|
それにともない、デフォルトで読み込むカーネルのファイル名
|
||||||
|
として、netbsd のほかに netbsd.gz が加えられた。
|
||||||
|
|
||||||
|
要するに、sdboot, fdboot, gunzip をつぎはぎしたもですね。
|
||||||
|
|
||||||
|
|
||||||
|
install:
|
||||||
|
|
||||||
|
1. make します
|
||||||
|
% make
|
||||||
|
|
||||||
|
2. /usr/mdec に置きます。
|
||||||
|
# make install
|
||||||
|
|
||||||
|
|
||||||
|
ディスクへの書き込み:
|
||||||
|
|
||||||
|
a. フロッピー
|
||||||
|
予め disklabel を書いたディスクに対して installboot で書き込みます。
|
||||||
|
# /usr/mdec/installboot /usr/mdec/fdboot /dev/rfd0c
|
||||||
|
^^
|
||||||
|
^^ の部分は書き込み先によって変更します。
|
||||||
|
|
||||||
|
b. SCSI ディスク
|
||||||
|
# /usr/mdec/installboot /usr/mdec/sdboot /dev/rsd0a
|
||||||
|
^^
|
||||||
|
^^ の部分は書き込み先によって変更します。
|
||||||
|
|
||||||
|
|
||||||
|
使いかたなど:
|
||||||
|
|
||||||
|
sdboot と全く同じです。README.sdboot などを参照してください。
|
||||||
|
(ああなんて手抜き)
|
||||||
|
|
||||||
|
カーネルを gzip で圧縮して使用する場合は、
|
||||||
|
あらかじめ、圧縮しない状態で、一度マルチユーザブートするか、
|
||||||
|
kvm_mkdb を実行して /var/db/kvm.db を作成しておくと、
|
||||||
|
ps などのカーネルを参照するコマンドも正常に動作するようです。
|
||||||
|
|
||||||
|
|
||||||
|
エラー:
|
||||||
|
|
||||||
|
xxboot は、エラーを検出すると、
|
||||||
|
|
||||||
|
xxboot: unsupported boot device
|
||||||
|
[Hit key to reboot]
|
||||||
|
|
||||||
|
のような表示をしてキー入力待ちになります。
|
||||||
|
ここで何かキーを押すとソフトウェアリセットがかかって再起動します。
|
||||||
|
エラーには次のようなものがあります:
|
||||||
|
|
||||||
|
"4MB RAM required"
|
||||||
|
主記憶が 4MB より少ないので xxboot をロードできません。
|
||||||
|
4MB 以上実装してあるのにこれが表示される時は、switch.x で
|
||||||
|
メモリスイッチを確認してください。
|
||||||
|
|
||||||
|
"MPU 68000?"
|
||||||
|
68000, 68008, 68010 でブートしようとしました。
|
||||||
|
|
||||||
|
"unsupported boot device"
|
||||||
|
現在のところ、このデバイスからのブートはできません。
|
||||||
|
きっと SASI HD か SRAM から起動しようとしたのでしょう。
|
||||||
|
|
||||||
|
"READ ID failed"
|
||||||
|
フロッピーのフォーマットを判定するための READ ID が失敗しました。
|
||||||
|
|
||||||
|
"READCAP failed"
|
||||||
|
SCSI HD のブロック長を調べるための READCAP が失敗しました。
|
||||||
|
|
||||||
|
"read error"
|
||||||
|
SCSI HD またはフロッピーの読み込みに失敗しました。
|
||||||
|
|
||||||
|
"read half of block"
|
||||||
|
ディスクのブロック(セクタ)よりファイルシステムのブロックが短いと
|
||||||
|
このエラーになることがあります。
|
||||||
|
|
||||||
|
"Can't boot from this partition"
|
||||||
|
先頭 7 個以外のパーティションから起動しようとしました。
|
||||||
|
あるいは、起動パーティションの特定に失敗しました。
|
||||||
|
|
||||||
|
"bogus super block: ルートファイルシステムが壊れています!"
|
||||||
|
正常なスーパーブロックが読めませんでした。
|
||||||
|
|
||||||
|
"improper file format: 実行不可能です。"
|
||||||
|
カーネルとして読み込んだファイルの形式が異常です。
|
||||||
|
|
||||||
|
"invalid compressed data"
|
||||||
|
"out of memory"
|
||||||
|
"unknown compression method"
|
||||||
|
"unsupported compression flag"
|
||||||
|
gzip 圧縮されたデータが異常です。
|
||||||
|
|
||||||
|
|
||||||
|
プログラムについて:
|
||||||
|
|
||||||
|
ブートプログラムの大部分は chapuni さんが書いたものです。
|
||||||
|
gzip の展開部分 (gunzip/inflate.c) は、gzip-1.2.4 の
|
||||||
|
Not copyrighted なコードから拝借しました。
|
||||||
|
Copyright のある部分は使用せずに私が書き直しましたので、
|
||||||
|
GPL に従う必要はありません。
|
||||||
|
私の作成/変更した部分について、(怪し気なスクリプトも含め)
|
||||||
|
著作権を主張するつもりはありません。
|
||||||
|
|
||||||
|
タイトルとして使っている BSD Daemon の著作権は、
|
||||||
|
Marshall Kirk McKusick 氏(mckusick@mckusick.com)が保持しています。
|
||||||
|
NetBSD/x68k の boot プログラムに使用して、Berkeley ライセンスで
|
||||||
|
配布するための許可を頂きました。
|
||||||
|
容量が残っていれば、バイナリにも "Copyright 1988 McKusick" のような
|
||||||
|
著作権表示を残してほしい(ただし必須ではない)とのことです。
|
||||||
|
他に転用する場合は、McKusick 氏に許可を求めてください。
|
||||||
|
|
||||||
|
BSD Daemon Copyright 1988 by Marshall Kirk McKusick.
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
Permission to use the daemon may be obtained from:
|
||||||
|
Marshall Kirk McKusick
|
||||||
|
1614 Oxford St
|
||||||
|
Berkeley, CA 94709-1608
|
||||||
|
USA
|
||||||
|
or via email at mckusick@mckusick.com
|
||||||
|
|
||||||
|
|
||||||
|
変更履歴:
|
||||||
|
ver 0.3
|
||||||
|
o 1GB 以上の SCSI ディスクからもブートできるようにした。
|
||||||
|
|
||||||
|
o SCSI ディスクの先頭以外のパーティションからもブートできるようにした。
|
||||||
|
|
||||||
|
o エラーチェックを大幅に強化した。
|
||||||
|
また、エラー時にキー入力を待って reboot するようにした。
|
||||||
|
|
||||||
|
o 内蔵、純正 SCSI ボード(またはその互換ボード)、満開 Mach-2 の
|
||||||
|
どれからブートしたかを調べてカーネルに渡すようにした。
|
||||||
|
|
||||||
|
o loadbsd.x と共通のカーネル転送コードを使うようにした。
|
||||||
|
|
||||||
|
o chapuni 氏の野望を引き継ぎ、無意味にグラフィカルにした。
|
||||||
|
|
||||||
|
o さらに、タイトルの絵を差し替えられるツールをこっそり
|
||||||
|
img ディレクトリに置いた。
|
||||||
|
|
||||||
|
ver 0.2
|
||||||
|
o タイマ、外部 power on の場合に、正常に動かない不具合を修正した。
|
||||||
|
|
||||||
|
o ソースを一部整理し、また、コードサイズを減らした。
|
||||||
|
|
||||||
|
ver 0.1
|
||||||
|
o make depend がうまく動くように xxboot.s → xxboot.S に
|
||||||
|
ファイル名を変更した。
|
||||||
|
|
||||||
|
o GPL なコードを排除した。
|
||||||
|
副作用として、100byte ほどコードが減った。
|
||||||
|
|
||||||
|
|
||||||
|
以下はソースを読む人向けです。
|
||||||
|
|
||||||
|
ソースについて:
|
||||||
|
ブートプログラム本体は、text+data を 8KB に、bss を 56KB に
|
||||||
|
収める必要があります。
|
||||||
|
8KB におさめるために、あちらこちらで変なことをしています。
|
||||||
|
ちなみに、もうほとんど容量が残っていません。
|
||||||
|
gunzip/inflate.c で malloc() を使っていたのですが、
|
||||||
|
malloc()/free() のパタンの性質を使って、にせものの
|
||||||
|
malloc をでっち上げてあります。malloc() 用のバッファは
|
||||||
|
bss ではなくスタックから取っています(bss も残り少ないから)。
|
||||||
|
|
||||||
|
bootufs.c ブートプログラム本体
|
||||||
|
xxboot.S アセンブリで書いた部分
|
||||||
|
chkfmt.s フロッピーのフォーマットを調べる部分
|
||||||
|
iocscall.h アセンブラ用ヘッダ
|
||||||
|
xxboot.h C 用ヘッダ
|
||||||
|
gunzip/* gzip の展開ルーチン asm() に注意
|
||||||
|
|
||||||
|
|
||||||
|
メモリマップ:
|
||||||
|
000000 |-----------------------------|
|
||||||
|
| 最終的にカーネルは 0 番地に |
|
||||||
|
| 転送される |
|
||||||
|
| ↓ |
|
||||||
|
002000 |-----------------------------|
|
||||||
|
|xxboot が最初に読まれる(FD) |
|
||||||
|
002400 |-----------------------------|
|
||||||
|
|xxboot が最初に読まれる(SCSI)|
|
||||||
|
002800 |-----------------------------|
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
100000 |-----------------------------|
|
||||||
|
| カーネル読み込みバッファ |
|
||||||
|
| ↓ |
|
||||||
|
| |
|
||||||
|
: :
|
||||||
|
| |
|
||||||
|
| ↑ |
|
||||||
|
| gzip の展開に使う |
|
||||||
|
3E8000 |-----------------------------|
|
||||||
|
| ↑ |
|
||||||
|
| xxboot のスタック |
|
||||||
|
3F0000 |-----------------------------|
|
||||||
|
| xxboot の text + data (8KB) |
|
||||||
|
3F2000 |-----------------------------|
|
||||||
|
| xxboot の bss (56KB) |
|
||||||
|
3FFFFF |-----------------------------| 4MB マシンの主記憶の上限
|
||||||
|
|
||||||
|
|
||||||
|
ブート動作:
|
||||||
|
1. まず、IOCS や SCSI の IPL により、xxboot の先頭 1KB が、
|
||||||
|
0x002000 (フロッピー), 0x002400 (SCSI) に読み込まれ、
|
||||||
|
先頭アドレスが実行されます。
|
||||||
|
|
||||||
|
2. xxboot は、ブートデバイスを調べ、自分自身の全体 (8KB) を
|
||||||
|
0x3F0000- にロードし、実行します。
|
||||||
|
|
||||||
|
3. SHIFT キーが押されていれば 5. へ。
|
||||||
|
|
||||||
|
4. ルートディレクトリから "netbsd" という名前のファイルを探し、
|
||||||
|
0x100000- に読み込みます。"netbsd" が見つからなければ "netbsd.gz"
|
||||||
|
も探します。読み込むことができれば 6. へ。
|
||||||
|
|
||||||
|
5. ルートディレクトリから、"netbsd" あるいは "vmunix" で始まる
|
||||||
|
ファイルのリストを作成し、ユーザに選択させます。
|
||||||
|
ユーザが選んだファイルを 0x100000- に読み込みます。
|
||||||
|
|
||||||
|
6. 0x100000- に読み込んだファイルが gzip で圧縮されていれば、
|
||||||
|
そのファイルを一旦 ??????-0x3E7FFF に転送し、0x100000 が
|
||||||
|
先頭になるように展開しなおします。
|
||||||
|
|
||||||
|
7. 0x100000- に読み込んだファイルが NetBSD/m68k の NMAGIC の
|
||||||
|
実行ファイルでなければエラーとします。
|
||||||
|
|
||||||
|
8. 割り込みを禁止します。
|
||||||
|
IOCS が低位アドレスをワークとして使っているためです。
|
||||||
|
|
||||||
|
9. 読み込んだファイルの text, data, bss セグメントを
|
||||||
|
0x000000- に転送/作成します。
|
||||||
|
|
||||||
|
10. 読み込んだファイルにシンボルテーブルがあれば、
|
||||||
|
シンボルテーブル、ストリングテーブルを転送します。
|
||||||
|
|
||||||
|
11. レジスタ、引数を設定し、カーネルを実行します。
|
||||||
|
|
||||||
|
|
||||||
|
SCSI ディスクの起動パーティション決定アルゴリズム:
|
||||||
|
xxboot の起動時の d2 の値が非零であれば、それをキロバイト単位の
|
||||||
|
パーティション先頭位置として使う。
|
||||||
|
d2 の値が 0 であれば、起動時の a0 がパーティションテーブルを
|
||||||
|
指しているとして、(a2 + 8):l & 0x00FFFFFF をキロバイト単位の
|
||||||
|
パーティションの先頭位置とする。
|
||||||
|
|
||||||
|
以上の方法で、純正 IPL, SxSI の IPL, BOOT MENU (Ver. 2.22)では
|
||||||
|
パーティションの先頭が見つけられるようです。
|
||||||
|
|
||||||
|
Makefile に書かれているコンパイルオプションの -DSCSI_ADHOC_BOOTPART
|
||||||
|
を外すと、従来通り先頭パーティション固定になります。
|
||||||
|
|
||||||
|
|
||||||
|
デバッグしたところ:
|
||||||
|
シンボルテーブルが無いカーネルでもストリングテーブル
|
||||||
|
(シンボル名のテーブル) を転送しようとしていたところを直した。
|
||||||
|
(電源投入直後だけフロッピーブートで 暴はる(京ことば) という
|
||||||
|
症状に悩まされていた。)
|
||||||
|
|
||||||
|
|
||||||
|
TODO:
|
||||||
|
o 1440KB フォーマットのフロッピーからもブートしたいんですが、
|
||||||
|
そうすると IOCS が使えないので、自前で読まなければならない
|
||||||
|
ことになります。…で、8KB におさまりそうにないですねえ。
|
||||||
|
|
||||||
|
o SASI とか、SASI ポート付きマシンを持っている人におまかせ
|
||||||
|
しましょう :-)。あ、NetBSD のデバイスドライバもね。
|
||||||
|
|
||||||
|
---written by Yasha (ITOH Yasufumi)
|
|
@ -0,0 +1,40 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# convert "jbsr" for external symbol to "bsr"
|
||||||
|
# --written by Yasha
|
||||||
|
#
|
||||||
|
# usage: nm foo.o | sh all_bsr.sh foo.s >foo_new.s
|
||||||
|
#
|
||||||
|
# $NetBSD: all_bsr.sh,v 1.1 1998/09/01 20:02:33 itohy Exp $
|
||||||
|
|
||||||
|
src="$1"
|
||||||
|
case "$src" in
|
||||||
|
'')
|
||||||
|
echo 'Convert "jbsr" for external symbol to "bsr"' >&2
|
||||||
|
echo "usage: nm foo.o | $0 foo.s >foo_new.s" >&2
|
||||||
|
exit 1;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exts=
|
||||||
|
while read line
|
||||||
|
do
|
||||||
|
set - $line
|
||||||
|
case "$1" in
|
||||||
|
U) exts="$exts $2";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# m68k gcc sometimes emits nops. why?
|
||||||
|
sed '
|
||||||
|
/^[ ]*nop[ ]*$/d
|
||||||
|
/jbsr[ ]/{
|
||||||
|
h
|
||||||
|
s/.*jbsr[ ]*//
|
||||||
|
s/$/:'"$exts"' /
|
||||||
|
/^\([^:]*\):.* \1 /{
|
||||||
|
g
|
||||||
|
s/jbsr[ ]/bsr /
|
||||||
|
p
|
||||||
|
d
|
||||||
|
}
|
||||||
|
g
|
||||||
|
}' "$src"
|
|
@ -0,0 +1,773 @@
|
||||||
|
/* $NetBSD: bootufs.c,v 1.1 1998/09/01 20:02:34 itohy Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1993, 1994 Takumi Nakamura.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by Takumi Nakamura.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* file: bootufs.c
|
||||||
|
*
|
||||||
|
* author: chapuni(GBA02750@niftyserve.or.jp)
|
||||||
|
*
|
||||||
|
* 参考にしたもの: UNIX C PROGRAMMING (NUTSHELL)
|
||||||
|
* (俗に言うライオン本)
|
||||||
|
*
|
||||||
|
* これからの野望;
|
||||||
|
* ・意味もなくグラフィカルにしてみよう。
|
||||||
|
* ・ufs アクセスモジュールは、/sys/lib/libsa のものが
|
||||||
|
* 使えるハズなので、ぜひともそれを使うようにしよう。
|
||||||
|
* ・将来きっと FD DRIVER が出来上がるハズなので、それに
|
||||||
|
* いち早く対応しよう。
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/reboot.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <ufs/ufs/dinode.h>
|
||||||
|
#include <ufs/ffs/fs.h>
|
||||||
|
#include <ufs/ufs/dir.h>
|
||||||
|
#include <a.out.h>
|
||||||
|
#include <machine/bootinfo.h>
|
||||||
|
#ifdef SCSI_ADHOC_BOOTPART
|
||||||
|
#include <machine/disklabel.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "xxboot.h"
|
||||||
|
#include "../../x68k/iodevice.h"
|
||||||
|
#include "../common/execkern.h"
|
||||||
|
#ifdef GZIP
|
||||||
|
#include "gunzip/gzip.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* assertion of sector size == 512 */
|
||||||
|
#if !(defined(DEV_BSHIFT) && defined(DEV_BSIZE) && defined(dbtob) \
|
||||||
|
&& DEV_BSHIFT == 9 && DEV_BSIZE == 512 && dbtob(1) == 512)
|
||||||
|
#error You must make changes to pass sector size to RAW_READ or 64bit-ise it.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define alloca __builtin_alloca
|
||||||
|
#define memcpy __builtin_memcpy
|
||||||
|
|
||||||
|
static inline void memset __P((void *p, int v, size_t len));
|
||||||
|
#ifdef SCSI_ADHOC_BOOTPART
|
||||||
|
static int get_scsi_part __P((void));
|
||||||
|
#endif
|
||||||
|
static int get_scsi_host_adapter __P((void));
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
strcmp(a, b)
|
||||||
|
const char *a;
|
||||||
|
const char *b;
|
||||||
|
{
|
||||||
|
|
||||||
|
while (*a && *a == *b)
|
||||||
|
a++, b++;
|
||||||
|
return (*a != *b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
memcmp(a, b, n)
|
||||||
|
const char *a;
|
||||||
|
const char *b;
|
||||||
|
int n;
|
||||||
|
{
|
||||||
|
|
||||||
|
while (*a == *b && --n)
|
||||||
|
a++, b++;
|
||||||
|
return (*a != *b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
memset(p, v, len)
|
||||||
|
void *p;
|
||||||
|
int v;
|
||||||
|
size_t len;
|
||||||
|
{
|
||||||
|
|
||||||
|
while (len--)
|
||||||
|
*(char *)p++ = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for debug */
|
||||||
|
#ifdef DEBUG_WITH_STDIO
|
||||||
|
extern int printf __P((const char *, ...));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define IODEVbase ((volatile struct IODEVICE *)PHYS_IODEV)
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct fs superblk; /* ホンモノ */
|
||||||
|
unsigned char buf[SBSIZE]; /* サイズ合わせ */
|
||||||
|
} superblk_buf;
|
||||||
|
|
||||||
|
#define sblock superblk_buf.superblk
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* ディレクトリエントリをため込むバッファ
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define N_VMUNIX 24
|
||||||
|
|
||||||
|
struct {
|
||||||
|
ino_t ino; /* inode */
|
||||||
|
char name[60];
|
||||||
|
} vmunix_dirent[N_VMUNIX];
|
||||||
|
|
||||||
|
char *lowram;
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* ブロックの連続読みを試みる。
|
||||||
|
* length = 0 のときは、単にバッファをフラッシュする
|
||||||
|
* だけとなる。
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void *s_buf;
|
||||||
|
u_int32_t s_blkpos;
|
||||||
|
size_t s_len;
|
||||||
|
|
||||||
|
int
|
||||||
|
raw_read_queue(buf, blkpos, len)
|
||||||
|
void *buf;
|
||||||
|
u_int32_t blkpos;
|
||||||
|
size_t len;
|
||||||
|
{
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
|
/* さいしょは何もしない */
|
||||||
|
if (s_len == 0) {
|
||||||
|
s_buf = buf;
|
||||||
|
s_blkpos = blkpos;
|
||||||
|
s_len = len;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
/* 前のセクタと連続しているとき */
|
||||||
|
if (len > 0 && s_blkpos + btodb(s_len) == blkpos) {
|
||||||
|
s_len += len;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
/* これまで溜っていたものを読む */
|
||||||
|
r = RAW_READ(s_buf, s_blkpos, s_len);
|
||||||
|
s_buf = buf;
|
||||||
|
s_blkpos = blkpos;
|
||||||
|
s_len = len;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* スーパーブロックを読みこむ
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
get_superblk()
|
||||||
|
{
|
||||||
|
|
||||||
|
RAW_READ(&superblk_buf.buf, SBLOCK, SBSIZE);
|
||||||
|
#ifdef DEBUG_WITH_STDIO
|
||||||
|
printf("fs_magic=%08lx\n", sblock.fs_magic);
|
||||||
|
printf("fs_ipg=%08lx\n", sblock.fs_ipg);
|
||||||
|
printf("fs_ncg=%08lx\n", sblock.fs_ncg);
|
||||||
|
printf("fs_bsize=%08lx\n", sblock.fs_bsize);
|
||||||
|
printf("fs_fsize=%08lx\n", sblock.fs_fsize);
|
||||||
|
printf("INOPB=%08lx\n", INOPB(&sblock));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* inode を取ってくる
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
get_inode(ino, pino)
|
||||||
|
ino_t ino;
|
||||||
|
struct dinode *pino;
|
||||||
|
{
|
||||||
|
struct dinode *buf = alloca((size_t) sblock.fs_bsize);
|
||||||
|
|
||||||
|
RAW_READ(buf,
|
||||||
|
fsbtodb(&sblock, (u_int32_t) ino_to_fsba(&sblock, ino)),
|
||||||
|
(size_t) sblock.fs_bsize);
|
||||||
|
*pino = buf[ino_to_fsbo(&sblock, ino)];
|
||||||
|
#ifdef DEBUG_WITH_STDIO
|
||||||
|
printf("%d)permission=%06ho\n", ino, pino->di_mode);
|
||||||
|
printf("%d)nlink=%4d\n", ino, pino->di_nlink);
|
||||||
|
printf("%d)uid=%4d\n", ino, pino->di_uid);
|
||||||
|
printf("%d)gid=%4d\n", ino, pino->di_gid);
|
||||||
|
printf("%d)size=%ld\n", ino, pino->di_size);
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* inode の指しているブロックを取ってくる
|
||||||
|
*
|
||||||
|
* NutShell ライオン本よりのパクり
|
||||||
|
*
|
||||||
|
* buf にはデータを読んでくるアドレスをセットして
|
||||||
|
* おいてほしいなあ。できればブロックを切りあげて
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
read_indirect(blkno, level, buf, count)
|
||||||
|
ufs_daddr_t blkno;
|
||||||
|
int level;
|
||||||
|
void **buf;
|
||||||
|
int count;
|
||||||
|
{
|
||||||
|
ufs_daddr_t idblk[MAXBSIZE / sizeof(ufs_daddr_t)];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
RAW_READ(idblk,
|
||||||
|
fsbtodb(&sblock, (u_int32_t) blkno),
|
||||||
|
(size_t) sblock.fs_bsize);
|
||||||
|
|
||||||
|
for (i = 0; i < NINDIR(&sblock) && count > 0; i++) {
|
||||||
|
if (level) {
|
||||||
|
/* さらに間接ブロックを読ませる */
|
||||||
|
count = read_indirect(idblk[i], level - 1, buf, count);
|
||||||
|
} else {
|
||||||
|
/* データを読む */
|
||||||
|
#ifdef DEBUG_WITH_STDIO
|
||||||
|
printf("%d%4d\n", level, idblk[i]);
|
||||||
|
#endif
|
||||||
|
raw_read_queue(*buf,
|
||||||
|
fsbtodb(&sblock, (u_int32_t) idblk[i]),
|
||||||
|
(size_t) sblock.fs_bsize);
|
||||||
|
*buf += sblock.fs_bsize;
|
||||||
|
count -= sblock.fs_bsize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
read_blocks(dp, buf, count)
|
||||||
|
struct dinode *dp;
|
||||||
|
void *buf;
|
||||||
|
int count;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (dp->di_size < (unsigned) count)
|
||||||
|
count = dp->di_size;
|
||||||
|
|
||||||
|
s_len = 0;
|
||||||
|
|
||||||
|
/* direct block を読む */
|
||||||
|
for (i = 0; i < NDADDR && count > 0; i++) {
|
||||||
|
#ifdef DEBUG_WITH_STDIO
|
||||||
|
printf(" %4d\n", dp->di_db[i]);
|
||||||
|
#endif
|
||||||
|
raw_read_queue(buf,
|
||||||
|
fsbtodb(&sblock, (u_int32_t) dp->di_db[i]),
|
||||||
|
(size_t) sblock.fs_bsize);
|
||||||
|
buf += sblock.fs_bsize;
|
||||||
|
count -= sblock.fs_bsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* indirect block を読む */
|
||||||
|
for (i = 0; i < NIADDR && count > 0; i++) {
|
||||||
|
count = read_indirect(dp->di_ib[i], i, &buf, count);
|
||||||
|
}
|
||||||
|
/* バッファのフラッシュ */
|
||||||
|
raw_read_queue(NULL, (u_int32_t) 0, (size_t) 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* 指定されたファイルの inode を求める
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
ino_t
|
||||||
|
search_file(dirino, filename)
|
||||||
|
ino_t dirino; /* ディレクトリの位置 */
|
||||||
|
const char *filename; /* ファイル名 */
|
||||||
|
{
|
||||||
|
void *dirp;
|
||||||
|
struct dinode dinode;
|
||||||
|
struct direct *dir;
|
||||||
|
|
||||||
|
get_inode(dirino, &dinode);
|
||||||
|
dirp = alloca((size_t) (dinode.di_size + MAXBSIZE - 1) & ~((unsigned) MAXBSIZE - 1));
|
||||||
|
read_blocks(&dinode, dirp, (int) dinode.di_size);
|
||||||
|
|
||||||
|
while (dir = dirp, dir->d_ino != 0) {
|
||||||
|
if (!strcmp(dir->d_name, filename))
|
||||||
|
return dir->d_ino;
|
||||||
|
dirp += dir->d_reclen;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* 指定されたファイルを読み込んでくる
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
load_ino(buf, ino, filename)
|
||||||
|
void *buf;
|
||||||
|
ino_t ino;
|
||||||
|
const char *filename;
|
||||||
|
{
|
||||||
|
struct dinode dinode;
|
||||||
|
|
||||||
|
B_PRINT("loading ");
|
||||||
|
B_PRINT(filename);
|
||||||
|
B_PRINT("...");
|
||||||
|
get_inode(ino, &dinode);
|
||||||
|
read_blocks(&dinode, buf, (int) dinode.di_size);
|
||||||
|
return dinode.di_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
load_name(buf, dirino, filename)
|
||||||
|
void *buf; /* 読み込み先 */
|
||||||
|
ino_t dirino; /* 該当ディレクトリの inode 番号 */
|
||||||
|
const char *filename; /* ファイル名 */
|
||||||
|
{
|
||||||
|
ino_t ino;
|
||||||
|
|
||||||
|
ino = search_file(dirino, filename);
|
||||||
|
return ino ? load_ino(buf, ino, filename) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* for test
|
||||||
|
*
|
||||||
|
* 今のところ、vmunix はシンボリックリンクは許されて
|
||||||
|
* いないが、将来的にはどうにかなるかもしれん
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
print_hex(x, l)
|
||||||
|
unsigned x; /* 表示する数字 */
|
||||||
|
int l; /* 表示する桁数 */
|
||||||
|
{
|
||||||
|
|
||||||
|
if (l > 0) {
|
||||||
|
print_hex(x >> 4, l - 1);
|
||||||
|
x &= 0x0F;
|
||||||
|
if (x > 9)
|
||||||
|
x += 7;
|
||||||
|
B_PUTC('0' + x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* vmunix.* netbsd.* のリストをつくり出す
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
pickup_list(dirino)
|
||||||
|
ino_t dirino;
|
||||||
|
{
|
||||||
|
void *dirp;
|
||||||
|
struct dinode dinode;
|
||||||
|
struct direct *dir;
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
get_inode(dirino, &dinode);
|
||||||
|
dirp = alloca((size_t) (dinode.di_size + MAXBSIZE - 1) & ~((unsigned) MAXBSIZE - 1));
|
||||||
|
read_blocks(&dinode, dirp, (int) dinode.di_size);
|
||||||
|
|
||||||
|
while (dir = dirp, dir->d_ino != 0) {
|
||||||
|
if (!memcmp(dir->d_name, "vmunix", 6)
|
||||||
|
|| !memcmp(dir->d_name, "netbsd", 6)) {
|
||||||
|
vmunix_dirent[n].ino = dir->d_ino;
|
||||||
|
memcpy(vmunix_dirent[n].name, dir->d_name, 60);
|
||||||
|
if (++n >= N_VMUNIX)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dirp += dir->d_reclen;
|
||||||
|
}
|
||||||
|
while (n < N_VMUNIX)
|
||||||
|
vmunix_dirent[n++].ino = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* vmunix_dirent[] のレコードを表示する
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
print_list(n, active, boothowto)
|
||||||
|
int n;
|
||||||
|
int active;
|
||||||
|
unsigned boothowto;
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!vmunix_dirent[n].ino)
|
||||||
|
return;
|
||||||
|
B_LOCATE(0, 7 + n);
|
||||||
|
B_PRINT(active && (boothowto & RB_SINGLE)
|
||||||
|
? "SINGLE "
|
||||||
|
: " ");
|
||||||
|
print_hex(vmunix_dirent[n].ino, 8);
|
||||||
|
B_PRINT(" ");
|
||||||
|
if (active)
|
||||||
|
B_COLOR(0x0F);
|
||||||
|
B_PRINT(vmunix_dirent[n].name);
|
||||||
|
B_COLOR(0x03);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SCSI_ADHOC_BOOTPART
|
||||||
|
/*
|
||||||
|
* get partition # from partition start position
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define NPART 15
|
||||||
|
#define PARTTBL_TOP ((unsigned)4) /* pos of part inf in 512byte-blocks */
|
||||||
|
#define MAXPART 6
|
||||||
|
const unsigned char partition_conv[MAXPART + 1] = { 0, 1, 3, 4, 5, 6, 7 };
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_scsi_part()
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
u_int32_t magic; /* 0x5836384B ("X68K") */
|
||||||
|
u_int32_t parttotal;
|
||||||
|
u_int32_t diskblocks;
|
||||||
|
u_int32_t diskblocks2; /* backup? */
|
||||||
|
struct dos_partition parttbl[NPART];
|
||||||
|
unsigned char formatstr[256];
|
||||||
|
unsigned char rest[512];
|
||||||
|
} partbuf;
|
||||||
|
int i;
|
||||||
|
u_int32_t part_top;
|
||||||
|
|
||||||
|
#ifdef BOOT_DEBUG
|
||||||
|
B_PRINT("seclen: ");
|
||||||
|
print_hex(SCSI_BLKLEN, 8); /* 0: 256, 1: 512, 2: 1024 */
|
||||||
|
B_PRINT(", topsec: ");
|
||||||
|
print_hex(SCSI_PARTTOP, 8); /* partition top in sector */
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* read partition table
|
||||||
|
*/
|
||||||
|
RAW_READ0(&partbuf, PARTTBL_TOP, sizeof partbuf);
|
||||||
|
|
||||||
|
part_top = SCSI_PARTTOP >> (2 - SCSI_BLKLEN);
|
||||||
|
for (i = 0; i < MAXPART; i++)
|
||||||
|
if ((u_int32_t) partbuf.parttbl[i].dp_start == part_top)
|
||||||
|
goto found;
|
||||||
|
|
||||||
|
BOOT_ERROR("Can't boot from this partition");
|
||||||
|
/* NOTREACHED */
|
||||||
|
found:
|
||||||
|
#ifdef BOOT_DEBUG
|
||||||
|
B_PRINT("; sd");
|
||||||
|
B_PUTC((unsigned)ID + '0'); /* SCSI ID (not NetBSD unit #) */
|
||||||
|
B_PUTC((unsigned)partition_conv[i] + 'a');
|
||||||
|
#endif
|
||||||
|
return partition_conv[i];
|
||||||
|
}
|
||||||
|
#endif /* SCSI_ADHOC_BOOTPART */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check the type of SCSI interface
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
get_scsi_host_adapter()
|
||||||
|
{
|
||||||
|
char *bootrom;
|
||||||
|
int ha;
|
||||||
|
|
||||||
|
#ifdef BOOT_DEBUG
|
||||||
|
B_PRINT(" at ");
|
||||||
|
#endif
|
||||||
|
bootrom = (char *) (BOOT_INFO & 0x00ffffe0);
|
||||||
|
if (!memcmp(bootrom + 0x24, "SCSIIN", 6)) {
|
||||||
|
#ifdef BOOT_DEBUG
|
||||||
|
B_PRINT("spc0");
|
||||||
|
#endif
|
||||||
|
ha = (X68K_BOOT_SCSIIF_SPC << 4) | 0;
|
||||||
|
} else if (badbaddr(&IODEVbase->io_exspc.bdid)) {
|
||||||
|
#ifdef BOOT_DEBUG
|
||||||
|
B_PRINT("mha0");
|
||||||
|
#endif
|
||||||
|
ha = (X68K_BOOT_SCSIIF_MHA << 4) | 0;
|
||||||
|
} else {
|
||||||
|
#ifdef BOOT_DEBUG
|
||||||
|
B_PRINT("spc1");
|
||||||
|
#endif
|
||||||
|
ha = (X68K_BOOT_SCSIIF_SPC << 4) | 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ha;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* まじかよ?
|
||||||
|
*
|
||||||
|
* すべての IPL モジュールを読み込んできたあとは、
|
||||||
|
* ここに飛んでくる。「コアの転送」が終了するまでは、
|
||||||
|
* x68k IOCS は生きています。割り込みをマスクするまでは
|
||||||
|
* 大丈夫でしょう。
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
volatile void
|
||||||
|
bootufs()
|
||||||
|
{
|
||||||
|
unsigned long boothowto;
|
||||||
|
unsigned long esym;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* これは 0x100000 から存在しているもの */
|
||||||
|
extern struct exec header;
|
||||||
|
extern char image[];
|
||||||
|
/* これはコピー品 */
|
||||||
|
struct execkern_arg execinfo;
|
||||||
|
|
||||||
|
int bootdev;
|
||||||
|
unsigned short SFT;
|
||||||
|
#ifdef BOOT_DEBUG
|
||||||
|
/* for debug; 起動時のレジスタが入っている */
|
||||||
|
extern unsigned startregs[16];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* MPU チェック */
|
||||||
|
#if 0
|
||||||
|
int sys_stat;
|
||||||
|
|
||||||
|
sys_stat = SYS_STAT(0);
|
||||||
|
if ((sys_stat & 255) == 0 ||
|
||||||
|
(getcpu() != 4 && !(sys_stat & (1 << 14)))) {
|
||||||
|
BOOT_ERROR("MMU がないため、NetBSD を起動できません。");
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BOOT_DEBUG
|
||||||
|
/* for debug; レジスタの状態をプリントする */
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
print_hex(startregs[i], 8);
|
||||||
|
B_PRINT((i & 7) == 7 ? "\r\n" : " ");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get boot device
|
||||||
|
*/
|
||||||
|
if (BINF_ISFD(&BOOT_INFO)) {
|
||||||
|
/* floppy */
|
||||||
|
bootdev = X68K_MAKEBOOTDEV(X68K_MAJOR_FD, BOOT_INFO & 3,
|
||||||
|
(FDSECMINMAX.minsec.N == 3) ? 0 : 2);
|
||||||
|
} else {
|
||||||
|
/* SCSI */
|
||||||
|
int part, ha;
|
||||||
|
|
||||||
|
#ifdef SCSI_ADHOC_BOOTPART
|
||||||
|
part = get_scsi_part();
|
||||||
|
#else
|
||||||
|
part = 0; /* sd?a only */
|
||||||
|
#endif
|
||||||
|
ha = get_scsi_host_adapter();
|
||||||
|
bootdev = X68K_MAKESCSIBOOTDEV(X68K_MAJOR_SD, ha >> 4, ha & 15,
|
||||||
|
ID & 7, 0, part);
|
||||||
|
}
|
||||||
|
#ifdef BOOT_DEBUG
|
||||||
|
B_PRINT("\r\nbootdev: ");
|
||||||
|
print_hex((unsigned) bootdev, 8);
|
||||||
|
B_PRINT("\r\nhit key\r\n");
|
||||||
|
(void) B_KEYINP(); /* wait key input */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* boothowto をセット */
|
||||||
|
boothowto = RB_AUTOBOOT;
|
||||||
|
|
||||||
|
/* シフトキーが押されていたら */
|
||||||
|
SFT = B_SFTSNS();
|
||||||
|
if (SFT & 0x01)
|
||||||
|
boothowto |= RB_SINGLE;
|
||||||
|
|
||||||
|
/* vmunix を読み込んでくる */
|
||||||
|
get_superblk();
|
||||||
|
if (sblock.fs_magic != FS_MAGIC) {
|
||||||
|
BOOT_ERROR("bogus super block: "
|
||||||
|
"ルートファイルシステムが壊れています!");
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (boothowto == RB_AUTOBOOT) {
|
||||||
|
esym = load_name(&header, ROOTINO, "netbsd");
|
||||||
|
#ifdef GZIP
|
||||||
|
if (!esym)
|
||||||
|
esym = load_name(&header, ROOTINO, "netbsd.gz");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SFT = B_SFTSNS();
|
||||||
|
if (SFT & 0x0001)
|
||||||
|
boothowto |= RB_SINGLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (boothowto != RB_AUTOBOOT || !esym) {
|
||||||
|
int x = 0;
|
||||||
|
|
||||||
|
printtitle();
|
||||||
|
B_PRINT("....どのカーネルを読み込みますか?\r\n"
|
||||||
|
"SHIFT で RB_SINGLE がトグルします。\r\n");
|
||||||
|
|
||||||
|
/* ルートディレクトリを解析する */
|
||||||
|
pickup_list(ROOTINO);
|
||||||
|
|
||||||
|
/* 表示する */
|
||||||
|
for (i = 0; i < N_VMUNIX; i++) {
|
||||||
|
if (!memcmp(vmunix_dirent[i].name, "netbsd", 7)) {
|
||||||
|
print_list(x, 0, boothowto);
|
||||||
|
x = i;
|
||||||
|
}
|
||||||
|
print_list(i, i == x, boothowto);
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_shift_release:
|
||||||
|
while (B_SFTSNS() & 0x0001)
|
||||||
|
;
|
||||||
|
|
||||||
|
/* 入力待ちループする */
|
||||||
|
for (;;) {
|
||||||
|
switch ((B_KEYINP() >> 8) & 0xFF) {
|
||||||
|
case 0x3C: /* UP */
|
||||||
|
if (x > 0) {
|
||||||
|
print_list(--x, 1, boothowto);
|
||||||
|
print_list(x + 1, 0, boothowto);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x3E: /* DOWN */
|
||||||
|
if (x < N_VMUNIX - 1
|
||||||
|
&& vmunix_dirent[x + 1].ino) {
|
||||||
|
print_list(++x, 1, boothowto);
|
||||||
|
print_list(x - 1, 0, boothowto);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x70: /* SHIFT */
|
||||||
|
boothowto ^= RB_SINGLE;
|
||||||
|
print_list(x, 1, boothowto);
|
||||||
|
goto wait_shift_release;
|
||||||
|
case 0x1D: /* CR */
|
||||||
|
case 0x4E: /* ENTER */
|
||||||
|
goto exit_loop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exit_loop:
|
||||||
|
printtitle();
|
||||||
|
esym = load_ino(&header,
|
||||||
|
vmunix_dirent[x].ino, vmunix_dirent[x].name);
|
||||||
|
}
|
||||||
|
#ifdef GZIP
|
||||||
|
load_done:
|
||||||
|
#endif
|
||||||
|
B_PRINT("done.\r\n");
|
||||||
|
|
||||||
|
#ifdef GZIP
|
||||||
|
/*
|
||||||
|
* Check if the file is gzip'ed
|
||||||
|
*/
|
||||||
|
if (check_gzip_magic((char *) &header)) {
|
||||||
|
/*
|
||||||
|
* uncompress
|
||||||
|
*/
|
||||||
|
char *ctop; /* gzip'ed top */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* transfer loaded file to safe? area
|
||||||
|
*
|
||||||
|
* 0x3F0000 - SIZE_ALLOC_BUF - ?
|
||||||
|
* (stack bottom) (see inflate.c)
|
||||||
|
*/
|
||||||
|
ctop = (char *) 0x3e8000 - esym;
|
||||||
|
memcpy(ctop, &header, esym);
|
||||||
|
|
||||||
|
B_PRINT("decompressing...");
|
||||||
|
|
||||||
|
/* unzip() doesn't return on failure */
|
||||||
|
esym = unzip(ctop, (char *) &header);
|
||||||
|
|
||||||
|
goto load_done;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 「ひらがな」で、ddb を起こす */
|
||||||
|
SFT = B_SFTSNS();
|
||||||
|
if (SFT & 0x2000)
|
||||||
|
boothowto |= RB_KDB;
|
||||||
|
|
||||||
|
/* ヘッダをコピーする */
|
||||||
|
execinfo.image_top = image;
|
||||||
|
execinfo.load_addr = 0;
|
||||||
|
execinfo.text_size = header.a_text;
|
||||||
|
execinfo.data_size = header.a_data;
|
||||||
|
execinfo.bss_size = header.a_bss;
|
||||||
|
execinfo.symbol_size = header.a_syms;
|
||||||
|
execinfo.d5 = BOOT_INFO; /* unused for now */
|
||||||
|
execinfo.rootdev = bootdev;
|
||||||
|
execinfo.boothowto = boothowto;
|
||||||
|
execinfo.entry_addr = header.a_entry;
|
||||||
|
|
||||||
|
/* 本体をコアへ load する */
|
||||||
|
if (N_GETMID(header) == MID_M68K
|
||||||
|
&& N_GETMAGIC(header) == NMAGIC) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ここから先は割り込み禁止である。
|
||||||
|
* 気をつけてくれ。
|
||||||
|
*/
|
||||||
|
asm("oriw #0x0700,sr");
|
||||||
|
|
||||||
|
/* 実行 */
|
||||||
|
exec_kernel(&execinfo);
|
||||||
|
/* NOTREACHED */
|
||||||
|
} else {
|
||||||
|
BOOT_ERROR("improper file format: 実行不可能です。");
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* eof */
|
|
@ -0,0 +1,148 @@
|
||||||
|
|
|
||||||
|
| check FD format
|
||||||
|
|
|
||||||
|
| Written by Yasha (ITOH Yasufumi)
|
||||||
|
| This code is in the public domain
|
||||||
|
|
|
||||||
|
| $NetBSD: chkfmt.s,v 1.1 1998/09/01 20:02:34 itohy Exp $
|
||||||
|
|
||||||
|
/* FDC address */
|
||||||
|
#define FDC_STATUS 0xE94001 /* status register */
|
||||||
|
#define FDC_DATA 0xE94003 /* data register */
|
||||||
|
|
||||||
|
#define INT_STAT 0xE9C001 /* interrupt control */
|
||||||
|
#define INT_FDC_BIT 2
|
||||||
|
|
||||||
|
/* Status Register */
|
||||||
|
#define NE7ST_CB_BIT 4 /* FDC busy */
|
||||||
|
#define NE7ST_DIO_BIT 6 /* data input/output */
|
||||||
|
#define NE7ST_RQM_BIT 7 /* request for master */
|
||||||
|
|
||||||
|
/* FDC command */
|
||||||
|
#define NE7CMD_READID 0x4A /* READ ID */
|
||||||
|
|
||||||
|
|
|
||||||
|
| Read ID of all sectors in current track.
|
||||||
|
| This routine expects that motor on, drive selection
|
||||||
|
| and seek is already done.
|
||||||
|
|
|
||||||
|
| input: d0.b: 0 0 0 0 0 HD US1 US0 (binary)
|
||||||
|
| output: d0.l: min # sector (N C H R (2hex))
|
||||||
|
| d1.l: max # sector (N C H R (2hex))
|
||||||
|
| destroy:
|
||||||
|
| d0, d1
|
||||||
|
|
|
||||||
|
.text
|
||||||
|
.even
|
||||||
|
.globl check_fd_format
|
||||||
|
check_fd_format:
|
||||||
|
moveml d2-d7/a1-a3,sp@-
|
||||||
|
|
||||||
|
moveb d0,d6 | head, drive
|
||||||
|
|
||||||
|
lea FDC_STATUS:l,a1
|
||||||
|
lea a1@(FDC_DATA-FDC_STATUS),a2 | FDC_DATA
|
||||||
|
lea a2@(INT_STAT-FDC_DATA),a3 | INT_STAT
|
||||||
|
|
||||||
|
movew sr,sp@-
|
||||||
|
oriw #0x0700,sr | keep out interrupts
|
||||||
|
bclr #INT_FDC_BIT,a3@ | disable FDC interrupt
|
||||||
|
|
||||||
|
jbsr read_id_sub
|
||||||
|
jne exit_check_format
|
||||||
|
movel d3,d2 | first sector
|
||||||
|
movel d3,d0 | sector min
|
||||||
|
movel d3,d1 | sector max
|
||||||
|
|
||||||
|
loop_read_id:
|
||||||
|
jbsr read_id_sub
|
||||||
|
jne exit_check_format
|
||||||
|
cmpl d0,d3
|
||||||
|
jcc sector_not_min
|
||||||
|
movel d3,d0
|
||||||
|
sector_not_min:
|
||||||
|
cmpl d3,d1
|
||||||
|
jcc sector_not_max
|
||||||
|
movel d3,d1
|
||||||
|
sector_not_max:
|
||||||
|
cmpl d2,d3
|
||||||
|
jne loop_read_id
|
||||||
|
|
||||||
|
exit_check_format:
|
||||||
|
bset #INT_FDC_BIT,a3@ | enable FDC interrupt
|
||||||
|
movew a7@+,sr
|
||||||
|
|
||||||
|
tstl d7
|
||||||
|
moveml a7@+,d2-d7/a1-a3
|
||||||
|
jne _err_read_id
|
||||||
|
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
|
||||||
|
| input: d6.b: 0 0 0 0 0 HD US1 US0 (binary)
|
||||||
|
| a1: FDC status addr
|
||||||
|
| a2: FDC data addr
|
||||||
|
| interrupt must be disabled
|
||||||
|
| output: d3.l: sector information: N C H R (2hex)
|
||||||
|
| d7.l: status (nonzero if error)
|
||||||
|
| Z flag: true if no error, false if error
|
||||||
|
| destroy:
|
||||||
|
| d3-d5, d7
|
||||||
|
|
|
||||||
|
read_id_sub:
|
||||||
|
| wait for FDC ready
|
||||||
|
fdc_wait_ready:
|
||||||
|
btst #NE7ST_CB_BIT,a1@
|
||||||
|
jne fdc_wait_ready
|
||||||
|
|
||||||
|
| send READ ID command
|
||||||
|
moveq #NE7CMD_READID,d4
|
||||||
|
jbsr fdc_send_command
|
||||||
|
moveb d6,d4 | X X X X X HD US1 US0 (binary)
|
||||||
|
jbsr fdc_send_command
|
||||||
|
|
||||||
|
| receive data
|
||||||
|
moveq #2,d4
|
||||||
|
jbsr fdc_read_bytes
|
||||||
|
movel d3,d7 | d7: FDC status: X ST0 ST1 ST2 (2hex)
|
||||||
|
moveq #3,d4
|
||||||
|
jbsr fdc_read_bytes | d3: sector info: C H R N (2hex)
|
||||||
|
rorl #8,d3 | d3: sector info: N C H R (2hex)
|
||||||
|
|
||||||
|
andil #0x00f8ffff,d7 | check status (must be zero)
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
|
||||||
|
| send one byte of command
|
||||||
|
|
|
||||||
|
fdc_send_command:
|
||||||
|
jbsr fdc_wait_rqm
|
||||||
|
jne fdc_send_command
|
||||||
|
moveb d4,a2@
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
|
||||||
|
| receive d4:w+1 bytes from FDC
|
||||||
|
|
|
||||||
|
fdc_read_bytes:
|
||||||
|
asll #8,d3
|
||||||
|
fdc_read_loop:
|
||||||
|
jbsr fdc_wait_rqm
|
||||||
|
jeq fdc_read_loop
|
||||||
|
moveb a2@,d3
|
||||||
|
dbra d4,fdc_read_bytes
|
||||||
|
rts
|
||||||
|
|
||||||
|
fdc_wait_rqm:
|
||||||
|
moveb a1@,d5
|
||||||
|
| btst #NE7ST_RQM_BIT,d5
|
||||||
|
| jeq fdc_wait_rqm
|
||||||
|
jpl fdc_wait_rqm | NE7ST_RQM_BIT = 7: sign bit
|
||||||
|
btst #NE7ST_DIO_BIT,d5
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
|
||||||
|
| error
|
||||||
|
|
|
||||||
|
_err_read_id:
|
||||||
|
BOOT_ERROR("READ ID failed")
|
|
@ -0,0 +1,132 @@
|
||||||
|
/*
|
||||||
|
* Convert an EUC-Japanese code C source file to Shift-JIS
|
||||||
|
* and to \xxx escape sequences (X680x0 IOCS uses Shift-JIS code)
|
||||||
|
*
|
||||||
|
* This is compiled and executed on the host, and should be portable
|
||||||
|
*
|
||||||
|
* Written by Yasha (ITOH Yasufumi)
|
||||||
|
* This code is in the public domain
|
||||||
|
*
|
||||||
|
* $NetBSD: ej2sjesc.c,v 1.1 1998/09/01 20:02:34 itohy Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifndef __P
|
||||||
|
# ifdef __STDC__
|
||||||
|
# define __P(x) x
|
||||||
|
# else
|
||||||
|
# define __P(x) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void euc_to_sjis __P((int *ph, int *pl));
|
||||||
|
int xfclose __P((FILE *fp));
|
||||||
|
int main __P((int argc, char *argv[]));
|
||||||
|
|
||||||
|
#define ISEUC1(c) ((unsigned char)(c) & 0x80)
|
||||||
|
#define ISEUC2(c) ((unsigned char)(c) & 0x80)
|
||||||
|
|
||||||
|
#define EUC2JIS(c) ((unsigned char)(c) & 0x7f)
|
||||||
|
|
||||||
|
void
|
||||||
|
euc_to_sjis(ph, pl)
|
||||||
|
int *ph, *pl;
|
||||||
|
{
|
||||||
|
int hi = EUC2JIS(*ph);
|
||||||
|
int lo = EUC2JIS(*pl);
|
||||||
|
|
||||||
|
lo += (hi % 2) ? 0x1f : 0x7d;
|
||||||
|
if (lo >= 0x7f)
|
||||||
|
lo++;
|
||||||
|
hi = (hi - 0x21)/2 + 0x81;
|
||||||
|
if (hi > 0x9f)
|
||||||
|
hi += 0x40;
|
||||||
|
*ph = hi;
|
||||||
|
*pl = lo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* I hear that closing stdin/stdout/stderr crashes exit(3) on some old BSDs
|
||||||
|
* (?? is it true?)
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xfclose(fp)
|
||||||
|
FILE *fp;
|
||||||
|
{
|
||||||
|
|
||||||
|
if (fp == stdin)
|
||||||
|
return 0; /* do nothing */
|
||||||
|
|
||||||
|
if (fp == stdout || fp == stderr)
|
||||||
|
return fflush(fp); /* complete write but not close */
|
||||||
|
|
||||||
|
return fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(argc, argv)
|
||||||
|
int argc;
|
||||||
|
char *argv[];
|
||||||
|
{
|
||||||
|
FILE *in, *out;
|
||||||
|
int c;
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
|
if (argc != 3) {
|
||||||
|
fprintf(stderr, "usage: %s infile outfile\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(argv[1], "-"))
|
||||||
|
in = stdin;
|
||||||
|
else if (!(in = fopen(argv[1], "r"))) {
|
||||||
|
perror(argv[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(argv[2], "-"))
|
||||||
|
out = stdout;
|
||||||
|
else if (!(out = fopen(argv[2], "w"))) {
|
||||||
|
perror(argv[2]);
|
||||||
|
xfclose(in);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* notify the original filname to the C compiler */
|
||||||
|
fprintf(out, "#line 1 \"%s\"\n", argv[1]);
|
||||||
|
|
||||||
|
while ((c = getc(in)) != EOF) {
|
||||||
|
if (ISEUC1(c)) {
|
||||||
|
int hi = c, lo = getc(in);
|
||||||
|
|
||||||
|
if (!ISEUC2(lo)) {
|
||||||
|
fprintf(stderr, "%s: not in EUC code\n",
|
||||||
|
argv[1]);
|
||||||
|
error = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
euc_to_sjis(&hi, &lo);
|
||||||
|
#if 0 /* for debug */
|
||||||
|
putc(hi, out);
|
||||||
|
putc(lo, out);
|
||||||
|
#else
|
||||||
|
fprintf(out, "\\%03o\\%03o", hi, lo);
|
||||||
|
#endif
|
||||||
|
} else
|
||||||
|
putc(c, out);
|
||||||
|
}
|
||||||
|
if (ferror(in) || xfclose(in)) {
|
||||||
|
perror(argv[1]);
|
||||||
|
error = 1;
|
||||||
|
}
|
||||||
|
if (ferror(out) || xfclose(out)) {
|
||||||
|
perror(argv[2]);
|
||||||
|
error = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
remove(argv[2]);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
# $NetBSD: MANIFEST,v 1.1 1998/09/01 20:03:45 itohy Exp $
|
||||||
|
#
|
||||||
|
Makefile.test test Makefile for Berkeley make
|
||||||
|
main.c test main() routine
|
||||||
|
gzip.h header file
|
||||||
|
inflate.c decompression routine (originally written by Mark Adler)
|
||||||
|
unzip.c interface routine
|
|
@ -0,0 +1,11 @@
|
||||||
|
# $NetBSD: Makefile.test,v 1.1 1998/09/01 20:03:46 itohy Exp $
|
||||||
|
#
|
||||||
|
# Makefile for test
|
||||||
|
|
||||||
|
PROG= zcat
|
||||||
|
SRCS= main.c unzip.c inflate.c
|
||||||
|
NOMAN= noman
|
||||||
|
CFLAGS= -Wall -O -fomit-frame-pointer -DBOOT -DTEST
|
||||||
|
LDFLAGS= -static -N
|
||||||
|
|
||||||
|
.include <bsd.prog.mk>
|
|
@ -0,0 +1,81 @@
|
||||||
|
/* $NetBSD: gzip.h,v 1.1 1998/09/01 20:03:46 itohy Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interface for extracting gzip'ed data
|
||||||
|
*
|
||||||
|
* Written by Yasha (ITOH Yasufumi)
|
||||||
|
* This code is in the public domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GZIP_H
|
||||||
|
#define GZIP_H
|
||||||
|
|
||||||
|
#ifdef __STDC__
|
||||||
|
# define OF(p) p
|
||||||
|
#else
|
||||||
|
# define const
|
||||||
|
# define OF(p) ()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef unsigned int uint32;
|
||||||
|
typedef unsigned short uint16;
|
||||||
|
typedef unsigned char uch;
|
||||||
|
typedef unsigned short ush;
|
||||||
|
typedef unsigned long ulg;
|
||||||
|
typedef void *voidp;
|
||||||
|
|
||||||
|
/* magic number for gzip */
|
||||||
|
#define GZIP_MAGIC1 037
|
||||||
|
#define GZIP_MAGIC2 0213
|
||||||
|
#define GZIP_MAGIC2_OLD 0236 /* gzip 0.5 */
|
||||||
|
|
||||||
|
/* check gzip magic number */
|
||||||
|
#define check_gzip_magic(top) \
|
||||||
|
({ register const uch *t = top; \
|
||||||
|
*t++ == GZIP_MAGIC1 && (*t == GZIP_MAGIC2 || *t == GZIP_MAGIC2_OLD);})
|
||||||
|
|
||||||
|
/* gzip compression method */
|
||||||
|
#define GZIP_METHOD_DEFLATED 8
|
||||||
|
|
||||||
|
/* gzip flags */
|
||||||
|
#define GZIP_FLAG_ASCII 0001
|
||||||
|
#define GZIP_FLAG_MULTIPART 0002
|
||||||
|
#define GZIP_FLAG_EXTRA 0004
|
||||||
|
#define GZIP_FLAG_FILE_NAME 0010
|
||||||
|
#define GZIP_FLAG_COMMENT 0020
|
||||||
|
#define GZIP_FLAG_ENCRYPTED 0040
|
||||||
|
#define GZIP_FLAGS_RESERVED 0300
|
||||||
|
|
||||||
|
/* the window size */
|
||||||
|
#define WSIZE 32768
|
||||||
|
|
||||||
|
extern const uch *csrc; /* compressed data */
|
||||||
|
extern uch *udst; /* uncompressed data */
|
||||||
|
extern long udst_cnt;
|
||||||
|
extern unsigned outcnt;
|
||||||
|
extern uch window[WSIZE];
|
||||||
|
|
||||||
|
long unzip OF((const uch *src, uch *dst));
|
||||||
|
#ifdef TEST
|
||||||
|
int inflate OF((void));
|
||||||
|
#endif
|
||||||
|
void flush_window OF((void));
|
||||||
|
|
||||||
|
#if !defined(__GNUC__) || __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
|
||||||
|
#define __attribute__(x)
|
||||||
|
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||||
|
__volatile
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
void BOOT_ERROR OF((const char *)) __attribute__((noreturn));
|
||||||
|
|
||||||
|
#define error(m) BOOT_ERROR(m)
|
||||||
|
|
||||||
|
#define Tracecv(a, b)
|
||||||
|
#define Tracevv(a)
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
# define NULL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* GZIP_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,42 @@
|
||||||
|
/* $NetBSD: main.c,v 1.1 1998/09/01 20:03:47 itohy Exp $ */
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "gzip.h"
|
||||||
|
|
||||||
|
#ifdef BOOT
|
||||||
|
static char src[1024*1024];
|
||||||
|
static char dst[2048*1024];
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
volatile
|
||||||
|
#endif
|
||||||
|
void
|
||||||
|
BOOT_ERROR(m)
|
||||||
|
const char *m;
|
||||||
|
{
|
||||||
|
write(2, m, strlen(m));
|
||||||
|
write(2, "\n", 1);
|
||||||
|
_exit(1);
|
||||||
|
for(;;); /* make gcc happy */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* for debug */
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
#ifdef BOOT
|
||||||
|
char *p;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
for (p = src; (len = read(0, p, src + sizeof src - p)) > 0; p += len)
|
||||||
|
;
|
||||||
|
unzip(src, dst);
|
||||||
|
#else
|
||||||
|
unzip(0,0);
|
||||||
|
#endif
|
||||||
|
#ifdef BOOT
|
||||||
|
write (1, dst, udst_cnt);
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,161 @@
|
||||||
|
/* $NetBSD: unzip.c,v 1.1 1998/09/01 20:03:47 itohy Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extract gzip'ed data on the memory
|
||||||
|
*
|
||||||
|
* Written by Yasha (ITOH Yasufumi)
|
||||||
|
* This code is in the public domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "gzip.h"
|
||||||
|
|
||||||
|
const uch *csrc; /* compressed data */
|
||||||
|
uch *udst; /* uncompressed data */
|
||||||
|
long udst_cnt; /* output byte counter */
|
||||||
|
|
||||||
|
unsigned outcnt; /* data length to be flushed */
|
||||||
|
|
||||||
|
void
|
||||||
|
flush_window()
|
||||||
|
{
|
||||||
|
#if defined(__GNUC__) && defined(__m68k__)
|
||||||
|
asm("lea _outcnt,a0\n\
|
||||||
|
movel a0@,d0\n\
|
||||||
|
addl d0,_udst_cnt\n\
|
||||||
|
movel d0,sp@-\n\
|
||||||
|
pea _window\n\
|
||||||
|
lea _udst,a1\n\
|
||||||
|
movel a1@,sp@-\n\
|
||||||
|
addl d0,a1@\n\
|
||||||
|
clrl a0@\n\
|
||||||
|
jbsr _memcpy\n\
|
||||||
|
lea sp@(12),sp");
|
||||||
|
#else
|
||||||
|
register unsigned cnt = outcnt;
|
||||||
|
|
||||||
|
udst_cnt += cnt;
|
||||||
|
memcpy(udst, window, cnt);
|
||||||
|
udst += cnt;
|
||||||
|
outcnt = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef TEST
|
||||||
|
#include "inflate.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* decompress gzip'ed data
|
||||||
|
*
|
||||||
|
* src: compressed data area for input
|
||||||
|
* dst: decompressed data area for output
|
||||||
|
*/
|
||||||
|
long
|
||||||
|
unzip(src, dst)
|
||||||
|
const uch *src;
|
||||||
|
uch *dst;
|
||||||
|
{
|
||||||
|
uch flags;
|
||||||
|
|
||||||
|
udst_cnt = 0;
|
||||||
|
udst = dst;
|
||||||
|
|
||||||
|
/* skip magic (must be checked before) */
|
||||||
|
src += 2;
|
||||||
|
|
||||||
|
/* check compression method */
|
||||||
|
if (*src++ != GZIP_METHOD_DEFLATED) {
|
||||||
|
error("unknown compression method");
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check flags */
|
||||||
|
flags = *src++;
|
||||||
|
if (flags &
|
||||||
|
(GZIP_FLAG_MULTIPART | GZIP_FLAG_ENCRYPTED | GZIP_FLAGS_RESERVED)) {
|
||||||
|
error("unsupported compression flag");
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* skip mod time (4bytes), extra flags, operating system */
|
||||||
|
src += (4 + 1 + 1);
|
||||||
|
|
||||||
|
/* part number (2bytes) may exist here but not supported */
|
||||||
|
|
||||||
|
/* skip extra field if present */
|
||||||
|
if (flags & GZIP_FLAG_EXTRA) {
|
||||||
|
/* its length (LSB first) */
|
||||||
|
unsigned extralen;
|
||||||
|
#if defined(__GNUC__) && defined(__m68k__)
|
||||||
|
/*
|
||||||
|
* This doesn't work on 68000/010 since it does an unaligned access.
|
||||||
|
*/
|
||||||
|
asm("movew %1@+,%0\n\
|
||||||
|
rolw #8,%0" : "=d" (extralen), "=a" (src) : "0" (0), "1" (src));
|
||||||
|
#else
|
||||||
|
extralen = *src++;
|
||||||
|
extralen += (*src++ << 8);
|
||||||
|
#endif
|
||||||
|
src += extralen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* skip original file name if present */
|
||||||
|
if (flags & GZIP_FLAG_FILE_NAME)
|
||||||
|
while (*src++)
|
||||||
|
;
|
||||||
|
|
||||||
|
/* skip file comment if present */
|
||||||
|
if (flags & GZIP_FLAG_COMMENT)
|
||||||
|
while (*src++)
|
||||||
|
;
|
||||||
|
|
||||||
|
/* encryption header (12bytes) may exist here but not supported */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Here must exist compressed data...
|
||||||
|
*/
|
||||||
|
csrc = src;
|
||||||
|
|
||||||
|
switch (inflate()) {
|
||||||
|
case 0:
|
||||||
|
/* no error */
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
error("out of memory");
|
||||||
|
/* NOTREACHED */
|
||||||
|
default:
|
||||||
|
invdata:
|
||||||
|
error("invalid compressed data");
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
src = csrc;
|
||||||
|
|
||||||
|
/* 32bit CRC is not checked --- skip */
|
||||||
|
src += 4;
|
||||||
|
|
||||||
|
/* check uncompressed input size (LSB first) */
|
||||||
|
{
|
||||||
|
uint32 len;
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && defined(__m68k__)
|
||||||
|
/*
|
||||||
|
* I think this is the smallest for MC68020 and later
|
||||||
|
* This doesn't work on 68000/010 since it does an unaligned access.
|
||||||
|
*/
|
||||||
|
asm("rolw #8,%0\n\
|
||||||
|
swap %0\n\
|
||||||
|
rolw #8,%0" : "=d" (len) : "0" (*(uint32 *)src));
|
||||||
|
#else
|
||||||
|
len = *src++;
|
||||||
|
len += *src++ << 8;
|
||||||
|
len += *src++ << 16;
|
||||||
|
len += *src << 24;
|
||||||
|
#endif
|
||||||
|
if (len != (uint32) udst_cnt)
|
||||||
|
goto invdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
return udst_cnt;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
# $NetBSD: MANIFEST,v 1.1 1998/09/01 20:04:04 itohy Exp $
|
||||||
|
|
||||||
|
netbsd.xpm Default boot image. The BSD Daemon is used by permission.
|
||||||
|
xpm2bootimg.c Convert *.xpm to boot title image format.
|
||||||
|
setbootimg.c Change boot title image of specified boot block (or file).
|
|
@ -0,0 +1,80 @@
|
||||||
|
/* XPM */
|
||||||
|
static char *netbsd[] = {
|
||||||
|
/* width height num_colors chars_per_pixel */
|
||||||
|
"56 52 5 1 XPMEXT",
|
||||||
|
/* colors */
|
||||||
|
" c None",
|
||||||
|
"# c #000000",
|
||||||
|
"* c #555555",
|
||||||
|
"+ c #aaaaaa",
|
||||||
|
". c #ffffff",
|
||||||
|
/* pixels */
|
||||||
|
" +. + ",
|
||||||
|
" *.. . ",
|
||||||
|
" *..+ ++ ",
|
||||||
|
" +..* +.* ",
|
||||||
|
" *..+** *++* ",
|
||||||
|
" +.+**.+** ++++ *.+** ",
|
||||||
|
" ..+**##*.*+++++++ *.+** ",
|
||||||
|
" ..**++##.+++##**** *...+** ",
|
||||||
|
" *..+##.#..##..##*****...++** ",
|
||||||
|
" *+#..#..#..##.##++.....++** ",
|
||||||
|
" +#...#.##....#.#*+.....++*# ",
|
||||||
|
" #....#.#.....#....+...++**# ",
|
||||||
|
" +#....#.#......#.+++++++**# ",
|
||||||
|
" #..##.#.###....#..++*****# ",
|
||||||
|
" #.####.#####...#...+++**# ",
|
||||||
|
" +#.#.##.##.##...#...++++* ",
|
||||||
|
" .#.#+##.##.##...#....+++** ",
|
||||||
|
" . +.*###########..#.....+++** ",
|
||||||
|
" .+ ...*###...###..#*.....+++*# ",
|
||||||
|
" + +.....#.....####*+++...+++*# ",
|
||||||
|
" .. ++ +.....#....#*.........+++** ",
|
||||||
|
" . + +.##..####**.........+++*# ",
|
||||||
|
" + . +..##........#####.+++** ",
|
||||||
|
".+ +.. *.++#.....###++..+++**# ",
|
||||||
|
" . ++. *+++######++...+++**# ",
|
||||||
|
" + .+*+. *++++++++...+*****# ",
|
||||||
|
" +++ +*++.*# *+++*...+++++**# ",
|
||||||
|
" **...* *.........++** ",
|
||||||
|
" +..*.*#* +...........++** ",
|
||||||
|
" ...*##+** ++............+*** ",
|
||||||
|
" *.+*#*+++*#..####....+..++*** ",
|
||||||
|
" ####++*++##+..+########++** ",
|
||||||
|
" .... ....#**+**.....#.......##** ..... ........+ ",
|
||||||
|
" +.. #.#**++***.....#..###...## .. ... .. ... ",
|
||||||
|
" .... ..#*********####..#.+#..##.. . .. .. ",
|
||||||
|
" .... ..#*########.###..#++#..# .. . .. ...",
|
||||||
|
" +..... . ######..##...#+#...# ... ... ...",
|
||||||
|
" +. ... .. ...##.....#..###...## .... .. ...",
|
||||||
|
" .. .. .. .. #..##..###......##### .... .. ...",
|
||||||
|
" .. ... .. .. #..##..###..###..#***# .... .. .. ",
|
||||||
|
" +.. .... .. ..##...##...#+*#..##++# ... ... ... ",
|
||||||
|
" .. .... .... ##..###...#++#..#.#+++#.. .. ..+ ",
|
||||||
|
" .. ... .. .#..###..####...#.###.#..#.. .... ",
|
||||||
|
" .. .. ... . #..#.#..###...# ...##..##..# .... ",
|
||||||
|
".... . .... ##..#........## ......##.......##** ",
|
||||||
|
" ######+++###########*** ##+*#######+.++* ",
|
||||||
|
" ......+..######+++++++++*# #..#***.....+*",
|
||||||
|
" +.....+++#.....+...++++**** *+...# ####.++",
|
||||||
|
" +++++++#+....++++++++++*** *++....+++++++.+++",
|
||||||
|
" ****#*+#+++++++***++***# +.+....+***+++++++*",
|
||||||
|
" ##********# #**#*++###****#*#",
|
||||||
|
" ##*+# ### ",
|
||||||
|
"XPMEXT copyright",
|
||||||
|
"BSD Daemon Copyright 1988 by Marshall Kirk McKusick."
|
||||||
|
"XPMEXT copyright_long",
|
||||||
|
"BSD Daemon image, used for NetBSD boot by permission.",
|
||||||
|
"",
|
||||||
|
"BSD Daemon Copyright 1988 by Marshall Kirk McKusick.",
|
||||||
|
"All Rights Reserved.",
|
||||||
|
"",
|
||||||
|
"Permission to use the daemon may be obtained from:",
|
||||||
|
" Marshall Kirk McKusick",
|
||||||
|
" 1614 Oxford St",
|
||||||
|
" Berkeley, CA 94709-1608",
|
||||||
|
" USA",
|
||||||
|
"or via email at mckusick@mckusick.com",
|
||||||
|
"XPMEXT rcsid $NetBSD: netbsd.xpm,v 1.1 1998/09/01 20:04:04 itohy Exp $",
|
||||||
|
"XPMENDEXT"
|
||||||
|
};
|
|
@ -0,0 +1,241 @@
|
||||||
|
/* $NetBSD: setbootimg.c,v 1.1 1998/09/01 20:04:05 itohy Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set boot title image (converted by xpm2bootimg)
|
||||||
|
* to boot file or installed boot block
|
||||||
|
*
|
||||||
|
* use with care, not to destroy the existent boot or the disklabel
|
||||||
|
*
|
||||||
|
* written by Yasha (ITOH Yasufumi), public domain
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#ifdef __NetBSD__
|
||||||
|
#include <err.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* define here for cross env
|
||||||
|
*/
|
||||||
|
#define SIZE_BOOTBLK 8192 /* <ufs/ffs/fs.h> BBSIZE */
|
||||||
|
#define MAGIC_DISKLABEL 0x82564557 /* <sys/disklabel.h> DISKMAGIC */
|
||||||
|
#define X68K_LABELOFF 64 /* <x68k/disklabel.h> LABELOFFSET */
|
||||||
|
|
||||||
|
#ifdef __STDC__
|
||||||
|
# define PROTO(x) x
|
||||||
|
#else
|
||||||
|
# define PROTO(x) ()
|
||||||
|
# ifndef const
|
||||||
|
# define const
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main PROTO((int argc, char *argv[]));
|
||||||
|
static unsigned get_uint16 PROTO((void *));
|
||||||
|
static unsigned get_uint32 PROTO((void *));
|
||||||
|
|
||||||
|
#ifndef __NetBSD__
|
||||||
|
/* for cross env */
|
||||||
|
|
||||||
|
#ifdef __STDC__
|
||||||
|
# include <stdarg.h>
|
||||||
|
# define VA_START(a, v) va_start(a, v)
|
||||||
|
# include <errno.h>
|
||||||
|
#else
|
||||||
|
# include <varargs.h>
|
||||||
|
# define VA_START(a, v) va_start(a)
|
||||||
|
extern int errno;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void err PROTO((int eval, const char *fmt, ...));
|
||||||
|
static void errx PROTO((int eval, const char *fmt, ...));
|
||||||
|
|
||||||
|
static void
|
||||||
|
#ifdef __STDC__
|
||||||
|
err(int eval, const char *fmt, ...)
|
||||||
|
#else
|
||||||
|
err(eval, fmt, va_alist)
|
||||||
|
int eval;
|
||||||
|
const char *fmt;
|
||||||
|
va_dcl
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
int e = errno;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
fprintf(stderr, "setbootimg: ");
|
||||||
|
if (fmt) {
|
||||||
|
VA_START(ap, fmt);
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
fprintf(stderr, ": ");
|
||||||
|
}
|
||||||
|
errno = e;
|
||||||
|
perror((char *) 0);
|
||||||
|
exit(eval);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
#ifdef __STDC__
|
||||||
|
errx(int eval, const char *fmt, ...)
|
||||||
|
#else
|
||||||
|
errx(eval, fmt, va_alist)
|
||||||
|
int eval;
|
||||||
|
const char *fmt;
|
||||||
|
va_dcl
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
fprintf(stderr, "setbootimg: ");
|
||||||
|
if (fmt) {
|
||||||
|
VA_START(ap, fmt);
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
exit(eval);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static unsigned
|
||||||
|
get_uint16(p)
|
||||||
|
void *p;
|
||||||
|
{
|
||||||
|
unsigned char *q = p;
|
||||||
|
|
||||||
|
return q[0] << 8 | q[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned
|
||||||
|
get_uint32(p)
|
||||||
|
void *p;
|
||||||
|
{
|
||||||
|
unsigned char *q = p;
|
||||||
|
|
||||||
|
return q[0] << 24 | q[1] << 16 | q[2] << 8 | q[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char boottop[] = {
|
||||||
|
0x60, 0x24, 0x53, 0x48, 0x41, 0x52, 0x50, 0x2F,
|
||||||
|
0x58, 0x36, 0x38, 0x30, 0x78, 0x30, 0x81, 0x99,
|
||||||
|
0x94, 0xE6, 0x82, 0xEA, 0x82, 0xBD, 0x8E, 0x9E,
|
||||||
|
0x82, 0xC9, 0x82, 0xCD, 0x8C, 0xBB, 0x8E, 0xC0,
|
||||||
|
0x93, 0xA6, 0x94, 0xF0, 0x81, 0x49
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
main(argc, argv)
|
||||||
|
int argc;
|
||||||
|
char *argv[];
|
||||||
|
{
|
||||||
|
char *imgfile, *bootfile;
|
||||||
|
char img[SIZE_BOOTBLK], boot[SIZE_BOOTBLK];
|
||||||
|
int size_img, size_boot;
|
||||||
|
int fd;
|
||||||
|
int labelstart, labelend, imgstart, imgend;
|
||||||
|
|
||||||
|
if (argc != 3) {
|
||||||
|
fprintf(stderr, "usage: %s image_file boot_block\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
imgfile = argv[1];
|
||||||
|
bootfile = argv[2];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read image
|
||||||
|
*/
|
||||||
|
if ((fd = open(imgfile, O_RDONLY)) < 0)
|
||||||
|
err(1, "%s", imgfile);
|
||||||
|
|
||||||
|
if ((size_img = read(fd, img, sizeof img)) < 0)
|
||||||
|
err(1, "%s", imgfile);
|
||||||
|
|
||||||
|
if (size_img >= (int) sizeof img)
|
||||||
|
errx(1, "%s: file too large", imgfile);
|
||||||
|
|
||||||
|
(void) close(fd);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read boot block
|
||||||
|
*/
|
||||||
|
if ((fd = open(bootfile, O_RDWR)) < 0)
|
||||||
|
err(1, "%s", bootfile);
|
||||||
|
|
||||||
|
if ((size_boot = read(fd, boot, sizeof boot)) < 0)
|
||||||
|
err(1, "%s", bootfile);
|
||||||
|
|
||||||
|
if (lseek(fd, (off_t) 0, SEEK_SET))
|
||||||
|
err(1, "%s: lseek", bootfile);
|
||||||
|
|
||||||
|
if (size_boot < 4096) /* XXX */
|
||||||
|
errx(1, "%s: too short", bootfile);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check boot block
|
||||||
|
*/
|
||||||
|
if (memcmp(boot, boottop, sizeof boottop))
|
||||||
|
errx(1, "%s: not a boot", bootfile);
|
||||||
|
|
||||||
|
labelstart = X68K_LABELOFF;
|
||||||
|
if (get_uint16(boot + labelstart - 4) != 0x6000) /* bra */
|
||||||
|
badboot: errx(1, "%s: wrong boot block", bootfile);
|
||||||
|
|
||||||
|
labelend = labelstart + get_uint16(boot + labelstart - 2) - 4;
|
||||||
|
if (labelend >= size_boot)
|
||||||
|
goto badboot;
|
||||||
|
|
||||||
|
imgstart = get_uint16(boot + labelend);
|
||||||
|
if (imgstart == 0)
|
||||||
|
errx(1, "%s: no image support by this boot", bootfile);
|
||||||
|
|
||||||
|
imgend = get_uint16(boot + imgstart);
|
||||||
|
imgstart += 2;
|
||||||
|
|
||||||
|
if (imgend < imgstart || imgend >= size_boot)
|
||||||
|
goto badboot;
|
||||||
|
|
||||||
|
/* disklabel exists? */
|
||||||
|
if (get_uint32(boot + labelstart) == MAGIC_DISKLABEL)
|
||||||
|
labelstart = labelend; /* don't destroy disklabel */
|
||||||
|
else
|
||||||
|
labelstart += 2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* the image fits this boot?
|
||||||
|
*/
|
||||||
|
if (size_img > (imgend - imgstart) + (labelend - labelstart))
|
||||||
|
errx(1, "%s: image doesn't fit (max %d bytes)",
|
||||||
|
imgfile, (imgend - imgstart) + (labelend - labelstart));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* put image into boot
|
||||||
|
*/
|
||||||
|
if (size_img <= (imgend - imgstart)) {
|
||||||
|
memcpy(boot + imgstart, img, size_img);
|
||||||
|
} else {
|
||||||
|
memcpy(boot + imgstart, img, imgend - imgstart);
|
||||||
|
boot[labelstart - 2] = 'i';
|
||||||
|
boot[labelstart - 1] = 'm';
|
||||||
|
memcpy(boot + labelstart, img + (imgend - imgstart),
|
||||||
|
size_img - (imgend - imgstart));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* write back boot block
|
||||||
|
*/
|
||||||
|
if (write(fd, boot, size_boot) != size_boot)
|
||||||
|
err(1, "%s: write back", bootfile);
|
||||||
|
|
||||||
|
if (close(fd))
|
||||||
|
err(1, "%s: close write", bootfile);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,439 @@
|
||||||
|
/* $NetBSD: xpm2bootimg.c,v 1.1 1998/09/01 20:04:05 itohy Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* convert XPM format image to boot title format
|
||||||
|
*
|
||||||
|
* written by Yasha (ITOH Yasufumi), public domain
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static int opt_ascii;
|
||||||
|
|
||||||
|
#define IMGWIDTH 56
|
||||||
|
#define IMGHEIGHT 52
|
||||||
|
|
||||||
|
/* if you change this, you must also make changes to the extraction code */
|
||||||
|
#define VALBIT 2
|
||||||
|
#define LENBIT 3
|
||||||
|
#define LENMAX (1<<LENBIT)
|
||||||
|
|
||||||
|
#if VALBIT + LENBIT > 8
|
||||||
|
#error too long encoding --- not portable between architectures in this code
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* this program may run on cross host, and should be portable */
|
||||||
|
#ifdef __STDC__
|
||||||
|
# define PROTO(x) x
|
||||||
|
#else
|
||||||
|
# define PROTO(x) ()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void putbyte PROTO((int c));
|
||||||
|
static void initdot PROTO((void));
|
||||||
|
static void putrun PROTO((int val, int len));
|
||||||
|
static void adddot PROTO((int val));
|
||||||
|
static void flushdot PROTO((void));
|
||||||
|
|
||||||
|
static unsigned rgb16b PROTO((int rgb));
|
||||||
|
static char *destring PROTO((char *str));
|
||||||
|
static char *getline PROTO((void));
|
||||||
|
static void error PROTO((char *msg));
|
||||||
|
int main PROTO((int argc, char *argv[]));
|
||||||
|
|
||||||
|
static int outbuf;
|
||||||
|
static int bufbits;
|
||||||
|
static int curval;
|
||||||
|
static int curlen;
|
||||||
|
|
||||||
|
static int obytes;
|
||||||
|
|
||||||
|
static void
|
||||||
|
putbyte(c)
|
||||||
|
int c;
|
||||||
|
{
|
||||||
|
static unsigned char wbuf;
|
||||||
|
|
||||||
|
if (c == -1) {
|
||||||
|
if (obytes % 16 && opt_ascii)
|
||||||
|
printf("\n");
|
||||||
|
if (obytes & 1) {
|
||||||
|
if (opt_ascii)
|
||||||
|
printf("\t.byte\t0x%02x\n", wbuf);
|
||||||
|
else
|
||||||
|
putchar(wbuf);
|
||||||
|
}
|
||||||
|
if (opt_ascii)
|
||||||
|
printf("| compressed image %d bytes\n", obytes);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (obytes % 16 == 0 && opt_ascii)
|
||||||
|
printf("\t.word\t");
|
||||||
|
|
||||||
|
obytes++;
|
||||||
|
if (obytes & 1)
|
||||||
|
wbuf = c;
|
||||||
|
else {
|
||||||
|
if (opt_ascii) {
|
||||||
|
if ((obytes >> 1) % 8 != 1)
|
||||||
|
printf(",");
|
||||||
|
printf("0x%04x", (wbuf << 8) | c);
|
||||||
|
} else
|
||||||
|
printf("%c%c", wbuf, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obytes % 16 == 0 && opt_ascii)
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
initdot()
|
||||||
|
{
|
||||||
|
|
||||||
|
outbuf = bufbits = curval = curlen = obytes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int put;
|
||||||
|
|
||||||
|
static void
|
||||||
|
putrun(val, len)
|
||||||
|
int val, len;
|
||||||
|
{
|
||||||
|
|
||||||
|
/* fprintf(stderr, "val %d, len %d\n", val, len);*/
|
||||||
|
outbuf <<= VALBIT;
|
||||||
|
outbuf |= val;
|
||||||
|
outbuf <<= LENBIT;
|
||||||
|
outbuf |= len - 1;
|
||||||
|
bufbits += VALBIT + LENBIT;
|
||||||
|
|
||||||
|
if (bufbits >= 8) {
|
||||||
|
putbyte((unsigned char) (outbuf >> (bufbits - 8)));
|
||||||
|
bufbits -= 8;
|
||||||
|
put = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
adddot(val)
|
||||||
|
int val;
|
||||||
|
{
|
||||||
|
|
||||||
|
if (curval != val) {
|
||||||
|
if (curlen)
|
||||||
|
putrun(curval, curlen);
|
||||||
|
curlen = 0;
|
||||||
|
curval = val;
|
||||||
|
}
|
||||||
|
curlen++;
|
||||||
|
if (curlen == LENMAX) {
|
||||||
|
putrun(val, LENMAX);
|
||||||
|
curlen = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
flushdot()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (curlen) {
|
||||||
|
putrun(curval, curlen);
|
||||||
|
curlen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bufbits) {
|
||||||
|
/* make sure data drain */
|
||||||
|
put = 0;
|
||||||
|
while (put == 0)
|
||||||
|
putrun(curval, LENMAX);
|
||||||
|
}
|
||||||
|
putbyte(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* convert r8g8b8 to g5r5b5i1
|
||||||
|
*/
|
||||||
|
static unsigned
|
||||||
|
rgb16b(rgb)
|
||||||
|
int rgb;
|
||||||
|
{
|
||||||
|
unsigned r = rgb >> 16, g = (rgb >> 8) & 0xff, b = rgb & 0xff;
|
||||||
|
unsigned rgb16;
|
||||||
|
|
||||||
|
rgb16 = (g << 8 & 0xf800) | (r << 3 & 0x7c0) | (b >> 2 & 0x3e);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* v v v v v i i i
|
||||||
|
* valid bits used for I bit
|
||||||
|
*/
|
||||||
|
if ((r & 7) + (g & 7) + (b & 7) >= 11)
|
||||||
|
rgb16 |= 1;
|
||||||
|
|
||||||
|
return rgb16;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
destring(str)
|
||||||
|
char *str; /* must be writable */
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if (*str != '"' || (len = strlen(str)) < 2)
|
||||||
|
return NULL;
|
||||||
|
p = str + len - 1;
|
||||||
|
if (*p == ',') {
|
||||||
|
if (len < 3)
|
||||||
|
return NULL;
|
||||||
|
p--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p != '"')
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*p = '\0';
|
||||||
|
return str + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *filename;
|
||||||
|
static FILE *infp;
|
||||||
|
static unsigned lineno;
|
||||||
|
|
||||||
|
static char *
|
||||||
|
getline()
|
||||||
|
{
|
||||||
|
static char buf[256];
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if (!fgets(buf, sizeof buf, infp)) {
|
||||||
|
if (ferror(infp)) {
|
||||||
|
perror(filename);
|
||||||
|
exit(1);
|
||||||
|
} else
|
||||||
|
return NULL; /* end of input */
|
||||||
|
}
|
||||||
|
lineno++;
|
||||||
|
if (!(p = strchr(buf, '\n'))) {
|
||||||
|
fprintf(stderr, "%s:%d: too long line\n", filename, lineno);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
error(msg)
|
||||||
|
char *msg;
|
||||||
|
{
|
||||||
|
if (!msg)
|
||||||
|
msg = "format error";
|
||||||
|
|
||||||
|
fprintf(stderr, "%s:%d: %s\n", filename, lineno, msg);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct color {
|
||||||
|
int ch;
|
||||||
|
enum col {
|
||||||
|
COL_BLACK, COL_1, COL_2, COL_WHITE
|
||||||
|
} val;
|
||||||
|
} coltbl[32];
|
||||||
|
|
||||||
|
unsigned col1, col2;
|
||||||
|
|
||||||
|
enum col bitmap[IMGHEIGHT][IMGWIDTH];
|
||||||
|
|
||||||
|
int
|
||||||
|
main(argc, argv)
|
||||||
|
int argc;
|
||||||
|
char *argv[];
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
unsigned u, colors, xcol, x;
|
||||||
|
char buf[256];
|
||||||
|
int in_oc;
|
||||||
|
char *progname = argv[0];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* parse arg
|
||||||
|
*/
|
||||||
|
if (argc > 1 && !strcmp(argv[1], "-s")) {
|
||||||
|
/*
|
||||||
|
* -s option: output assembler source
|
||||||
|
* (output binary otherwise)
|
||||||
|
*/
|
||||||
|
opt_ascii = 1;
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
}
|
||||||
|
if (argc == 1) {
|
||||||
|
infp = stdin;
|
||||||
|
filename = "stdin";
|
||||||
|
} else if (argc == 2) {
|
||||||
|
if ((infp = fopen(argv[1], "r")) == NULL) {
|
||||||
|
perror(argv[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
filename = argv[1];
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "usage: %s [file.xpm]\n", progname);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check XPM magic
|
||||||
|
*/
|
||||||
|
if (!(p = getline()))
|
||||||
|
error("short file");
|
||||||
|
|
||||||
|
if (strcmp(p, "/* XPM */"))
|
||||||
|
error((char *) NULL);
|
||||||
|
|
||||||
|
while ((p = getline()) && !(p = destring(p)))
|
||||||
|
;
|
||||||
|
if (!p)
|
||||||
|
error((char *) NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* the first string must be
|
||||||
|
* "56 52 5 1 XPMEXT",
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
unsigned w, h, cpp;
|
||||||
|
|
||||||
|
if (sscanf(p, "%u %u %u %u %s",
|
||||||
|
&w, &h, &colors, &cpp, buf) != 5)
|
||||||
|
error("must be \"56 52 * 1 XPMEXT\"");
|
||||||
|
|
||||||
|
if (w != IMGWIDTH)
|
||||||
|
error("image width must be 56");
|
||||||
|
if (h != IMGHEIGHT)
|
||||||
|
error("image height must be 52");
|
||||||
|
if (cpp != 1)
|
||||||
|
error("chars-per-pixel must be 1");
|
||||||
|
if (strcmp(buf, "XPMEXT"))
|
||||||
|
error("XPMEXT is required");
|
||||||
|
}
|
||||||
|
if (colors > sizeof coltbl / sizeof coltbl[0])
|
||||||
|
error("too many colors");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read colors
|
||||||
|
* ". c #ffffff",
|
||||||
|
*/
|
||||||
|
xcol = 0;
|
||||||
|
for (u = 0; u < colors; u++) {
|
||||||
|
while ((p = getline()) && !(p = destring(p)))
|
||||||
|
;
|
||||||
|
if (!p)
|
||||||
|
error((char *) NULL);
|
||||||
|
if (sscanf(p, "%c %c %s", buf, buf+1, buf+2) != 3)
|
||||||
|
error((char *) NULL);
|
||||||
|
|
||||||
|
coltbl[u].ch = buf[0];
|
||||||
|
if (buf[2] == '#') {
|
||||||
|
int v;
|
||||||
|
if (sscanf(buf+3, "%x", &v) != 1)
|
||||||
|
error((char *) NULL);
|
||||||
|
if (v == 0)
|
||||||
|
coltbl[u].val = COL_BLACK;
|
||||||
|
else if (v == 0xffffff)
|
||||||
|
coltbl[u].val = COL_WHITE;
|
||||||
|
else if (xcol == 0) {
|
||||||
|
coltbl[u].val = COL_1;
|
||||||
|
col1 = rgb16b(v);
|
||||||
|
xcol++;
|
||||||
|
} else if (xcol == 1) {
|
||||||
|
coltbl[u].val = COL_2;
|
||||||
|
col2 = rgb16b(v);
|
||||||
|
xcol++;
|
||||||
|
} else
|
||||||
|
error("too many colors");
|
||||||
|
} else if (!strcmp(buf+2, "None")) {
|
||||||
|
/*
|
||||||
|
* transparent color is treated as black
|
||||||
|
*/
|
||||||
|
coltbl[u].val = COL_BLACK;
|
||||||
|
} else
|
||||||
|
error("unknown color (symbolic name is not supported)");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read bitmaps
|
||||||
|
*/
|
||||||
|
for (u = 0; u < IMGHEIGHT; u++) {
|
||||||
|
|
||||||
|
while ((p = getline()) && !(p = destring(p)))
|
||||||
|
;
|
||||||
|
if (!p)
|
||||||
|
error((char *) NULL);
|
||||||
|
|
||||||
|
if (strlen(p) != IMGWIDTH)
|
||||||
|
error((char *) NULL);
|
||||||
|
|
||||||
|
for (x = 0; x < IMGWIDTH; x++, p++) {
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
for (i = 0; i < colors; i++)
|
||||||
|
if (coltbl[i].ch == *p)
|
||||||
|
goto found_ch;
|
||||||
|
error("unknown character");
|
||||||
|
|
||||||
|
found_ch:
|
||||||
|
bitmap[u][x] = coltbl[i].val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read XPMEXTs and output copyright string
|
||||||
|
*/
|
||||||
|
in_oc = 0;
|
||||||
|
while ((p = getline()) && *p == '\"') {
|
||||||
|
if (!(p = destring(p)))
|
||||||
|
error((char *) NULL);
|
||||||
|
if (!strcmp(p, "XPMEXT copyright"))
|
||||||
|
in_oc = 1;
|
||||||
|
else if (!strncmp(p, "XPMENDEXT", 3))
|
||||||
|
break;
|
||||||
|
else if (!strncmp(p, "XPM", 3))
|
||||||
|
in_oc = 0;
|
||||||
|
else {
|
||||||
|
if (in_oc) {
|
||||||
|
if (opt_ascii)
|
||||||
|
printf("\t.ascii\t\"\\n%s\"\n", p);
|
||||||
|
else
|
||||||
|
printf("\n%s", p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* terminate string */
|
||||||
|
if (opt_ascii)
|
||||||
|
printf("\t.byte\t0\n");
|
||||||
|
else
|
||||||
|
putchar('\0');
|
||||||
|
|
||||||
|
/* output color palette */
|
||||||
|
if (opt_ascii)
|
||||||
|
printf("\t.word\t0x%x,0x%x\n", col1, col2);
|
||||||
|
else
|
||||||
|
printf("%c%c%c%c", col1 >> 8, col1, col2 >> 8, col2);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* scan bitmap and output
|
||||||
|
*/
|
||||||
|
initdot();
|
||||||
|
|
||||||
|
for (u = 0; u < IMGHEIGHT; u++)
|
||||||
|
for (x = 0; x < IMGWIDTH; x++)
|
||||||
|
adddot(bitmap[u][x]);
|
||||||
|
|
||||||
|
flushdot();
|
||||||
|
|
||||||
|
if (opt_ascii)
|
||||||
|
printf("\t.even\n");
|
||||||
|
|
||||||
|
return ferror(stdout);
|
||||||
|
}
|
|
@ -0,0 +1,170 @@
|
||||||
|
#! /bin/sh
|
||||||
|
#
|
||||||
|
# do like as disklabel -B
|
||||||
|
#
|
||||||
|
# usage: installboot <boot_file> <boot_device(raw)>
|
||||||
|
#
|
||||||
|
# requires /bin/sh /bin/dd /bin/mkdir /bin/rm /bin/test
|
||||||
|
# /sbin/disklabel /usr/bin/sed /usr/bin/od
|
||||||
|
#
|
||||||
|
# Public domain --written by Yasha (ITOH Yasufumi)
|
||||||
|
#
|
||||||
|
# $NetBSD: installboot.sh,v 1.1 1998/09/01 20:02:34 itohy Exp $
|
||||||
|
|
||||||
|
# disklabel magic (0x82564557) in target byte order
|
||||||
|
disklabelmagic='202 126 105 127' # target is Big endian
|
||||||
|
#disklabelmagic='127 105 126 202' # target is Little endian
|
||||||
|
#disklabelmagic='126 202 127 105' # target is PDP endian
|
||||||
|
|
||||||
|
usage='echo "usage: $0 [-nvf] /usr/mdec/xxboot /dev/rxx?a" >&2; exit 1'
|
||||||
|
|
||||||
|
blksz=1024
|
||||||
|
nblock=8 # boot block in $blksz (8KB)
|
||||||
|
rawpart=c
|
||||||
|
|
||||||
|
PATH=/bin:/sbin:/usr/bin
|
||||||
|
|
||||||
|
# parse options
|
||||||
|
dowrite=true
|
||||||
|
verbose=false
|
||||||
|
force=false
|
||||||
|
while (case "$1" in -*) ;; *) exit 1;; esac); do
|
||||||
|
case "$1" in
|
||||||
|
-[nvf]|-[nvf][nvf]|-[nvf][nvf][nvf]|-[nvf][nvf][nvf][nvf]) # enough?
|
||||||
|
case "$1" in *n*) dowrite=false;; esac
|
||||||
|
case "$1" in *v*) verbose=true;; esac
|
||||||
|
case "$1" in *f*) force=true;; esac
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
eval $usage;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
case "$#" in
|
||||||
|
2) ;;
|
||||||
|
*) eval $usage;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
boot="$1"
|
||||||
|
rootdev="$2"
|
||||||
|
temp=/tmp/installboot$$
|
||||||
|
isafloppy=false
|
||||||
|
haslabel=false
|
||||||
|
|
||||||
|
# report error early
|
||||||
|
if test ! -f "$boot"; then
|
||||||
|
echo "$boot: file not found" >&2
|
||||||
|
eval $usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check device so as not to destroy non-BSD partitions
|
||||||
|
if test -b "$rootdev"; then
|
||||||
|
echo "$rootdev: is a block special---specify a char special"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if test -c "$rootdev"; then
|
||||||
|
if $force; then :; else # check if not -f
|
||||||
|
case "$rootdev" in
|
||||||
|
/dev/rfd??) # floppies---check disklabel later
|
||||||
|
isafloppy=true;;
|
||||||
|
/dev/r*[a-h]) # SCSI disks
|
||||||
|
$verbose && echo "checking partition type..."
|
||||||
|
rawdev="`echo \"$rootdev\" | sed 's/.$/'$rawpart'/'`"
|
||||||
|
part="`echo \"$rootdev\" | sed 's/^.*\(.\)$/\1/'`"
|
||||||
|
pinfo="`disklabel \"$rawdev\" | sed '1,/^$/d' |
|
||||||
|
sed -n -e 's/^#.*/#/p' -e \"/^ $part/p\"`"
|
||||||
|
$verbose && echo "$pinfo" | sed '/^#/d'
|
||||||
|
case "$pinfo" in
|
||||||
|
'#'*' '$part:*4.2BSD*)
|
||||||
|
$verbose && echo "partition OK"
|
||||||
|
;;
|
||||||
|
'#') echo "$rootdev: no such partition" >&2
|
||||||
|
exit 1;;
|
||||||
|
'') echo "$rootdev: can't read disklabel" >&2
|
||||||
|
exit 1;;
|
||||||
|
*) echo "$rootdev: not a BSD filesystem" >&2
|
||||||
|
exit 1;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
/*) # ???
|
||||||
|
echo "$rootdev: can't install boot to this device" >&2
|
||||||
|
exit 1;;
|
||||||
|
*)
|
||||||
|
echo "$rootdev: not in the absolute path" >&2
|
||||||
|
exit 1;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
elif test ! -f "$rootdev"; then
|
||||||
|
echo "$rootdev: no such file or character special" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check for disklabel
|
||||||
|
case "`(dd if=\"$rootdev\" bs=$blksz count=1 | dd bs=4 skip=16 count=1 |
|
||||||
|
od -b | sed 1q) 2>/dev/null`" in
|
||||||
|
'0000000 '*" $disklabelmagic"*)
|
||||||
|
$verbose && echo "$rootdev: disklabel exists---may be a floppy disk"
|
||||||
|
haslabel=true;;
|
||||||
|
'0000000 '*|'*')
|
||||||
|
if $isafloppy; then
|
||||||
|
echo "$rootdev: not a BSD floppy disk" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
$verbose && echo "$rootdev: no disklabel in boot block---may be a SCSI disk"
|
||||||
|
;;
|
||||||
|
*) # error
|
||||||
|
if $force; then :; else # check if not -f
|
||||||
|
echo "$rootdev: can't read boot block" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# write boot block
|
||||||
|
if $haslabel; then
|
||||||
|
trap "rm -rf $temp; exit 1" 1 2 3 15
|
||||||
|
rm -rf $temp
|
||||||
|
mkdir $temp || exit 1
|
||||||
|
bootblk=$temp/bootblk
|
||||||
|
|
||||||
|
# read original disklabel and create new boot block
|
||||||
|
# with somewhat paranoid error checkings
|
||||||
|
$verbose && echo "extracting disklabel of $rootdev"
|
||||||
|
case `( ( dd if="$boot" bs=64 count=1 || echo boot >&3
|
||||||
|
(dd if="$rootdev" bs=$blksz count=1 || echo dev >&3) |
|
||||||
|
dd bs=4 skip=16 count=69 || echo label >&3
|
||||||
|
dd if="$boot" bs=340 skip=1 || echo boot >&3
|
||||||
|
) >$bootblk 2>/dev/null ) 3>&1` in
|
||||||
|
'') ;; # OK
|
||||||
|
*dev*) echo "$rootdev: can't read disklabel" >&2
|
||||||
|
rm -rf $temp; exit 1;;
|
||||||
|
*label*)
|
||||||
|
echo "can't create temporary file" >&2
|
||||||
|
rm -rf $temp; exit 1;;
|
||||||
|
boot*) echo "$boot: unreadable" >&2
|
||||||
|
rm -rf $temp; exit 1;;
|
||||||
|
*) echo "$boot: unreadable or can't write temporary file" >&2
|
||||||
|
rm -rf $temp; exit 1;;
|
||||||
|
esac
|
||||||
|
# check if the disklabel is correctly read
|
||||||
|
case "`(dd if=$bootblk bs=$blksz count=1 | dd bs=4 skip=16 count=1 |
|
||||||
|
od -b | sed 1q) 2>/dev/null`" in
|
||||||
|
'0000000 '*" $disklabelmagic"*) ;;
|
||||||
|
*) echo "failed to extract original disklabel" >&2
|
||||||
|
rm -rf $temp; exit 1;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
$verbose && echo "writing $boot to $rootdev"
|
||||||
|
cmd="dd if=$bootblk bs=$blksz count=$nblock conv=sync,notrunc of=$rootdev"
|
||||||
|
$verbose && echo "$cmd"
|
||||||
|
if $dowrite; then $cmd; else :; fi
|
||||||
|
s=$?
|
||||||
|
rm -rf $temp
|
||||||
|
exit $s
|
||||||
|
else
|
||||||
|
$verbose && echo "writing $boot to $rootdev"
|
||||||
|
cmd="dd if=$boot bs=$blksz count=$nblock conv=sync,notrunc of=$rootdev"
|
||||||
|
$verbose && echo "$cmd"
|
||||||
|
if $dowrite; then $cmd; else :; fi
|
||||||
|
fi
|
|
@ -0,0 +1,44 @@
|
||||||
|
/* $NetBSD: iocscall.h,v 1.1 1998/09/01 20:02:34 itohy Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IOCS call macros for X680x0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef X68k_IOCSCALL_H
|
||||||
|
#define X68k_IOCSCALL_H
|
||||||
|
|
||||||
|
#ifdef __NeXT__
|
||||||
|
# define IMM \#
|
||||||
|
#else
|
||||||
|
# define IMM #
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define IOCS(n) \
|
||||||
|
moveq IMM n,d0;\
|
||||||
|
trap IMM 15
|
||||||
|
|
||||||
|
#define __B_KEYINP 0x00
|
||||||
|
#define __B_SFTSNS 0x02
|
||||||
|
#define __TPALET2 0x14
|
||||||
|
#define __TCOLOR 0x15
|
||||||
|
#define __TEXTPUT 0x1B
|
||||||
|
#define __B_PUTC 0x20
|
||||||
|
#define __B_PRINT 0x21
|
||||||
|
#define __B_COLOR 0x22
|
||||||
|
#define __B_LOCATE 0x23
|
||||||
|
#define __B_CLR_ST 0x2A
|
||||||
|
#define __B_READ 0x46
|
||||||
|
#define __BOOTINF 0xFFFFFF8E
|
||||||
|
#define __JISSFT 0xFFFFFFA1
|
||||||
|
#define __SYS_STAT 0xFFFFFFAC /* only for X68030 or Xellent */
|
||||||
|
#define __SCSIDRV 0xFFFFFFF5
|
||||||
|
|
||||||
|
#define SCSIIOCS(s) \
|
||||||
|
moveq IMM s,d1;\
|
||||||
|
IOCS(__SCSIDRV)
|
||||||
|
|
||||||
|
#define __S_READ 0x21
|
||||||
|
#define __S_READCAP 0x25
|
||||||
|
#define __S_READEXT 0x26
|
||||||
|
|
||||||
|
#endif /*X68k_IOCSCALL_H*/
|
|
@ -0,0 +1,815 @@
|
||||||
|
| file: boot.s
|
||||||
|
| author: chapuni(GBA02750@niftyserve.or.jp)
|
||||||
|
| Yasha
|
||||||
|
|
|
||||||
|
| $NetBSD: xxboot.S,v 1.1 1998/09/01 20:02:35 itohy Exp $
|
||||||
|
|
||||||
|
#include "iocscall.h"
|
||||||
|
|
||||||
|
#define BASEOFF 0x8000
|
||||||
|
#define BASEPTR_A (TEXTADDR+BASEOFF)
|
||||||
|
#define BASEPTR_R pc@(top+BASEOFF:W)
|
||||||
|
|
||||||
|
#define SRAM 0x00ED0000 /* SRAM stat addr */
|
||||||
|
#define SRAM_MEMSZ (SRAM + 8) /* (L) size of main memory */
|
||||||
|
#define MINMEM 0x00400000 /* at least 4MB required */
|
||||||
|
|
||||||
|
#define BOOT_ERROR(s) jbsr boot_error; .asciz s; .even
|
||||||
|
|
||||||
|
.globl _header
|
||||||
|
.globl _image
|
||||||
|
|
||||||
|
_header=0x100000 | まずは、このアドレスに
|
||||||
|
_image=_header+(8*4) | コアをロードします。
|
||||||
|
|
||||||
|
#ifdef BOOT_DEBUG
|
||||||
|
.globl _startregs
|
||||||
|
_startregs=0xb000 | chosen arbitrarily...
|
||||||
|
#endif
|
||||||
|
|
||||||
|
.globl _bootufs
|
||||||
|
.text
|
||||||
|
top:
|
||||||
|
bras entry0
|
||||||
|
.ascii "SHARP/"
|
||||||
|
.ascii "X680x0"
|
||||||
|
.word 0x8199,0x94e6,0x82ea,0x82bd
|
||||||
|
.word 0x8e9e,0x82c9,0x82cd,0x8cbb
|
||||||
|
.word 0x8ec0,0x93a6,0x94f0,0x8149
|
||||||
|
| 0x2000 (FD), 0x2400 (SASI/SCSI) (もしくは 0x3F0000)
|
||||||
|
| d4 にはすでに SCSI ID が入っている
|
||||||
|
| ここから jmp まではリロケータブルに書かねばならない。
|
||||||
|
entry0:
|
||||||
|
#ifdef BOOT_DEBUG
|
||||||
|
moveml d0-d7/a0-a7,_startregs
|
||||||
|
#endif
|
||||||
|
lea BASEPTR_A:l,a5 | set base ptr
|
||||||
|
#define RELOC(adr) a5@(((adr)-(BASEPTR_A&0xffff)):W)
|
||||||
|
|
||||||
|
lea RELOC(_edata),a1 | BSS start
|
||||||
|
movew #_end-1,d0 | BSS end (low word only)
|
||||||
|
|
||||||
|
#ifndef BOOT_DEBUG /* not enough space -- moved below */
|
||||||
|
| check memory size (high word)
|
||||||
|
cmpiw #MINMEM/0x10000,SRAM_MEMSZ
|
||||||
|
#endif
|
||||||
|
bra entry
|
||||||
|
|
||||||
|
| 0x40 (= LABELOFFSET in <machine/disklabel.h>)
|
||||||
|
| Here disklabel exists for floppy disk (276 bytes)
|
||||||
|
disklabel:
|
||||||
|
.space 300
|
||||||
|
|
||||||
|
#ifdef TITLE_IMAGE
|
||||||
|
.word img_title-top
|
||||||
|
#else
|
||||||
|
.word 0
|
||||||
|
#endif
|
||||||
|
entry:
|
||||||
|
#ifdef BOOT_DEBUG
|
||||||
|
| check memory size (high word)
|
||||||
|
cmpiw #MINMEM/0x10000,SRAM_MEMSZ
|
||||||
|
#endif
|
||||||
|
jcc memok | (continued from above) RAM >= 4MB
|
||||||
|
BOOT_ERROR("4MB RAM required")
|
||||||
|
memok:
|
||||||
|
| clear out BSS (must be <= 64KB)
|
||||||
|
subw a1,d0
|
||||||
|
clrbss: clrb a1@+
|
||||||
|
dbra d0,clrbss
|
||||||
|
|
||||||
|
| set system stack
|
||||||
|
lea RELOC(top),a1 | set stack pointer to 0x003F0000
|
||||||
|
lea a1@,sp | a1 will be used later for IOCS calls
|
||||||
|
|
||||||
|
| we use 68020 instructions, and check MPU beforehand
|
||||||
|
|
|
||||||
|
| here d1.w = -1, and the above "subw a1,d0" = 0x9049, and
|
||||||
|
| if MPU <= 010 loads 0x49,
|
||||||
|
| if MPU >= 020 loads 0x90.
|
||||||
|
| This is a move, not a tst instruction
|
||||||
|
| because pc-relative tsts are not availble on 000/010.
|
||||||
|
chkmpu: moveb pc@(clrbss-chkmpu-2:B,d0:W:2),d0 | 103B 02xx
|
||||||
|
jmi mpuok | MC68020 or later
|
||||||
|
BOOT_ERROR("MPU 68000?")
|
||||||
|
mpuok: | XXX check for MMU?
|
||||||
|
|
||||||
|
movel d4,RELOC(_ID) | SCSI ID (if booted from SCSI)
|
||||||
|
IOCS(__BOOTINF)
|
||||||
|
movel d0,RELOC(_BOOT_INFO)
|
||||||
|
lsll #8,d0 | clear MSByte
|
||||||
|
lsrl #8,d0 |
|
||||||
|
|
||||||
|
|
|
||||||
|
| 0x80...0x8F SASI
|
||||||
|
| 0x90...0x93 Floppy
|
||||||
|
| 0xED0000...0xED3FFE SRAM
|
||||||
|
| others ROM (SCSI?)
|
||||||
|
|
|
||||||
|
movel d0,d1
|
||||||
|
clrb d1
|
||||||
|
tstl d1
|
||||||
|
jne boot_ram_rom
|
||||||
|
|
|
||||||
|
| SASI or Floppy
|
||||||
|
|
|
||||||
|
movel d0,d2
|
||||||
|
andib #0xFC,d0
|
||||||
|
cmpib #0x90,d0
|
||||||
|
jne boot_dev_unsupported | boot from SASI?
|
||||||
|
|
|
||||||
|
| Floppy
|
||||||
|
|
|
||||||
|
moveb d2,d0
|
||||||
|
andib #0x03,d0 | drive # (head=0)
|
||||||
|
jbsr check_fd_format
|
||||||
|
moveml d0-d1,RELOC(_FDSECMINMAX) | min and max sec #
|
||||||
|
lslw #8,d2
|
||||||
|
moveq #0x70,d1
|
||||||
|
orw d2,d1 | PDA*256 + MODE
|
||||||
|
movel d1,RELOC(_FDMODE)
|
||||||
|
movel d0,d2 | read position (first sector)
|
||||||
|
movel #8192,d3 | read bytes
|
||||||
|
IOCS(__B_READ)
|
||||||
|
jra boot_read_done
|
||||||
|
|
||||||
|
#include "chkfmt.s"
|
||||||
|
|
||||||
|
boot_ram_rom:
|
||||||
|
movel d0,d1
|
||||||
|
swap d1
|
||||||
|
cmpiw #0x00ED,d1
|
||||||
|
jne boot_SCSI
|
||||||
|
| boot from SRAM?
|
||||||
|
|
||||||
|
boot_dev_unsupported:
|
||||||
|
BOOT_ERROR("unsupported boot device")
|
||||||
|
|
||||||
|
|
|
||||||
|
| volatile void BOOT_ERROR(const char *msg);
|
||||||
|
| print error message, wait for key press and reboot
|
||||||
|
|
|
||||||
|
booterr_msg: .ascii "\r\n\n"
|
||||||
|
.ascii BOOT
|
||||||
|
.asciz ": "
|
||||||
|
reboot_msg: .asciz "\r\n[Hit key to reboot]"
|
||||||
|
.even
|
||||||
|
|
||||||
|
.globl _BOOT_ERROR
|
||||||
|
_BOOT_ERROR: addql #4,sp
|
||||||
|
|
||||||
|
boot_error: lea pc@(booterr_msg),a1
|
||||||
|
IOCS(__B_PRINT)
|
||||||
|
moveal sp@+,a1
|
||||||
|
IOCS(__B_PRINT)
|
||||||
|
lea pc@(reboot_msg),a1
|
||||||
|
IOCS(__B_PRINT)
|
||||||
|
|
||||||
|
| wait for a key press (or release of a modifier)
|
||||||
|
IOCS(__B_KEYINP)
|
||||||
|
|
||||||
|
| issue software reset
|
||||||
|
trap #10
|
||||||
|
| NOTREACHED
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
| ROM boot ... probably from SCSI
|
||||||
|
|
|
||||||
|
boot_SCSI:
|
||||||
|
#ifdef SCSI_ADHOC_BOOTPART
|
||||||
|
|
|
||||||
|
| Find out boot partition in an ad hoc manner.
|
||||||
|
|
|
||||||
|
|
||||||
|
| get block length of the SCSI disk
|
||||||
|
SCSIIOCS(__S_READCAP) | using buffer at a1
|
||||||
|
tstl d0
|
||||||
|
jeq 1f
|
||||||
|
BOOT_ERROR("READCAP failed")
|
||||||
|
1: moveq #0,d5
|
||||||
|
moveb a1@(6),d5 | 1: 256, 2: 512, 4: 1024
|
||||||
|
lsrb #1,d5 | 0: 256, 1: 512, 2: 1024
|
||||||
|
movel d5,RELOC(_SCSI_BLKLEN)
|
||||||
|
|
||||||
|
| find out the start position of the boot partition
|
||||||
|
| XXX VERY AD HOC
|
||||||
|
|
|
||||||
|
| SCSI IPLs (genuine and SxSI):
|
||||||
|
| pass read pos (in kilobytes) in d2
|
||||||
|
| partition table on the memory is destroyed
|
||||||
|
| BOOT MENU Ver.2.22:
|
||||||
|
| passes partition table entry address in a0
|
||||||
|
| d2 is cleared to zero
|
||||||
|
| No other IPL is supported. XXX FIXME
|
||||||
|
tstl d2
|
||||||
|
jne 1f
|
||||||
|
| no information in d2 -- probably from BOOT MENU
|
||||||
|
| a0 points the partiion table entry
|
||||||
|
movel a0@(0x0008),d2 | in KByte
|
||||||
|
1: lsll #8,d2 | clear MSByte
|
||||||
|
lsrl #6,d2 |
|
||||||
|
lsrl d5,d2 | in sector
|
||||||
|
movel d2,RELOC(_SCSI_PARTTOP)
|
||||||
|
|
||||||
|
| read entire boot
|
||||||
|
moveq #8192/256,d3 | size is 8KB
|
||||||
|
lsrl d5,d3 | in sector
|
||||||
|
jbsr scsiread | read at a1
|
||||||
|
#else
|
||||||
|
moveq #1,d5 | 512bytes/sec
|
||||||
|
moveq #8192/512,d3 | 読み込める最大サイズ
|
||||||
|
moveq #0x40,d2 | いわゆる決め打ち(sd*a のみ)
|
||||||
|
SCSIIOCS(__S_READ)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
boot_read_done:
|
||||||
|
|
||||||
|
| テキストパレットの初期化
|
||||||
|
moveq #15,d1
|
||||||
|
initpalet:
|
||||||
|
moveq #0,d2
|
||||||
|
subqw #1,d2 | movel #0xFFFF,d2
|
||||||
|
IOCS(__TPALET2)
|
||||||
|
subqw #1,d1
|
||||||
|
moveq #0,d2
|
||||||
|
IOCS(__TPALET2)
|
||||||
|
dbra d1,initpalet
|
||||||
|
|
||||||
|
jsr RELOC(_printtitle)
|
||||||
|
jmp RELOC(_bootufs) | 0x3Fxxxx に飛んでゆく
|
||||||
|
|
||||||
|
read_error: BOOT_ERROR("read error")
|
||||||
|
|
||||||
|
#undef RELOC /* base register a5 is no longer available */
|
||||||
|
|
||||||
|
|
|
||||||
|
| read SCSI
|
||||||
|
|
|
||||||
|
| input: d2.l: pos in sector
|
||||||
|
| d3.l: len in sector
|
||||||
|
| d4: target SCSI ID
|
||||||
|
| d5: sector length (0: 256, 1: 512, 2: 1024)
|
||||||
|
| a1: buffer address
|
||||||
|
| destroy:
|
||||||
|
| d0, d1, a1
|
||||||
|
|
|
||||||
|
scsiread:
|
||||||
|
moveml d2-d3/d6-d7/a2,sp@-
|
||||||
|
| if (pos >= 0x200000 || (len > 255 && pos + len >= 0x200000))
|
||||||
|
| use READEXT
|
||||||
|
| else
|
||||||
|
| use READ
|
||||||
|
moveq #0x20,d0
|
||||||
|
swap d0 | d0.l = 0x00200000
|
||||||
|
moveq #0,d6
|
||||||
|
subqb #1,d6 | d6.l = 255
|
||||||
|
moveq #8,d7
|
||||||
|
addb d5,d7 | d7.b = (sector length: 0-2) + 8
|
||||||
|
cmpl d0,d2
|
||||||
|
jcc scsiread_ext
|
||||||
|
moveq #__S_READ,d1
|
||||||
|
cmpl d3,d6
|
||||||
|
jcc scsiread_noext
|
||||||
|
subl d2,d0 | d0.0 = 0x200000 - pos
|
||||||
|
cmpl d0,d3 | <= len
|
||||||
|
jcs scsiread_noext | no
|
||||||
|
|
||||||
|
scsiread_ext: | use READEXT
|
||||||
|
extw d6 | d6.l = 65535
|
||||||
|
moveq #__S_READEXT,d1
|
||||||
|
|
||||||
|
scsiread_noext: | use READ
|
||||||
|
loop_scsiread:
|
||||||
|
| d1: SCSI IOCS call #
|
||||||
|
| d6: max sector count at a time
|
||||||
|
movel d3,a2 | save original len in a2
|
||||||
|
cmpl d3,d6
|
||||||
|
jcc 1f
|
||||||
|
movel d6,d3
|
||||||
|
1: IOCS(__SCSIDRV) | SCSIIOCS(d1)
|
||||||
|
tstl d0
|
||||||
|
jne read_error
|
||||||
|
movel d3,d0 | addr += read count << (8 + sec len)
|
||||||
|
asll d7,d0
|
||||||
|
addl d0,a1
|
||||||
|
exg d3,a2 | restore original len to d3
|
||||||
|
addl a2,d2 | pos += read count
|
||||||
|
subl a2,d3 | len -= read count
|
||||||
|
jne loop_scsiread
|
||||||
|
moveml sp@+,d2-d3/d6-d7/a2
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
|
||||||
|
| The former part must reside in the first 1KB.
|
||||||
|
|
|
||||||
|
.globl first_kbyte
|
||||||
|
first_kbyte:
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The latter text+data part is not accessible at the first boot time.
|
||||||
|
| PC-relative can be used from here.
|
||||||
|
|
|
||||||
|
|
||||||
|
| int badbaddr __P((caddr_t adr));
|
||||||
|
| check if the given address is valid for byte read
|
||||||
|
| return: 0: valid, 1: not valid
|
||||||
|
|
||||||
|
.globl _badbaddr
|
||||||
|
_badbaddr:
|
||||||
|
lea 0x0008:W,a1 | MPU Bus Error vector
|
||||||
|
moveq #1,d0
|
||||||
|
lea pc@(badr1),a0
|
||||||
|
movew sr,sp@-
|
||||||
|
oriw #0x0700,sr | keep out interrupts
|
||||||
|
movel a1@,sp@-
|
||||||
|
movel a0,a1@ | set bus error vector
|
||||||
|
movel sp,d1 | save sp
|
||||||
|
moveal sp@(10),a0
|
||||||
|
tstb a0@ | try read...
|
||||||
|
moveq #0,d0 | this is skipped on bus error
|
||||||
|
badr1: moveal d1,sp | restore sp
|
||||||
|
movel sp@+,a1@
|
||||||
|
movew sp@+,sr
|
||||||
|
rts
|
||||||
|
|
||||||
|
| void RAW_READ __P((void *buf, u_int32_t blkpos, size_t bytelen));
|
||||||
|
| inputs:
|
||||||
|
| buf: input buffer address
|
||||||
|
| blkpos: read start position in the partition in 512byte-blocks
|
||||||
|
| bytelen: read length in bytes
|
||||||
|
|
||||||
|
Lraw_read_buf=4+(4*11)
|
||||||
|
Lraw_read_pos_=Lraw_read_buf+4
|
||||||
|
Lraw_read_len=Lraw_read_buf+8
|
||||||
|
|
||||||
|
.globl _RAW_READ
|
||||||
|
#ifdef SCSI_ADHOC_BOOTPART
|
||||||
|
.globl _RAW_READ0
|
||||||
|
| RAW_READ of physical disk
|
||||||
|
_RAW_READ0:
|
||||||
|
moveq #0,d0
|
||||||
|
jra raw_read1
|
||||||
|
#endif
|
||||||
|
_RAW_READ:
|
||||||
|
#ifdef SCSI_ADHOC_BOOTPART
|
||||||
|
movel _SCSI_PARTTOP,d0
|
||||||
|
raw_read1:
|
||||||
|
#endif
|
||||||
|
moveml d2-d7/a2-a6,sp@-
|
||||||
|
moveml sp@(Lraw_read_buf),d1-d3
|
||||||
|
movel d1,a1
|
||||||
|
| d2.l: pos in 512byte-blocks
|
||||||
|
| d3.l: length in bytes
|
||||||
|
| a1 (=d1): buffer address
|
||||||
|
|
||||||
|
lea BASEPTR_R,a5 | set base ptr
|
||||||
|
#define RELOC(adr) a5@(((adr)-(BASEPTR_A&0xffff)):W)
|
||||||
|
|
||||||
|
tstb RELOC(_BOOT_INFO+1) | simple check. may be incorrect!
|
||||||
|
beqs raw_read_floppy
|
||||||
|
|
||||||
|
raw_read_scsi:
|
||||||
|
movel RELOC(_ID),d4 | SCSI ID
|
||||||
|
#ifdef SCSI_ADHOC_BOOTPART
|
||||||
|
movel RELOC(_SCSI_BLKLEN),d5 | sector size: 0-2
|
||||||
|
| XXX length must be sector aligned
|
||||||
|
lsrl #8,d3 | size in 256byte-blocks
|
||||||
|
lsrl d5,d3 | size in sector
|
||||||
|
bcss read_half | minimal error check
|
||||||
|
lsll #1,d2 | X flag and d2: pos in 256byte-blocks
|
||||||
|
roxrl d5,d2 | pos in sector
|
||||||
|
addl d0,d2 | physical pos in sector
|
||||||
|
#else
|
||||||
|
moveq #1,d5 | 512bytes/sec
|
||||||
|
moveq #9,d0 | shift count
|
||||||
|
addl #511,d3
|
||||||
|
lsrl d0,d3
|
||||||
|
bcss read_half | minimal error check
|
||||||
|
|
||||||
|
addl #0x40,d2 | 'a' partition starts here
|
||||||
|
#endif
|
||||||
|
| jcc 1f
|
||||||
|
| BOOT_ERROR("out of seek") | pos exceeds 32bit
|
||||||
|
|1:
|
||||||
|
jbsr scsiread
|
||||||
|
bras raw_read_end
|
||||||
|
|
||||||
|
raw_read_floppy:
|
||||||
|
|
|
||||||
|
| Floppy read routine
|
||||||
|
|
|
||||||
|
|
||||||
|
| convert to seek position
|
||||||
|
|
||||||
|
asll #2,d2 | size in 128byte-blocks
|
||||||
|
|
||||||
|
| sec = raw_read_pos (d2)
|
||||||
|
| sec >>= 7 + (sector length: 0-3)
|
||||||
|
|
||||||
|
lea RELOC(_FDSECMINMAX),a0
|
||||||
|
moveq #0,d1
|
||||||
|
moveb a0@,d1 | d1: sector length (0-3)
|
||||||
|
lsrl d1,d2 | d2: pos in sector
|
||||||
|
bcss read_half | error check
|
||||||
|
|
||||||
|
| trk = sec / (# sectors)
|
||||||
|
| sec = sec % (# sectors)
|
||||||
|
|
||||||
|
moveb a0@(7),d1 | d1: max sector #
|
||||||
|
subb a0@(3),d1 | - min sector #
|
||||||
|
addqb #1,d1 | d1: # sectors
|
||||||
|
divu d1,d2 | d2: (sec << 16) | track
|
||||||
|
|
||||||
|
| position = (sec length << 24) | (track/2 << 16)
|
||||||
|
| | (track%2 << 8) | (min sec # + sec)
|
||||||
|
|
||||||
|
movel a0@,d0 | d0: (sec len << 24) | min sec #
|
||||||
|
lsrw #1,d2 | d2: (sec << 16) | (track / 2)
|
||||||
|
jcc 1f
|
||||||
|
bset #8,d0 | |= (track % 2) << 8
|
||||||
|
1: swap d2 | d2: ((track / 2) << 16) | sec
|
||||||
|
addl d0,d2 | d2: position
|
||||||
|
|
||||||
|
| read
|
||||||
|
movel RELOC(_FDMODE),d1 | PDA*256 + MODE
|
||||||
|
|
||||||
|
| B_READ (for floppy)
|
||||||
|
| d1.w: PDA x 256 + MODE
|
||||||
|
| PDA: 0x90 (drive 0) ... 0x93 (drive 3)
|
||||||
|
| MODE: bit6: MFM
|
||||||
|
| bit5: retry
|
||||||
|
| bit4: seek
|
||||||
|
| d2.l: position
|
||||||
|
| bit31-24: sector length (0: 128, 1: 256, 2: 512, 3: 1K)
|
||||||
|
| bit23-16: track # (0-79)
|
||||||
|
| bit15-08: side (0 or 1)
|
||||||
|
| bit07-00: sector # (1-)
|
||||||
|
| d3.l: read bytes
|
||||||
|
| a1: read address
|
||||||
|
| return:
|
||||||
|
| d0: bit 31-24 ST0
|
||||||
|
| bit 23-16 ST1
|
||||||
|
| bit 15- 8 ST2
|
||||||
|
| bit 7- 0 C
|
||||||
|
| -1 on parameter error
|
||||||
|
| destroy: d0, d2, d3, a1
|
||||||
|
IOCS(__B_READ)
|
||||||
|
andil #0xf8ffff00,d0 | check status (must be zero)
|
||||||
|
jne read_error
|
||||||
|
|
||||||
|
raw_read_end:
|
||||||
|
moveml sp@+,a2-a6/d2-d7
|
||||||
|
rts
|
||||||
|
#undef RELOC /* base register a5 is no longer available */
|
||||||
|
|
||||||
|
read_half: BOOT_ERROR("read half of block")
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
.globl _JISSFT
|
||||||
|
_JISSFT:
|
||||||
|
movel sp@(4),d1
|
||||||
|
IOCS(__JISSFT)
|
||||||
|
rts
|
||||||
|
#endif
|
||||||
|
|
||||||
|
.globl _B_SFTSNS
|
||||||
|
_B_SFTSNS:
|
||||||
|
IOCS(__B_SFTSNS)
|
||||||
|
rts
|
||||||
|
|
||||||
|
.globl _B_KEYINP
|
||||||
|
_B_KEYINP:
|
||||||
|
IOCS(__B_KEYINP)
|
||||||
|
rts
|
||||||
|
|
||||||
|
.globl _B_PUTC
|
||||||
|
_B_PUTC:
|
||||||
|
movel sp@(4),d1
|
||||||
|
IOCS(__B_PUTC)
|
||||||
|
rts
|
||||||
|
|
||||||
|
.globl _B_PRINT
|
||||||
|
_B_PRINT:
|
||||||
|
movel sp@(4),a1
|
||||||
|
IOCS(__B_PRINT)
|
||||||
|
rts
|
||||||
|
|
||||||
|
.globl _B_COLOR
|
||||||
|
_B_COLOR:
|
||||||
|
movel sp@(4),d1
|
||||||
|
IOCS(__B_COLOR)
|
||||||
|
rts
|
||||||
|
|
||||||
|
.globl _B_LOCATE
|
||||||
|
_B_LOCATE:
|
||||||
|
movel d2,sp@-
|
||||||
|
movel sp@(8),d1
|
||||||
|
movel sp@(12),d2
|
||||||
|
IOCS(__B_LOCATE)
|
||||||
|
movel sp@+,d2
|
||||||
|
rts
|
||||||
|
|
||||||
|
.globl _B_CLR_ST
|
||||||
|
_B_CLR_ST:
|
||||||
|
movel sp@(4),d1
|
||||||
|
IOCS(__B_CLR_ST)
|
||||||
|
rts
|
||||||
|
|
||||||
|
.globl _printtitle
|
||||||
|
_printtitle:
|
||||||
|
lea pc@(msg_title),a1
|
||||||
|
IOCS(__B_PRINT)
|
||||||
|
#ifndef TITLE_IMAGE
|
||||||
|
rts
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TITLE_IMAGE
|
||||||
|
# define IMGXPOS 17
|
||||||
|
# define IMGYPOS 1
|
||||||
|
# define IMGWIDTH 56
|
||||||
|
# define IMGHEIGHT 52
|
||||||
|
|
|
||||||
|
| display title image
|
||||||
|
|
|
||||||
|
put_image: link a6,#-(IMGWIDTH*IMGHEIGHT/8*2+8) | make local buffer
|
||||||
|
moveal sp,a1 | buffer (plane #0) top
|
||||||
|
moveml d2-d7/a2-a4,sp@-
|
||||||
|
|
||||||
|
lea a1@(IMGWIDTH*IMGHEIGHT/8+4),a4 | buffer (plane #1) top
|
||||||
|
movel #IMGWIDTH*0x10000+IMGHEIGHT,a1@ | image size
|
||||||
|
movel a1@+,a4@+
|
||||||
|
|
||||||
|
lea pc@(img_title),a2
|
||||||
|
moveaw a2@+,a3 | only the lower word is valid
|
||||||
|
|
||||||
|
1: tstb a2@+ | skip human readable comment
|
||||||
|
jne 1b
|
||||||
|
lea a2@(4),a0 | image data here
|
||||||
|
|
||||||
|
moveq #0,d2 | (b) now have 0bit
|
||||||
|
moveq #0,d3 | (w) input bit buffer
|
||||||
|
|
||||||
|
moveq #16,d4 | (b) output bit count
|
||||||
|
moveq #IMGWIDTH*IMGHEIGHT/16+0xffffff00,d7
|
||||||
|
|
||||||
|
| d2.b: # bits in input buffer
|
||||||
|
| d3.w: input buffer
|
||||||
|
| d4.b: # bits in output buffer
|
||||||
|
| d5.w: output buffer for plane 0
|
||||||
|
| d6.w: output buffer for plane 1
|
||||||
|
| d7.b: size count
|
||||||
|
| a0: input data pointer
|
||||||
|
|
||||||
|
Lrunlen: | a run entry:
|
||||||
|
| value (2bit)
|
||||||
|
| length-1 (3bit)
|
||||||
|
subqb #5,d2 | have enough bits?
|
||||||
|
jcc Lhave5b | yes
|
||||||
|
| fill byte
|
||||||
|
cmpaw a0,a3 | the register order is significant
|
||||||
|
| for word comparison
|
||||||
|
jne 1f
|
||||||
|
lea pc@(disklabel),a0 | continue to disklabel area?
|
||||||
|
cmpiw #0x696d,a0@+ | check magic number
|
||||||
|
jne Lrxabort | no, abort (no image)
|
||||||
|
1: moveb a0@+,d0
|
||||||
|
addqb #8,d2 | d2: 3: have 0bit, ..., 7: have 4bit
|
||||||
|
lslw #8,d0 | clear unused bits
|
||||||
|
lsrw d2,d0
|
||||||
|
orw d0,d3
|
||||||
|
|
||||||
|
Lhave5b: | field# 19 20 21 22 23 24 25 26 27 28 29 30 31
|
||||||
|
| d3: ... v v l l l ? ? ? ? ? ? ? 0
|
||||||
|
bfexts d3{#19,#2},d0 | value
|
||||||
|
bfextu d3{#21,#3},d1 | length - 1
|
||||||
|
lslw #5,d3
|
||||||
|
|
||||||
|
Lrxloop: lslw #2,d6
|
||||||
|
bfins d0,d6{#30,#2}
|
||||||
|
roxrw #1,d6
|
||||||
|
roxlw #1,d5
|
||||||
|
subqb #1,d4
|
||||||
|
jne 1f
|
||||||
|
moveq #16,d4
|
||||||
|
movew d5,a1@+
|
||||||
|
movew d6,a4@+
|
||||||
|
subqb #1,d7 | end?
|
||||||
|
1: dbeq d1,Lrxloop | fall down if end
|
||||||
|
jne Lrunlen | fall down if end
|
||||||
|
|
||||||
|
moveq #1,d1
|
||||||
|
movew a2@+,d2
|
||||||
|
IOCS(__TPALET2)
|
||||||
|
moveq #2,d1
|
||||||
|
movew a2@,d2
|
||||||
|
IOCS(__TPALET2)
|
||||||
|
|
||||||
|
| moveq #0x02,d1 | plane 1 (already have it)
|
||||||
|
IOCS(__TCOLOR)
|
||||||
|
moveq #IMGXPOS,d1
|
||||||
|
moveq #IMGYPOS,d2
|
||||||
|
IOCS(__TEXTPUT)
|
||||||
|
moveq #0x01,d1 | plane 0
|
||||||
|
IOCS(__TCOLOR)
|
||||||
|
moveq #IMGXPOS,d1
|
||||||
|
lea a6@(-(IMGWIDTH*IMGHEIGHT/8*2+8)),a1
|
||||||
|
IOCS(__TEXTPUT)
|
||||||
|
|
||||||
|
Lrxabort: moveml sp@+,d2-d7/a2-a4
|
||||||
|
unlk a6
|
||||||
|
rts
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|IOCS SYS_STAT $AC
|
||||||
|
|
|
||||||
|
|入力 d1.l=0 のとき d0.l に以下の値
|
||||||
|
| bit0~7 0:68000, 1:68010, 2:68020, 3:68030
|
||||||
|
| bit14 0:MMUなし, 1:MMUあり
|
||||||
|
| bit15 0:FPCPなし, 1:FPCPあり
|
||||||
|
| bit16~31 クロックスピード
|
||||||
|
|
|
||||||
|
| X68000 の IOCS には $AC はないのでエラーになりますが、Xellent30 の場合は
|
||||||
|
|起動時に SRAM で組み込んでくれます。
|
||||||
|
.globl _SYS_STAT
|
||||||
|
_SYS_STAT:
|
||||||
|
movel sp@(4),d1
|
||||||
|
IOCS(__SYS_STAT)
|
||||||
|
rts
|
||||||
|
|
||||||
|
.globl _getcpu
|
||||||
|
_getcpu:
|
||||||
|
movl #0x200,d0 | data freeze bit
|
||||||
|
movc d0,cacr | only exists on 68030
|
||||||
|
movc cacr,d0 | read it back
|
||||||
|
tstl d0 | zero?
|
||||||
|
jeq Lnot68030 | yes, we have 68020/68040
|
||||||
|
movq #3,d0 | 68030
|
||||||
|
rts
|
||||||
|
Lnot68030:
|
||||||
|
bset #31,d0 | data cache enable bit
|
||||||
|
movc d0,cacr | only exists on 68040
|
||||||
|
movc cacr,d0 | read it back
|
||||||
|
tstl d0 | zero?
|
||||||
|
jeq Lis68020 | yes, we have 68020
|
||||||
|
moveq #0,d0 | now turn it back off
|
||||||
|
movec d0,cacr | before we access any data
|
||||||
|
movq #4,d0 | 68040
|
||||||
|
rts
|
||||||
|
Lis68020:
|
||||||
|
movq #2,d0 | 68020
|
||||||
|
rts
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
| void memcpy(void *dst, const void *src, size_t count);
|
||||||
|
| void memmove(void *dst, const void *src, size_t count);
|
||||||
|
|
|
||||||
|
| small and slow memcpy...
|
||||||
|
| THIS FUNCTION DOES NOT CONFORM THE ANSI STANDARD
|
||||||
|
|
|
||||||
|
.globl _memcpy, _memmove
|
||||||
|
_memcpy:
|
||||||
|
_memmove:
|
||||||
|
lea sp@(12),a1
|
||||||
|
movel a1@,d1 | count
|
||||||
|
jeq Lmcpret
|
||||||
|
moveal a1@-,a0 | src
|
||||||
|
moveal a1@-,a1 | dest
|
||||||
|
cmpl a1,a0
|
||||||
|
jcc Lmcpfw
|
||||||
|
| copy backward
|
||||||
|
addal d1,a0
|
||||||
|
addal d1,a1
|
||||||
|
1: moveb a0@-,a1@-
|
||||||
|
subql #1,d1
|
||||||
|
jne 1b
|
||||||
|
jra Lmcpret
|
||||||
|
Lmcpfw: | copy forward
|
||||||
|
1: moveb a0@+,a1@+
|
||||||
|
subql #1,d1
|
||||||
|
jne 1b
|
||||||
|
Lmcpret:
|
||||||
|
| movel sp@(8),d0 | uncomment this to conform ANSI
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
|
||||||
|
| Copy and exec kernel
|
||||||
|
|
|
||||||
|
#include "../common/execkern.S"
|
||||||
|
|
||||||
|
|
|
||||||
|
| Title message
|
||||||
|
|
|
||||||
|
msg_title:
|
||||||
|
.byte 0x1a | clear screen and cursor home
|
||||||
|
.ascii "\033[3;4H" | move cursor to 4, 3
|
||||||
|
.ascii "\033[37m" | bold
|
||||||
|
.ascii "NetBSD boot"
|
||||||
|
.ascii "\033[m" | normal
|
||||||
|
.ascii " ("
|
||||||
|
.ascii BOOT
|
||||||
|
.ascii " "
|
||||||
|
.ascii BOOT_VERS
|
||||||
|
#ifdef BOOT_DEBUG
|
||||||
|
.ascii "/DEBUG"
|
||||||
|
#endif
|
||||||
|
#ifndef TITLE_IMAGE
|
||||||
|
.ascii "/no title image"
|
||||||
|
#endif
|
||||||
|
.ascii ")"
|
||||||
|
.asciz "\r\n\n"
|
||||||
|
.even
|
||||||
|
|
||||||
|
#ifdef TITLE_IMAGE
|
||||||
|
|
|
||||||
|
| Title Image
|
||||||
|
|
|
||||||
|
img_title:
|
||||||
|
.word imgend1
|
||||||
|
#ifdef BOOT_DEBUG
|
||||||
|
.space 200 | no space for BSD Daemon...
|
||||||
|
#else
|
||||||
|
| compressed image data
|
||||||
|
|
||||||
|
| BSD Daemon Image, used for NetBSD boot by permission.
|
||||||
|
| (Thanks for permission!)
|
||||||
|
|
||||||
|
| BSD Daemon Copyright 1988 by Marshall Kirk McKusick.
|
||||||
|
| All Rights Reserved.
|
||||||
|
|
|
||||||
|
| Permission to use the daemon may be obtained from:
|
||||||
|
| Marshall Kirk McKusick
|
||||||
|
| 1614 Oxford St
|
||||||
|
| Berkeley, CA 94709-1608
|
||||||
|
| USA
|
||||||
|
| or via email at mckusick@mckusick.com
|
||||||
|
|
||||||
|
| Human readable copyright notice to be found with strings(1).
|
||||||
|
| Terminate with a nul character.
|
||||||
|
|
||||||
|
.asciz "\nBSD Daemon Copyright 1988 by Marshall Kirk McKusick."
|
||||||
|
|
||||||
|
.word 0x5295,0xAD6A | palet1, palet2
|
||||||
|
.word 0x39c3,0x0c1c,0xd039,0xce71,0xa327,0x3830,0x739c,0xe146
|
||||||
|
.word 0x6073,0x8227,0x39ce,0x0865,0x0738,0x2184,0x1ce7,0x3233
|
||||||
|
.word 0x049c,0xe88a,0x0e73,0x9618,0x8271,0x0486,0x6646,0x2093
|
||||||
|
.word 0x9ce4,0xcc12,0x1461,0x1622,0x3104,0x9ce7,0x2653,0x10e2
|
||||||
|
.word 0x4158,0x91a8,0x24e7,0x38d1,0x9807,0x00c8,0x7216,0x6a29
|
||||||
|
.word 0x39ce,0x4440,0x1906,0x4190,0xe031,0xe452,0x739c,0x9006
|
||||||
|
.word 0x8180,0xec18,0x0221,0xc8a0,0xe739,0xb60c,0x0380,0xdc35
|
||||||
|
.word 0x149c,0xe724,0x01b0,0x601d,0x062c,0x939c,0xe6c8,0x700c
|
||||||
|
.word 0x0b60,0xcc58,0x739c,0xf81e,0x09a0,0x6a49,0x39ce,0x6803
|
||||||
|
.word 0x00c0,0x701c,0x0740,0xd4d0,0x739c,0xd806,0x0100,0xe038
|
||||||
|
.word 0x0e81,0xb924,0xe726,0x0d0c,0x20e2,0xc839,0x249c,0xe4c4
|
||||||
|
.word 0x0ba4,0x0b42,0xc811,0xc920,0xe73c,0x070e,0x0383,0x44b5
|
||||||
|
.word 0x241c,0xe3c8,0x6228,0x701b,0x023f,0x8924,0xe726,0x0501
|
||||||
|
.word 0xc301,0xc8d3,0xfc49,0x0739,0xa01c,0x1219,0x0fc9,0x8924
|
||||||
|
.word 0xe716,0x2028,0x64a8,0xc441,0xc147,0x3249,0xce4c,0x0e38
|
||||||
|
.word 0x2a24,0x58ea,0x4939,0xcd00,0xe208,0x860a,0x8bea,0x0c39
|
||||||
|
.word 0xce09,0x0608,0x8e10,0x3449,0x1aa2,0x4e73,0x9d3a,0x4111
|
||||||
|
.word 0xfc45,0x2739,0xcb0c,0xa308,0x0205,0x0fea,0x2939,0xce4d
|
||||||
|
.word 0x2030,0x4823,0xfdc1,0x4739,0xc68c,0x4100,0x4490,0x0c8f
|
||||||
|
.word 0x70cc,0x5473,0x9ce0,0x8a22,0x1866,0x078a,0x4e72,0x6c7b
|
||||||
|
.word 0x0260,0x9e03,0xc148,0x780f,0xc090,0xc970,0x04c5,0x5c06
|
||||||
|
.word 0x45a1,0x641a,0x0e47,0xa1ec,0x7903,0xd03c,0x8310,0x0643
|
||||||
|
.word 0x91e0,0x3926,0x47b1,0xe408,0x3e05,0x9044,0x190e,0x4780
|
||||||
|
.word 0xe49a,0x0c38,0x2c1c,0x390e,0x8100,0x683a,0x2689,0xa0c3
|
||||||
|
.word 0x00d0,0x722d,0x0780,0xc8b4,0x2d8f,0x25d0,0x721c,0x8720
|
||||||
|
.word 0xc872,0x1c8b,0xa5d8,0xb25d,0x0721,0xd032,0x0c87,0x21c8
|
||||||
|
.word 0xb22c,0x8141,0xd872,0x5c86,0x1916,0xc190,0xe43a,0x0e81
|
||||||
|
.word 0x0403,0x2188,0x740d,0x1341,0xc8f6,0x0d8f,0x22d0,0x220c
|
||||||
|
.word 0x8300,0x9032,0x0c97,0x300e,0x49a0,0x6478,0x0645,0x91e8
|
||||||
|
.word 0x1816,0x0190,0x647b,0x1649,0x90e8,0x380e,0x4180,0x645a
|
||||||
|
.word 0x0e83,0x90e4,0x3b1e,0xc981,0x6c79,0x07c5,0xd0f8,0x2939
|
||||||
|
.word 0xc523,0x8946,0x820d,0x0c45,0x070f,0x6192,0xde08,0x3832
|
||||||
|
.word 0x0572,0x083c,0x3920,0x721a,0x9ac8,0x8868,0xf889,0xc160
|
||||||
|
.word 0x4377,0x8a84,0x88ee,0xd891,0xc2b0,0x2200,0xb2a2,0xa1c3
|
||||||
|
.word 0x10dc,0x1564,0x1ce3,0x79c6,0x9022,0x2258,0x1073,0x9ce7
|
||||||
|
.word 0x2a20,0x701c
|
||||||
|
.even
|
||||||
|
.space IMAGE_EXTRA | allow larger image
|
||||||
|
.even
|
||||||
|
#endif
|
||||||
|
imgend1:
|
||||||
|
#endif /* TITLE_IMAGE */
|
||||||
|
|
||||||
|
|
|
||||||
|
| global variables
|
||||||
|
|
|
||||||
|
.comm _ID,4 | SCSI ID
|
||||||
|
.comm _BOOT_INFO,4 | result of IOCS(__BOOTINF)
|
||||||
|
.comm _FDMODE,4 | Floppy access mode: PDA x 256 + MODE
|
||||||
|
.comm _FDSECMINMAX,8 | +0: (min sector) sector length
|
||||||
|
| +1: (min sector) track #
|
||||||
|
| +2: (min sector) side
|
||||||
|
| +3: (min sector) sector #
|
||||||
|
| +4: (max sector) sector length
|
||||||
|
| +5: (max sector) track #
|
||||||
|
| +6: (max sector) side
|
||||||
|
| +7: (max sector) sector #
|
||||||
|
#ifdef SCSI_ADHOC_BOOTPART
|
||||||
|
.comm _SCSI_PARTTOP,4 | top position of boot partition in sector
|
||||||
|
.comm _SCSI_BLKLEN,4 | sector len 0: 256, 1: 512, 2: 1024
|
||||||
|
#endif
|
|
@ -0,0 +1,68 @@
|
||||||
|
/* $NetBSD: xxboot.h,v 1.1 1998/09/01 20:02:35 itohy Exp $ */
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* file: boot.h
|
||||||
|
*
|
||||||
|
* author: chapuni(GBA02750@niftyserve.or.jp)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* xxboot.S */
|
||||||
|
__dead void BOOT_ERROR __P((const char *msg)) __attribute__((noreturn));
|
||||||
|
int badbaddr __P((volatile void *adr));
|
||||||
|
int RAW_READ __P((void *buf, u_int32_t blkpos, size_t bytelen));
|
||||||
|
#ifdef SCSI_ADHOC_BOOTPART
|
||||||
|
int RAW_READ0 __P((void *buf, u_int32_t blkpos, size_t bytelen));
|
||||||
|
#endif
|
||||||
|
unsigned B_KEYINP __P((void));
|
||||||
|
void B_CLR_ST __P((unsigned x));
|
||||||
|
void B_PUTC __P((unsigned c));
|
||||||
|
void B_PRINT __P((const unsigned char *p));
|
||||||
|
unsigned B_COLOR __P((unsigned w));
|
||||||
|
unsigned B_LOCATE __P((int x, int y));
|
||||||
|
#if 0
|
||||||
|
unsigned JISSFT __P((unsigned c));
|
||||||
|
#endif
|
||||||
|
unsigned short B_SFTSNS __P((void));
|
||||||
|
void printtitle __P((void));
|
||||||
|
#if 0
|
||||||
|
int SYS_STAT __P((int flags));
|
||||||
|
int getcpu __P((void));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern unsigned ID; /* target SCSI ID */
|
||||||
|
extern unsigned BOOT_INFO; /* result of IOCS(__BOOTINF) */
|
||||||
|
|
||||||
|
/* check whether the bootinf is SCSI or floppy */
|
||||||
|
#define BINF_ISFD(pbinf) (*((char *)(pbinf) + 1) == 0)
|
||||||
|
|
||||||
|
extern unsigned FDMODE; /* Floppy access mode: PDA x 256 + MODE */
|
||||||
|
extern struct fdfmt{
|
||||||
|
struct {
|
||||||
|
unsigned char N; /* sector length 0: 128, ..., 3: 1K */
|
||||||
|
unsigned char C; /* cylinder # */
|
||||||
|
unsigned char H; /* head # */
|
||||||
|
unsigned char R; /* sector # */
|
||||||
|
} minsec, maxsec;
|
||||||
|
} FDSECMINMAX; /* FD format type of the first track */
|
||||||
|
#ifdef SCSI_ADHOC_BOOTPART
|
||||||
|
extern u_int32_t SCSI_PARTTOP; /* top position of boot partition in sector */
|
||||||
|
extern u_int32_t SCSI_BLKLEN; /* sector len 0: 256, 1: 512, 2: 1024 */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* bootufs.c */
|
||||||
|
int raw_read_queue __P((void *buf, u_int32_t blkpos, size_t len));
|
||||||
|
void get_superblk __P((void));
|
||||||
|
int get_inode __P((ino_t ino, struct dinode *pino));
|
||||||
|
int read_indirect __P((ufs_daddr_t blkno, int level, void **buf, int count));
|
||||||
|
void read_blocks __P((struct dinode *dp, void *buf, int count));
|
||||||
|
ino_t search_file __P((ino_t dirino, const char *filename));
|
||||||
|
unsigned load_ino __P((void *buf, ino_t ino, const char *filename));
|
||||||
|
unsigned load_name __P((void *buf, ino_t dirino, const char *filename));
|
||||||
|
void print_hex __P((unsigned x, int l));
|
||||||
|
void pickup_list __P((ino_t dirino));
|
||||||
|
void print_list __P((int n, int active, unsigned boothowto));
|
||||||
|
volatile void bootufs __P((void));
|
||||||
|
|
||||||
|
/* eof */
|
Loading…
Reference in New Issue