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:
itohy 1998-09-01 20:02:32 +00:00
parent ecc30b1784
commit f9175d6bc7
21 changed files with 4906 additions and 0 deletions

View File

@ -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>

View File

@ -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 キーの押下判定を緩めました。
・読み込み速度を高速にしました。
改悪点は以下の通りです。
・メッセージ「まじかよ?」その他がなくなった。
- 以上 -

View File

@ -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)

View File

@ -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"

View File

@ -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 */

View File

@ -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")

View File

@ -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;
}

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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).

View 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"
};

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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

View File

@ -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*/

View File

@ -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
| bit07 0:68000, 1:68010, 2:68020, 3:68030
| bit14 0:MMU, 1:MMU
| bit15 0:FPCP, 1:FPCP
| bit1631
|
| 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

View File

@ -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 */