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