Merge branch 'develop' into fix_uploads

This commit is contained in:
Daniel Markstedt 2021-09-22 20:45:33 -07:00
commit 991d1232f9
15 changed files with 231 additions and 1276 deletions

View File

@ -1,116 +0,0 @@
------------------------------------------------------------------------------
SCSI Target Emulator RaSCSI for Raspberry Pi
Powered by XM6 TypeG Technology.
Copyright (C) 2016-2020 GIMONS
------------------------------------------------------------------------------
□変換基板の必要性について
SCSIはTTLレベルで5Vを220Ωと330Ωで分圧パッシブターミネータの場合する
ことで各信号線に3V弱の電圧がかかった状態が定常状態信号的にはネゲート)に
なっています。
イニシエータ側もしくはターゲット側が信号をアサートする0Vにしようと
すると両端のターミネータから合わせて5000÷220×2=45mAの電流が流れることに
なりますX68000のSCSIコントローラであるMB89352のデータシートを見ればシンク
電流としてIol48mAとなっています
RPIのGPIOはこのような大きなシンク電流は吸収できません。電気的に安全な接続
を行うためには汎用ロジックIC等で変換基板を作る必要があります。汎用ロジック
ICで48mAものシンク電流に耐えるのは74LS06とか07といったオープンコレクタで
ハイパワータイプのものを使用します。
作者は74HC541×3,74HC126×1,74HC04×1で基本的なSCSIの方向制御を行い更に
74LS07×3を使ってバスをドライブする回路を組んでみたところ問題なく動作する
ことを確認しました。
他にも74LS641の派生版である74LS641-1を使用すると回路はシンプルに構成できる
でしょう。ーマル品と違ってシンク電流が48mA対応なので74LS07を使用する必要
はありません。しかし入手性はそれほど良くありません。
□変換基板の回路図案
同じフォルダに回路図案を入れています。
・target.png
SCSIのターゲットモードを使用するための変換基板回路図です。基本機能である
HDDやMOのエミュレーションを行うのであればこの回路図相当の物を作れば良い
でしょう。使用するGPIOピンも最も少ない構成になります。
ピンアサインを変更しなければRaSCSIのstandardディレクトリに含まれる
バイナリを使用することが可能です。
・fullspec.png
SCSIのターゲットモード、イニシエータモードを利用できる変換基板回路図です。
全ての74LS641-1の方向制御をRaSCSIから行いますのでGPIOピンを三つ余分に使用
してしまいます。
ピンアサインのカスタマイズで、PIN_TAD,PIN_IND,PIN_DTDにそれぞれ標準
では6,7,8を設定してコンパイルする必要があります。ピンアサインの
カスタマイズを参照してください。
□既存のものを手に入れる方法
最近では主にTwitter界隈を通じてRaSCSI用の変換基板を作成していただいて
いる方々がいらっしゃいます。直ぐに見つかると思いますのでここでの紹介
は省略します。時期は未定ですが公式版の有償頒布を計画しています。
□ピンアサインのカスタマイズ
GPIOの信号制御論理やピンアサインはgpiobus.hに定義があります。
カスタマイズ例としてgpiobus.hに下記の二つの変換基板用定義例を用意しました。
配布物の中にはコンパイル済みバイナリも含まれています。
・あいぼむ版
・GAMERnium版
□カスタマイズ方法
・RaSCSI起動時のメッセージです。
CONNECT_DESC
・信号制御モードを選択します。
SIGNAL_CONTROL_MODE
0:SCSI論理仕様
直結またはHPに公開した74LS641-1等を使用する変換基板
アーサート:0V
ネゲート :オープンコレクタ出力(バスから切り離す)
1:負論理仕様(負論理->SCSI論理への変換基板を使用する場合)
現時点でこの仕様による変換基板は存在しません
アーサート:0V -> (CONVERT) -> 0V
ネゲート :3.3V -> (CONVERT) -> オープンコレクタ出力
2:正論理仕様(正論理->SCSI論理への変換基板を使用する場合)
RaSCSI Adapter Rev.C @132sync等
アーサート:3.3V -> (CONVERT) -> 0V
ネゲート :0V -> (CONVERT) -> オープンコレクタ出力
・制御信号ピンアサイン
PIN_ACT:SCSIコマンドを処理中の状態を示す信号のピン番号。
PIN_ENB:起動から終了の間の有効信号を示す信号のピン番号。
PIN_TAD:ターゲット信号(BSY,IO,CD,MSG,REG)の入出力方向を示す信号のピン番号。
PIN_IND:イニシーエータ信号(SEL,ATN,RST,ACK)の入出力方向を示す信号のピン番号。
PIN_DTD:データ信号(DT0...DT7,DP)の入出力方向を示す信号のピン番号。
・制御信号出力論理
0V:FALSE 3.3V:TRUEで指定します。
ACT_ON:PIN_ACT信号の論理です。
ENB_ON:PIN_ENB信号の論理です。
TAD_IN:PIN_TAD入力方向時の論理です。
IND_IN:PIN_ENB入力方向時の論理です。
DTD_IN:PIN_ENB入力方向時の論理です。
・SCSI信号ピンアサイン
PIN_DT0PIN_SEL:それぞれSCSI信号のピン番号です。
□コンパイル方法
・実行ファイル(rascsi,rasctl)
gpiobus.hを修正
make clean
make
[EOF]

View File

@ -1,116 +0,0 @@
-------------------------------------------------- ----------------------------
SCSI Target Emulator RaSCSI for Raspberry Pi
Powered by XM6 TypeG Technology.
Copyright (C) 2016-2020 GIMONS
-------------------------------------------------- ----------------------------
□ Necessity of conversion board
SCSI divides 5V at 220Ω and 330Ω at TTL level (in the case of passive terminator)
As a result, the state where a voltage of less than 3 V is applied to each signal line becomes a steady state (signal-wise negate)
It has become.
Initiator side or target side tries to assert signal (=0V)
Then, a total current of 5000÷220×2=45mA flows from both terminators.
If you look at the data sheet of MB89352 which is the SCSI controller of X68000,
The current is Iol48mA).
The RPI GPIO cannot absorb such a large sink current. Electrically secure connection
To do this, it is necessary to make a conversion board with a general-purpose logic IC. General logic
It is an open collector such as 74LS06 or 07 that can withstand a sink current of 48 mA with IC.
Use the high power type.
The author does basic SCSI direction control with 74HC541×3,74HC126×1,74HC04×1
I tried to build a circuit to drive the bus using 74LS07 × 3 and it works without problems
I confirmed that.
If you use 74LS641-1 which is a derivative of 74LS641, you can configure the circuit simply.
Would be Unlike normal products, the sink current is compatible with 48 mA, so it is necessary to use 74LS07
there is no. But availability is not so good.
□ Circuit board of conversion board
The circuit design is put in the same folder.
・Target.png
Conversion board circuit diagram for using SCSI target mode. It is a basic function
If you want to emulate HDD or MO, you can make something equivalent to this circuit diagram.
Would be It also uses the fewest GPIO pins.
If you do not change the pin assignment, it will be included in the standard directory of RaSCSI
It is possible to use the binary.
・Fullspec.png
It is a conversion board circuit diagram that can use SCSI target mode and initiator mode.
All 74LS641-1 direction control is performed from RaSCSI, so use 3 extra GPIO pins
I will do it.
Customize pin assignments to PIN_TAD, PIN_IND, PIN_DTD respectively
Now you need to set 6,7,8 and compile. Pin assigned
See Customization.
□ How to get existing ones
Recently, you have created a conversion board for RaSCSI mainly through the Twitter area.
There are people who are. Introducing here
Is omitted. The timing is undecided, but we plan to distribute the official version for a fee.
□ Customize pin assignment
The signal control logic and pin assignment of GPIO are defined in gpiobus.h.
As a customization example, the following two conversion board definition examples are prepared in gpiobus.h.
Compiled binaries are also included in the distribution.
・Aibomu version
・GAMERnium version
□ How to customize
-This is a message when starting up RaSCSI.
CONNECT_DESC
・Select the signal control mode.
SIGNAL_CONTROL_MODE
0: SCSI logical specification
Conversion board using 74LS641-1 etc. directly connected or published on HP
Arthurt: 0V
Negative: Open collector output (disconnect from bus)
1: Negative logic specification (when using the conversion board for negative logic -> SCSI logic)
There are no conversion boards with this specification at this time
Arthurt: 0V -> (CONVERT) -> 0V
Negative: 3.3V -> (CONVERT) -> Open collector output
2: Positive logic specification (when using the conversion board for positive logic -> SCSI logic)
RaSCSI Adapter Rev.C @132sync etc.
Arthurt: 3.3V -> (CONVERT) -> 0V
Negative: 0V -> (CONVERT) -> Open collector output
・Control signal pin assignment
PIN_ACT: The pin number of the signal that indicates the status that the SCSI command is being processed.
PIN_ENB: Pin number of the signal that indicates the valid signal from start to finish.
PIN_TAD: Pin number of the signal that indicates the input/output direction of the target signal (BSY,IO,CD,MSG,REG).
PIN_IND: Pin number of the signal indicating the input/output direction of the initiator signal (SEL, ATN, RST, ACK).
PIN_DTD: Pin number of the signal that indicates the input/output direction of the data signal (DT0...DT7,DP).
・Control signal output logic
0V:FALSE Specify with 3.3V:TRUE.
ACT_ON: PIN_ACT signal logic.
ENB_ON: Logic of PIN_ENB signal.
TAD_IN:PIN_TAD This is the logic in the input direction.
IND_IN:PIN_ENB Logic in the input direction.
DTD_IN:PIN_ENB Logic in the input direction.
・ SCSI signal pin assignment
PIN_DT0 to PIN_SEL: Each is the pin number of the SCSI signal.
□ How to compile
・Executable files (rascsi, rasctl)
Fix gpiobus.h
make clean
make
[EOF]

View File

@ -3,8 +3,8 @@
rascsi \- Emulates SCSI devices using the Raspberry Pi GPIO pins rascsi \- Emulates SCSI devices using the Raspberry Pi GPIO pins
.SH SYNOPSIS .SH SYNOPSIS
.B rascsi .B rascsi
[\fB\-f\f® \fIFOLDER\fR] [\fB\-F\f® \fIFOLDER\fR]
[\fB\-g\f® \fILOG_LEVEL\fR] [\fB\-L\f® \fILOG_LEVEL\fR]
[\fB\-h\fR] [\fB\-h\fR]
[\fB\-n\fR \fIVENDOR:PRODUCT:REVISION\fR] [\fB\-n\fR \fIVENDOR:PRODUCT:REVISION\fR]
[\fB\-p\f® \fIPORT\fR] [\fB\-p\f® \fIPORT\fR]
@ -46,10 +46,10 @@ To quit RaSCSI, press Control + C. If it is running in the background, you can k
.BR \-b\fI " " \fIBLOCK_SIZE .BR \-b\fI " " \fIBLOCK_SIZE
The optional block size. For SCSI drives 512, 1024, 2048 or 4096 bytes, default size is 512 bytes. For SASI drives 256 or 1024 bytes, default is 256 bytes. The optional block size. For SCSI drives 512, 1024, 2048 or 4096 bytes, default size is 512 bytes. For SASI drives 256 or 1024 bytes, default is 256 bytes.
.TP .TP
.BR \-f\fI " " \fIFOLDER .BR \-F\fI " " \fIFOLDER
The default folder for image files. For files in this folder no absolute path needs to be specified. The initial default folder is '~/images'. The default folder for image files. For files in this folder no absolute path needs to be specified. The initial default folder is '~/images'.
.TP .TP
.BR \-g\fI " " \fILOG_LEVEL .BR \-L\fI " " \fILOG_LEVEL
The rascsi log level (trace, debug, info, warn, err, critical, off). The default log level is 'info'. The rascsi log level (trace, debug, info, warn, err, critical, off). The default log level is 'info'.
.TP .TP
.BR \-h\fI " " \fI .BR \-h\fI " " \fI

View File

@ -1,335 +0,0 @@
------------------------------------------------------------------------------
SCSI Target Emulator RaSCSI (*^..^*)
for Raspberry Pi
Powered by XM6 TypeG Technology.
Copyright (C) 2016-2020 GIMONS
------------------------------------------------------------------------------
□RaSCSIとは
RaSCSIはRaspberry Piで動作するSCSIデバイス(ハードディスクMOCD-ROM)を
仮想的に再現するエミュレータです。SCSIを採用したSHARPのX68000で使用する
ことを目的として開発しました。RaSCSIを導入したRaspberry PiをX68000のSCSI
コネクタに接続するだけで物理的なSCSIデバイスとして認識されます。
X68000以外にもSCSIを採用したFM TOWNSやPC98等のレトロPCでも使用できるかも
しれません。作者はFM TOWNSとPC9821Ceで動作するところまでは確認しています。
RaSCSIはSCSIデバイスをエミュレートするソフトウェアに加えてRaspberry Piの
GPIOコネクタをSCSIコネクタに変換する機構の総称を指します。
□動作環境
(1)Raspberry Pi
Raspberry Pi Zero
Raspberry Pi Zero W
Raspberry Pi Zero WH
Raspberry Pi 2 Model B
Raspberry Pi 3 Model B(推奨)
Raspberry Pi 3 Model A+
Raspberry Pi 3 Model B+
Raspberry Pi 4 Model B
Zero/Zero W/Zero WHでは性能的に少し不安定かもしれません。
3 Model A+/3 Model B+/4 Model Bは高性能ですが熱の影響でCPUクロックが
変動することがありますので対策が必要でしょう。
(2)OS
RASPBIAN BUSTERで開発およびテストしています。
RaSCSIはSCSI信号をGPIOを利用して制御しているので可能な限り低レイテンシー
の状態で使用する必要があります。したがってCUIモードで利用することを推奨
します。
□SCSIコネクタとの接続方法
状況が複雑になってきましたのでRaSCSIのホームページ上で情報提供しています。
このドキュメントの最後にある公式ホームページを参考にして下さい。
□配布物
配布するアーカイブには実行ファイル、ドキュメント、ソースコードのそれぞれが
ディレクトリで分かれて含まれています。
bin/ ・・・ 実行ファイル
raspberrypi/ ・・・ RPI用のプログラム
rascsi.tar.gz ・・・ 実行ファイルをtar+gzipしたもの。
x68k/ ・・・ X68000用の専用ドライバ
RASDRIVER.XDF・・・ 二つのドライバを含むフロッピーイメージ
RASDRIVER.HDS・・・ 二つのドライバを含むSCSI HDイメージ
RASDRIVER.HDF・・・ 二つのドライバを含むSASI HDイメージ
doc/ ・・・ ドキュメント
rascsi.txt ・・・ 当ドキュメント
x68k.txt ・・・ X68000固有機能の説明
converter.txt ・・・ 変換基板の説明
pinassign.png ・・・ ピンアサイン図
target.png ・・・ 変換基板回路図案(ターゲットモード)
fullspec.png ・・・ 変換基板回路図案(フルスペック)
src/ ・・・ ソースコード
raspberrypi/ ・・・ RPI用のプログラムソース一式
x68k/ ・・・ X68000用のプログラム一式
RPIで使用するプログラムはrascsi.tar.gzですのでRPI上に転送してから解凍して
下さい。パーミッション等を維持するためにRPI上で解凍することを推奨します。
rascsi.tar.gzにはstandard,fullspec,aibom,gamerniumのディレクトリが含まれ
ています。
直結ケーブルや直結基板を使用する場合はstandardディレクトリの実行ファイル
を使用して下さい。
同様にフルスペック版と説明された変換基板の場合はfullspecのディレクトリの
ものを使用します(直結でも動くと思います)。
aibom,gamerniumディレクトリのものは"あいぼむ版","GAMERnium版"の変換基板を
使用する時のものです。
X68000用のドライバはRASDRIVER.XDFもしくはRASDRIVER.HDSの中に次の二つが含ま
れています。
RASDRV.SYS ・・・ ホストドライブドライバ
RASETHER.SYS ・・・ イーサネットドライバ
□RASCI本体の使用方法(rascsi)
ID指定の場合
rascsi [-IDn FILE] ...
n:07
HD指定の場合(X68000 SASI機のHD指定互換)
rascsi [-HDn FILE] ...
n:015
ルート権限が必要ですのでsudo等で起動する必要があります。
オプションに-hを付けると簡単なHELPが表示されます
Usage: rascsi [-IDn FILE] ...
n is SCSI identification number(0-7).
FILE is disk image file.
Usage: rascsi [-HDn FILE] ...
n is X68000 SASI HD number(0-15).
FILE is disk image file.
Image type is detected based on file extension.
hdf : SASI HD image(XM6 SASI HD image)
hds : SCSI HD image(XM6 SCSI HD image)
hdn : SCSI HD image(NEC GENUINE)
hdi : SCSI HD image(Anex86 HD image)
nhd : SCSI HD image(T98Next HD image)
hda : SCSI HD image(APPLE GENUINE)
mos : SCSI MO image(XM6 SCSI MO image)
iso : SCSI CD image(ISO 9660 image)
引数では-IDnもしくは-HDnとFILEの一組で一つのSCSI(SASI)デバイスを指定できます。
-IDの後ろの番号はSCSI(SASI) IDです。IDは0-7を指定できますが通常レトロPC本体
がイニシエータとしてID7等を使用していると思います。その場合は0-6を指定する
ことになります。
FILEは仮想ディスクイメージのファイルパスです。イメージファイル名には拡張子
が必要です。拡張子によってHD,MO,CDの種別を判定しています。
例)SCSI ID0にHDIMAGE0.HDS,ID1にHDIMAGE1.HDSを指定して起動する場合、
sudo rascsi -ID0 HDIMAGE0.HDS -ID1 HDIMAGE1.HDS
終了する場合はCTRL+Cで停止します。
バックグラウンドで起動した場合にはkillコマンド該当プロセスにINTシグナルか
HUPシグナルを送ることで終了します。
rascsiは起動後にソケット(6868ポート)を開いて外部からの管理コマンドを受け
付ける状態になります。したがって既に別プロセスとしてrascsiが起動している
場合はエラーメッセージとともに起動を中断します。
□管理ツールの使用方法(rasctl)
バージョン1.10からrasctlという管理ツールを提供します。これはrascsiプロセス
がバックグラウンドで起動(6868ポートで接続待ちの状態)している場合にディスク
操作のコマンドを発行することが可能となります。コマンドラインは下記の通り。
rasctl -i ID [-u UNIT] [-c CMD] [-t TYPE] [-f FILE]
ID : SCSI ID(07)
UNIT : ユニット番号(0または1)
CMD : 操作コマンド
attach : ディスクを取り付ける
detach : ディスクを取り外す
insert : メディアを挿入する(MOまたはCDのみ)
eject : メディアを取り出す(MOまたはCDのみ)
protect : メディアを書き込み禁止にする(MOのみ)
TYPE : ディスク種別
hd : ハードディスク(SASI/SCSI)
mo : MO(光磁気ディスク)
cd : CDROM(CDROMドライブ)
bridge : ブリッジデバイス
FILE : ディスクイメージファイルのパス
IDは必須です。UNITは省略時は0です(SCSIの場合は0を基本とします)。
CMDは省略時はattachと解釈します。TYPEはコマンドがattachの場合にはFILEの拡張子
から自動判定します。FILEはTYPEを明示的に指定している場合は拡張子が異なっても
構いません。基本的CMD,TYPEの解釈は大文字小文字を無視します。最初の1文字でのみ
判定しています。
コマンド例
rasctl -i 0 -f HDIMAGE0.HDS
の場合はSCSI IDは0。CMDはデフォルトでattachでありTYPEは拡張子HDSから判断
するのでhdと推測することになりrascsi起動時のオプション指定と同等です。
現在の状態を確認するにために-lオプションのみを指定するとデバイス一覧が表示
されます。コマンドラインは下記の通り。
rasctl -l
rasctl自体の起動にはルート権限は必要ありません。
□ディスクダンプツールの使用方法(rasdump)
直結もしくは直結基板、またはフルスペック基板向けのサンプルプログラムです。
名前の通りSCSI HDDやMOのイメージをダンプ(オプションでリストア)します。
自身のIDはBIDで指定して下さい。省略時は7を使用します。
rasdump -i ID [-b BID] -f FILE [-r]
ID : ターゲットデバイスのSCSI ID
BID : RaSCSI自身のSCSI ID
FILE : ダンプファイル名
-r リストアモード
サンプルなので必要最低限の処理しか実装していませんので改造するなりして
ご使用下さい。
□SASI専用ディスクダンプツールの使用方法(sasidump)
rasdumpをベースにSASI専用に作成したダンプツールです。
SASI HDイメージをダンプ(オプションでリストア)します。
sasidump -i ID [-u UT] [-b BSIZE] -c COUNT -f FILE [-r]
ID : ターゲットデバイスのSASI ID
UT : ターゲットデバイスのUNIT ID
BSIZE: ブロックサイズ(デフォルトは512)
COUNT: ブロック数
FILE : ダンプファイル名
-r リストアモード
□ソースから実行ファイルをコンパイルする場合
スタンダード版
make CONNECT_TYPE=STANDARD
フルスペック版
make CONNECT_TYPE=FULLSPEC
あいぼむ版
make CONNECT_TYPE=AIBOM
GAMERnium版
make CONNECT_TYPE=GAMERNIUM
□サポートするディスクイメージ
(1)SCSI ハードディスク
HDSファイル形式 (拡張子HDS/HDN/HDI/NHD/HDA)
ファイルサイズは10MB以上4095MB以下の範囲で任意のサイズ(但し512バイト単位)
拡張子が"HDN"の場合はNEC純正55ボード(PC-9801-55)向けの純正ハードディスク
エミュレーションを行います。INQUIRYで返却される情報やMODE SENSEのサイズに
に違いがあります。
拡張子が"HDI","NHD"の場合はそれぞれPC98エミュレータであるAnex86及びT98Next
のSCSIハードディスクイメージを使用するものです。HDNの時と同様に一部の情報
がNEC用に変換されます。
拡張子が"HDA"の場合はAPPLE純正ハードディスクエミュレーションを行います。
INQUIRY及びMODE SENSEで返却される情報に違いがあります。
(2)SASI ハードディスク
HDFファイル形式 (拡張子HDF)
ファイルサイズは10441728バイト、20748288バイト、41496576バイトのいずれか
(それぞれ10MBドライブ、20MBドライブ、40MBドライブに対応)を推奨します。
256バイト単位であれば10M512Mの任意のファイルサイズがマウント可能です。
Version1.46から22437888バイトのイメージはMZ-2500/MZ-2800 MZ-1F23専用の
20MBイメージとして認識します(ブロックサイズが1024という特殊イメージ)。
(3)SCSI 光磁気(MO)ディスク
MOSファイル形式 (拡張子MOS)
ファイルサイズは次の4種類のいずれか
128MBタイプ (127398912バイト)
230MBタイプ (228518400バイト)
540MBタイプ (533248000バイト)
640MBタイプ (635600896バイト)
128MB,230MB,540MBは512バイト/セクタ、640MBは2048バイト/セクタになります。
(4)SCSI CD-ROMディスク
ISOファイル形式 (拡張子ISO、ISO9660ベタイメージ)
モード1(2048バイト/セクタ)で、データのみ格納されたファイルとRAW形式で記録
されたファイルの両方に対応しています。
□ディスクイメージの作成
RaSCSI自体がX68000エミュレータであるXM6 TypeGの派生物です。従ってディスク
イメージの作成はXM6 TypeGの「ツール」メニューから行うことを前提としています。
もちろん先に説明した仕様に従えばdd等で空のイメージファイルを作成することも
可能です。
100MBのHDSイメージ(空ファイル)を作る場合
dd if=/dev/zero of=HARDDISK.HDS bs=512 count=204800
□動作実績
作者の開発環境であるX68000 PRO(内蔵SASI/純正SCSIボード)、X68030 内蔵SCSI、
XVI Compact 内蔵SCSIで動作確認しています。Mach-2でも動作しました。
他にも初代X68000,ACE,EXPERT,XVI,PRO2,SUPER等で動作報告がありましたので、
X68000シリーズはほぼ問題ないでしょう。
その他のレトロPCではFM TOWNSシリーズ、Apple Macintosh、MSX(MEGA-SCSI利用)
で動作報告があります。PC98シリーズは動作したという報告も多数ありますが、
SCSIボードによっては全く動作しないという報告もあります。
□活用方法
 XM6等のX68000エミュレータを使用している場合はエミュレータで環境構築したHDD
イメージをFTP等でRaspberry Piに転送することでX68000の実機に接続できます。
またその逆も然りで実機上に存在するファイルを格納したHDDイメージをPCにFTP等
で転送することでエミュレータで活用することができます。
□ライセンス
RaSCSIはあるがまま"AS IS"で配布されるソフトウェアです。
つまり使用者が受けたあらゆる損害に対して一切責任を持ちません。またソフト
ウェアに不備もしくは不具合があったとしてもそれを修正する責任もありません。
RaSCSIを利用することでRaspberry PiやレトロPCが故障するリスクがあります。
あくまで自己責任でチャレンジしてください。
XM6 TypeG同様に実験成果公開という性質上私のHP以外での配布を認めておりません。
XM6のライセンス条項を継承していますので雑誌/書籍での紹介事前の許諾が必要です。
そもそも2019年にもなってSCSIに反応するのは限られた人だけだと思います。
□変換基板の頒布について
変換基板を有償で頒布する場合は下記の条件に従う限り作者に許諾を得る必要は
ありません。重要なことは基板を購入したユーザーに十分な情報を提供することと
心得て下さい。
1.頒布価格
基板製作費 パーツ費用 運送費 +(社会通念上一般的な)手数料。
2.回路図
購入者に回路図を提供して下さい。基板頒布と同時もしくは別途ホームページから
のダウンロード等手段は自由です。
3.動作検証
X68000実機環境の動作検証は必須とします。実機が手に入らない場合はX68000
ユーザーの方に検証の協力をお願いしてもよいでしょう。動作検証は起動確認以外
に書き込みや負荷テストをお願いします。検証結果は使用した環境やと共に公開
して下さい。
□変換基板(公式版)について
BOOTHで2019年3月以降配布しています(数に限りがありますので不定期です)。
□公開ホームページ
http://retropc.net/gimons/rascsi/
□連絡先
twitter https://twitter.com/kugimoto0715
e-mail gimons.developer.works@gmail.com
[EOF]

View File

@ -1,335 +0,0 @@
-------------------------------------------------- ----------------------------
SCSI Target Emulator RaSCSI (*^..^*)
for Raspberry Pi
Powered by XM6 TypeG Technology.
Copyright (C) 2016-2020 GIMONS
-------------------------------------------------- ----------------------------
□ What is RaSCSI
RaSCSI is a SCSI device (hard disk, MO, CD-ROM) that operates on the Raspberry Pi.
It is a virtual emulator. Use with SHARP X68000 that adopts SCSI
It was developed for that purpose. Raspberry Pi with RaSCSI installed on the X68000 SCSI
Simply connect it to the connector and it will be recognized as a physical SCSI device.
In addition to the X68000, it may be possible to use it with a retro PC such as FM TOWNS or PC 98 that adopted SCSI.
May. The author has confirmed that it works with FM TOWNS and PC9821Ce.
RaSCSI is a software that emulates SCSI devices plus Raspberry Pi
Refers to the general term for the mechanism that converts a GPIO connector into a SCSI connector.
□ Operating environment
(1) Raspberry Pi
Raspberry Pi Zero
Raspberry Pi Zero W
Raspberry Pi Zero WH
Raspberry Pi 2 Model B
Raspberry Pi 3 Model B (recommended)
Raspberry Pi 3 Model A+
Raspberry Pi 3 Model B+
Raspberry Pi 4 Model B
Performance may be a little unstable with Zero/Zero W/Zero WH.
3 Model A+/3 Model B+/4 Model B has high performance, but CPU clock is affected by heat.
It may fluctuate, so it will be necessary to take measures.
(2) OS
Developed and tested by RASPBIAN BUSTER.
RaSCSI uses GPIO to control SCSI signals, so latency is as low as possible.
Must be used in the state of. Therefore, it is recommended to use it in CUI mode.
To do.
□ Connection method with SCSI connector
Since the situation has become complicated, we provide information on the RaSCSI home page.
Please refer to the official website at the end of this document.
□ Handout
The executable file, the document, and the source code are stored in the distributed archive.
It is divided and included in the directory.
bin/ ・・・ Executable file
raspberrypi/ ・・・ RPI program
rascsi.tar.gz ・・・ The tar+gzip of the executable file.
x68k/ ・・・ Dedicated driver for X68000
RASDRIVER.XDF... A floppy image containing two drivers
RASDRIVER.HDS... A SCSI HD image containing two drivers
RASDRIVER.HDF... SASI HD image containing two drivers
doc/ ・・・Documents
rascsi.txt ・・・ This document
x68k.txt ・・・ Description of X68000 specific functions
converter.txt ・・・ Description of converter board
pinassign.png ・・・ Pin assignment diagram
target.png ・・・ Conversion board circuit pattern (target mode)
fullspec.png ・・・Conversion board circuit pattern (full spec)
src/ ・・・ Source code
raspberrypi/ ・・・ Set of program source for RPI
x68k/ ・・・ Set of programs for X68000
The program used in RPI is rascsi.tar.gz, so transfer it to RPI and decompress it.
Please. It is recommended to unzip on RPI to maintain permissions etc.
rascsi.tar.gz contains standard, fullspec, aibom and gamernium directories.
I am.
Executable file in the standard directory when using a direct connection cable or direct connection board
Please use.
Similarly, in the case of the conversion board described as the full spec version, in the fullspec directory
I will use one (I think that it works even if it is directly connected).
For the aibom and gamernium directories, use the conversion boards of "Aibomu version" and "GAMERnium version".
It is when using.
The driver for X68000 includes the following two in RASDRIVER.XDF or RASDRIVER.HDS
It is
RASDRV.SYS ・・・ Host drive driver
RASETHER.SYS ・・・ Ethernet driver
□ How to use RASCI main unit (rascsi)
When ID is specified
rascsi [-IDn FILE] ...
n:0 ~ 7
When specifying HD (compatible with HD specification of X68000 SASI machine)
rascsi [-HDn FILE] ...
n: 0 ~ 15
Since root authority is required, it is necessary to start with sudo etc.
If you add -h to the option, a simple HELP will be displayed
Usage: rascsi [-IDn FILE] ...
n is SCSI identification number(0-7).
FILE is disk image file.
Usage: rascsi [-HDn FILE] ...
n is X68000 SASI HD number(0-15).
FILE is disk image file.
Image type is detected based on file extension.
hdf: SASI HD image(XM6 SASI HD image)
hds: SCSI HD image(XM6 SCSI HD image)
hdn: SCSI HD image (NEC GENUINE)
hdi: SCSI HD image(Anex86 HD image)
nhd: SCSI HD image(T98Next HD image)
hda: SCSI HD image(APPLE GENUINE)
mos: SCSI MO image(XM6 SCSI MO image)
iso: SCSI CD image (ISO 9660 image)
In the argument, one SCSI (SASI) device can be specified by a pair of -IDn or -HDn and FILE.
-The number after the ID is the SCSI (SASI) ID. You can specify 0-7 as the ID, but usually the retro PC body
I think you are using ID7 etc. as the initiator. In that case, specify 0-6
It will be.
FILE is the file path of the virtual disk image. The image file name has an extension
Is required. The type of HD, MO, CD is determined by the extension.
Example) When you specify HDIMAGE0.HDS for SCSI ID0 and HDIMAGE1.HDS for ID1 and start up,
sudo rascsi -ID0 HDIMAGE0.HDS -ID1 HDIMAGE1.HDS
When you finish, press CTRL+C to stop.
If it is started in the background, is the kill command an INT signal to the relevant process?
It ends by sending a HUP signal.
After starting, rascsi opens a socket (6868 port) and receives external management commands.
It is ready to be attached. Therefore, rascsi has already started as another process.
If so, the boot will abort with an error message.
□ How to use the management tool (rasctl)
We provide a management tool called rasctl from version 1.10. This is the rascsi process
Disk is running in the background (waiting for connection on port 6868)
It is possible to issue operation commands. The command line is as follows.
rasctl -i ID [-u UNIT] [-c CMD] [-t TYPE] [-f FILE]
ID: SCSI ID (0 to 7)
UNIT: Unit number (0 or 1)
CMD: Operation command
attach: attach disk
detach: detach disk
insert: insert media (MO or CD only)
eject: Eject media (MO or CD only)
protect: Write protect the media (MO only)
TYPE: Disc type
hd: Hard disk (SASI/SCSI)
mo: MO (magneto-optical disk)
cd: CDROM (CDROM drive)
bridge: Bridge device
FILE: Path of disk image file
ID is required. UNIT defaults to 0 (default is 0 for SCSI).
CMD is interpreted as attach when omitted. TYPE is the extension of FILE when the command is attach
It will automatically judge from. FILE has a different extension if TYPE is explicitly specified.
does not matter. Basic interpretation of CMD and TYPE is case insensitive. Only the first letter
Judging.
Command example
rasctl -i 0 -f HDIMAGE0.HDS
Is 0, the SCSI ID is 0. CMD is attach by default and TYPE is determined from the extension HDS
Therefore, it is supposed to be hd and it is equivalent to the option specification when starting rascsi.
If only -l option is specified to check the current status, the device list is displayed.
Will be done. The command line is as follows.
rasctl -l
You do not need root privileges to start rasctl itself.
□ How to use Disk Dump Tool (rasdump)
Sample program for direct connection or direct connection board, or full-spec board.
As the name suggests, it dumps (optionally restores) the image of SCSI HDD or MO.
Specify your own ID as BID. If omitted, 7 is used.
rasdump -i ID [-b BID] -f FILE [-r]
ID: SCSI ID of the target device
BID: RaSCSI's own SCSI ID
FILE: dump file name
-r: Restore mode
Since it is a sample, only the minimum necessary processing is implemented, so do not modify it
Please use.
□ How to use SASI dedicated disk dump tool (sasidump)
A dump tool created for SASI based on rasdump.
Dump (optionally restore) the SASI HD image.
sasidump -i ID [-u UT] [-b BSIZE] -c COUNT -f FILE [-r]
ID: SASI ID of the target device
UT: UNIT ID of the target device
BSIZE: Block size (default 512)
COUNT: Number of blocks
FILE: dump file name
-r: Restore mode
□ When compiling the executable file from the source
Standard edition
make CONNECT_TYPE=STANDARD
Full spec version
make CONNECT_TYPE=FULLSPEC
Aibomu version
make CONNECT_TYPE=AIBOM
GAMERnium version
make CONNECT_TYPE=GAMERNIUM
□ Supported disk images
(1) SCSI hard disk
HDS file format (extension HDS/HDN/HDI/NHD/HDA)
The file size can be any size within the range of 10MB to 4095MB (in 512-byte units)
If the extension is "HDN", a genuine hard disk for NEC genuine 55 board (PC-9801-55)
Perform emulation. For information returned by INQUIRY and MODE SENSE size
There is a difference.
If the extension is "HDI" or "NHD", the PC98 emulator is Annex86 or T98Next.
It is intended to use a SCSI hard disk image. Some information as in HDN
Is converted for NEC.
If the extension is "HDA", APPLE genuine hard disk emulation is performed.
There is a difference in the information returned by INQUIRY and MODE SENSE.
(2) SASI hard disk
HDF file format (extension HDF)
File size is either 10441728 bytes, 20748288 bytes, or 41496576 bytes
We recommend 10MB drive, 20MB drive and 40MB drive respectively.
Any file size from 10M to 512M can be mounted in 256-byte units.
Images from version 1.46 to 22437888 bytes are for MZ-2500/MZ-2800 MZ-1F23
Recognized as a 20MB image (special image with a block size of 1024).
(3) SCSI magneto-optical (MO) disk
MOS file format (extension MOS)
File size is one of the following four types:
128MB type (127398912 bytes)
230MB type (228518400 bytes)
540MB type (533248000 bytes)
640MB type (635600896 bytes)
128MB, 230MB, 540MB is 512 bytes/sector and 640MB is 2048 bytes/sector.
(4) SCSI CD-ROM disk
ISO file format (extension ISO, ISO9660 solid image)
Record in a file containing only data and in RAW format in mode 1 (2048 bytes/sector)
Both files are supported.
□ Disk image creation
RaSCSI itself is a derivative of the XM6 TypeG, an X68000 emulator. Therefore the disc
It is assumed that the image is created from the "Tools" menu of XM6 TypeG.
Of course, you can also create an empty image file with dd etc. according to the specifications explained above.
Is possible.
Example) When creating a 100 MB HDS image (empty file)
dd if=/dev/zero of=HARDDISK.HDS bs=512 count=204800
□ Operation record
The author's development environment X68000 PRO (built-in SASI/genuine SCSI board), X68030 built-in SCSI,
We have confirmed the operation with the XVI Compact built-in SCSI. It also worked on Mach-2.
Since there were other operation reports on the first generation X68000, ACE, EXPERT, XVI, PRO2, SUPER, etc.,
The X68000 series should be fine.
For other retro PCs, FM TOWNS series, Apple Macintosh, MSX (using MEGA-SCSI)
There is an operation report in. There are many reports that the PC98 series worked, but
Some SCSI boards do not even work at all.
□ How to use
 If you are using an X68000 emulator such as XM6, HDD that is built by the emulator
You can connect to the actual X68000 machine by transferring the image to the Raspberry Pi by FTP etc.
The reverse is also true, and the HDD image that stores the files that exist on the actual machine is FTPed to the PC, etc.
You can use it in the emulator by transferring with.
□ License
RaSCSI is software distributed as is "AS IS".
That is, we do not take any responsibility for any damages that the user receives. Soft again
We are not responsible for fixing any defects or defects in the software.
There is a risk that the Raspberry Pi and retro PC will break down by using RaSCSI.
Please challenge at your own risk.
As with XM6 TypeG, we are not allowed to distribute it on other than my HP due to the nature of experimental results disclosure.
As it inherits the license terms of XM6, introduction in magazines/books requires prior permission.
In the first place, I think only a limited number of people will respond to SCSI in 2019.
□About distribution of conversion boards
If you want to distribute the conversion board for a fee, it is not necessary to obtain permission from the author as long as you follow the conditions below.
There is none. It is important to provide enough information to the user who purchased the board.
Please understand.
1.Distribution price
Board production cost + parts cost + transportation cost + (general social convention) fee.
2. Schematic
Please provide the buyer with the schematic. Simultaneously with board distribution or separately from homepage
There are no restrictions on the means of downloading.
3. Operation verification
Operation verification of the X68000 actual machine environment is mandatory. If you can not get the real machine X68000
You may ask the user to cooperate with the verification. Operation verification is other than startup confirmation
Please write and load test. Verification results are published together with the environment in which they were used
please do it.
□ About conversion board (official version)
It has been distributed on BOOTH since March 2019 (it is irregular because the number is limited).
□ Public homepage
http://retropc.net/gimons/rascsi/
□ Contact information
twitter https://twitter.com/kugimoto0715
e-mail gimons.developer.works@gmail.com
[EOF]

View File

@ -1,97 +1,129 @@
!! ------ THIS FILE IS AUTO_GENERATED! DO NOT MANUALLY UPDATE!!! !! ------ THIS FILE IS AUTO_GENERATED! DO NOT MANUALLY UPDATE!!!
!! ------ The native file is rascsi.1. Re-run 'make docs' after updating !! ------ The native file is rascsi.1. Re-run 'make docs' after updating\n\n
rascsi(1) General Commands Manual rascsi(1)
rascsi(1) General Commands Manual rascsi(1)
NAME NAME
rascsi - Emulates SCSI devices using the Raspberry Pi GPIO pins rascsi - Emulates SCSI devices using the Raspberry Pi GPIO pins
SYNOPSIS SYNOPSIS
rascsi [-f[u00AE] FOLDER] [-g[u00AE] LOG_LEVEL] [-h] [-n VENDOR:PRODUCT:REVISION] [-p[u00AE] PORT] [-r RESERVED_IDS] [-n TYPE] [-v] [-IDn FILE] [-HDn FILE]... rascsi [-F[u00AE] FOLDER] [-L[u00AE] LOG_LEVEL] [-h] [-n VENDOR:PROD
UCT:REVISION] [-p[u00AE] PORT] [-r RESERVED_IDS] [-n TYPE] [-v] [-IDn
FILE] [-HDn FILE]...
DESCRIPTION DESCRIPTION
rascsi Emulates SCSI devices using the Raspberry Pi GPIO pins. rascsi Emulates SCSI devices using the Raspberry Pi GPIO pins.
In the arguments to RaSCSI, one or more SCSI (-IDn) or SASI (-HDn) devices can be specified. The number (n) after the ID or HD identifier specifies the ID number for that device. In the arguments to RaSCSI, one or more SCSI (-IDn) or SASI (-HDn) de
For SCSI: The ID is limited from 0-7. However, typically SCSI ID 7 is reserved for the "initiator" (the host computer). Note that SASI is considered rare and only used on very vices can be specified. The number (n) after the ID or HD identifier
early Sharp X68000 computers. specifies the ID number for that device. For SCSI: The ID is limited
from 0-7. However, typically SCSI ID 7 is reserved for the "initiator"
(the host computer). Note that SASI is considered rare and only used on
very early Sharp X68000 computers.
RaSCSI will determine the type of device based upon the file extension of the FILE argument. RaSCSI will determine the type of device based upon the file extension
hdf: SASI Hard Disk image (XM6 SASI HD image - typically only used with X68000) of the FILE argument.
hdf: SASI Hard Disk image (XM6 SASI HD image - typically only used
with X68000)
hds: SCSI Hard Disk image (generic, non-removable) hds: SCSI Hard Disk image (generic, non-removable)
hdr: SCSI Hard Disk image (generic, removable) hdr: SCSI Hard Disk image (generic, removable)
hdn: SCSI Hard Disk image (NEC GENUINE) hdn: SCSI Hard Disk image (NEC GENUINE)
hdi: SCSI Hard Disk image (Anex86 HD image) hdi: SCSI Hard Disk image (Anex86 HD image)
nhd: SCSI Hard Disk image (T98Next HD image) nhd: SCSI Hard Disk image (T98Next HD image)
hda: SCSI Hard Disk image (APPLE GENUINE - typically used with Mac SCSI emulation) hda: SCSI Hard Disk image (APPLE GENUINE - typically used with Mac
mos: SCSI Magneto-optical image (XM6 SCSI MO image - typically only used with X68000) SCSI emulation)
mos: SCSI Magneto-optical image (XM6 SCSI MO image - typically only
used with X68000)
iso: SCSI CD-ROM image (ISO 9660 image) iso: SCSI CD-ROM image (ISO 9660 image)
For example, if you want to specify an Apple-compatible HD image on ID 0, you can use the following command: For example, if you want to specify an Apple-compatible HD image on ID
0, you can use the following command:
sudo rascsi -ID0 /path/to/drive/hdimage.hda sudo rascsi -ID0 /path/to/drive/hdimage.hda
Once RaSCSI starts, it will open a socket (default port is 6868) to allow external management commands. If another process is using the rascsi port, RaSCSI will terminate, since Once RaSCSI starts, it will open a socket (default port is 6868) to al
it is likely another instance of RaSCSI. Once RaSCSI has initialized, the rasctl utility can be used to send commands. low external management commands. If another process is using the
rascsi port, RaSCSI will terminate, since it is likely another instance
of RaSCSI. Once RaSCSI has initialized, the rasctl utility can be used
to send commands.
To quit RaSCSI, press Control + C. If it is running in the background, you can kill it using an INT signal. To quit RaSCSI, press Control + C. If it is running in the background,
you can kill it using an INT signal.
OPTIONS OPTIONS
-b BLOCK_SIZE -b BLOCK_SIZE
The optional block size. For SCSI drives 512, 1024, 2048 or 4096 bytes, default size is 512 bytes. For SASI drives 256 or 1024 bytes, default is 256 bytes. The optional block size. For SCSI drives 512, 1024, 2048 or 4096
bytes, default size is 512 bytes. For SASI drives 256 or 1024
bytes, default is 256 bytes.
-f FOLDER -F FOLDER
The default folder for image files. For files in this folder no absolute path needs to be specified. The initial default folder is '~/images'. The default folder for image files. For files in this folder no
absolute path needs to be specified. The initial default folder
is '~/images'.
-g LOG_LEVEL -L LOG_LEVEL
The rascsi log level (trace, debug, info, warn, err, critical, off). The default log level is 'info'. The rascsi log level (trace, debug, info, warn, err, critical,
off). The default log level is 'info'.
-h Show a help page. -h Show a help page.
-n VENDOR:PRODUCT:REVISION -n VENDOR:PRODUCT:REVISION
Set the vendor, product and revision for the device, to be returned with the INQUIRY data. A complete set of name components must be provided. VENDOR may have up to 8, Set the vendor, product and revision for the device, to be re
PRODUCT up to 16, REVISION up to 4 characters. Padding with blanks to the maxium length is automatically applied. Once set the name of a device cannot be changed. turned with the INQUIRY data. A complete set of name components
must be provided. VENDOR may have up to 8, PRODUCT up to 16, RE
VISION up to 4 characters. Padding with blanks to the maxium
length is automatically applied. Once set the name of a device
cannot be changed.
-p PORT -p PORT
The rascsi server port, default is 6868. The rascsi server port, default is 6868.
-r RESERVED_IDS -r RESERVED_IDS
Comma-separated list of IDs to reserve. -p TYPE The optional case-insensitive device type (SAHD, SCHD, SCRM, SCCD, SCMO, SCBR, SCDP). If no type is specified for devices Comma-separated list of IDs to reserve. -p TYPE The optional
that support an image file, rascsi tries to derive the type from the file extension. case-insensitive device type (SAHD, SCHD, SCRM, SCCD, SCMO,
SCBR, SCDP). If no type is specified for devices that support an
image file, rascsi tries to derive the type from the file exten
sion.
-v Display the rascsi version. -v Display the rascsi version.
-IDn FILE -IDn FILE
n is the SCSI ID number (0-7) n is the SCSI ID number (0-7)
FILE is the name of the image file to use for the SCSI device. For devices that do not support an image file (SCBR, SCDP) a dummy name must be provided. FILE is the name of the image file to use for the SCSI device.
For devices that do not support an image file (SCBR, SCDP) a
dummy name must be provided.
-HDn FILE -HDn FILE
n is the SASI ID number (0-15) n is the SASI ID number (0-15)
FILE is the name of the image file to use for the SASI device. FILE is the name of the image file to use for the SASI device.
Note: SASI usage is rare, and is typically limited to early Unix workstations and Sharp X68000 systems. Note: SASI usage is rare, and is typically limited to early Unix
workstations and Sharp X68000 systems.
EXAMPLES EXAMPLES
Launch RaSCSI with no emulated drives attached: Launch RaSCSI with no emulated drives attached:
rascsi rascsi
Launch RaSCSI with an Apple hard drive image as ID 0 and a CD-ROM as ID 2 Launch RaSCSI with an Apple hard drive image as ID 0 and a CD-ROM as ID
2
rascsi -ID0 /path/to/harddrive.hda -ID2 /path/to/cdimage.iso rascsi -ID0 /path/to/harddrive.hda -ID2 /path/to/cdimage.iso
Launch RaSCSI with a removable SCSI drive image as ID 0 and the raw device file /dev/hdb (e.g. a USB stick) and a DaynaPort network adapter as ID 6: Launch RaSCSI with a removable SCSI drive image as ID 0 and the raw de
vice file /dev/hdb (e.g. a USB stick) and a DaynaPort network adapter
as ID 6:
rascsi -ID0 -t scrm /dev/hdb -ID6 -t scdp DUMMY_FILENAME rascsi -ID0 -t scrm /dev/hdb -ID6 -t scdp DUMMY_FILENAME
To create an empty, 100MB HD image, use the following command: To create an empty, 100MB HD image, use the following command:
dd if=/dev/zero of=/path/to/newimage.hda bs=512 count=204800 dd if=/dev/zero of=/path/to/newimage.hda bs=512 count=204800
In case the fallocate command is available a much faster alternative to the dd command is: In case the fallocate command is available a much faster alternative to
the dd command is:
fallocate -l 104857600 /path/to/newimage.hda fallocate -l 104857600 /path/to/newimage.hda
SEE ALSO SEE ALSO
rasctl(1), scsimon(1) rasctl(1), scsimon(1)
Full documentation is available at: <https://www.github.com/akuker/RASCSI/wiki/> Full documentation is available at:
<https://www.github.com/akuker/RASCSI/wiki/>
rascsi(1) rascsi(1)

View File

@ -3,12 +3,16 @@
rasctl \- Sends management commands to the rascsi process rasctl \- Sends management commands to the rascsi process
.SH SYNOPSIS .SH SYNOPSIS
.B rasctl .B rasctl
\fB\-L\fR |
\fB\-e\fR | \fB\-e\fR |
\fB\-k\fR | \fB\-k\fR |
\fB\-l\fR | \fB\-l\fR |
\fB\-s\fR | \fB\-s\fR |
\fB\-y\fR | \fB\-T\fR |
[\fB\-d\fR \fIIMAGE_FOLDER\fR] [\fB\-F\fR \fIIMAGE_FOLDER\fR]
[\fB\-C\fR \fIFILENAME:FILESIZE\fR]
[\fB\-x\fR \fICURRENT_NAME:NEW_NAME\fR]
[\fB\-R\fR \fICURRENT_NAME:NEW_NAME\fR]
[\fB\-g\fR \fILOG_LEVEL\fR] [\fB\-g\fR \fILOG_LEVEL\fR]
[\fB\-h\fR \fIHOST\fR] [\fB\-h\fR \fIHOST\fR]
[\fB\-p\fR \fIPORT\fR] [\fB\-p\fR \fIPORT\fR]
@ -32,13 +36,13 @@ Note: The command and type arguments are case insensitive. Only the first letter
.SH OPTIONS .SH OPTIONS
.TP .TP
.BR \-a\fI " "\fIFILENAME:FILESIZE .BR \-C\fI " "\fIFILENAME:FILESIZE
Create an image file in the default image folder with the specified name and size in bytes. Create an image file in the default image folder with the specified name and size in bytes.
.TP .TP
.BR \-d\fI " "\fIIMAGE_FOLDER .BR \-F\fI " "\fIIMAGE_FOLDER
Set the default image folder. Set the default image folder.
.TP .TP
.BR \-g\fI " "\fILOG_LEVEL .BR \-L\fI " "\fILOG_LEVEL
Set the rascsi log level (trace, debug, info, warn, err, critical, off). Set the rascsi log level (trace, debug, info, warn, err, critical, off).
.TP .TP
.BR \-h\fI " " \fIHOST .BR \-h\fI " " \fIHOST
@ -47,13 +51,13 @@ The rascsi host to connect to, default is 'localhost'.
.BR \-e\fI .BR \-e\fI
List all images files in the default image folder. List all images files in the default image folder.
.TP .TP
.BR \-k\fI .BR \-N\fI
Lists all available network interfaces provided that they are up. Lists all available network interfaces provided that they are up.
.TP .TP
.BR \-l\fI .BR \-l\fI
List all of the devices that are currently being emulated by RaSCSI, as well as their current status. List all of the devices that are currently being emulated by RaSCSI, as well as their current status.
.TP .TP
.BR \-m\fI " "\fICURRENT_NAME:NEW_NAME .BR \-R\fI " "\fICURRENT_NAME:NEW_NAME
Rename an image file in the default image folder. Rename an image file in the default image folder.
.TP .TP
.BR \-p\fI " " \fIPORT .BR \-p\fI " " \fIPORT
@ -65,13 +69,13 @@ Comma-separated list of IDs to reserve.
.BR \-s\fI .BR \-s\fI
Display server-side settings like available images or supported device types. Display server-side settings like available images or supported device types.
.TP .TP
.BR \-y\fI .BR \-T\fI
Display all device types and their properties. Display all device types and their properties.
.TP .TP
.BR \-v\fI " " \fI .BR \-v\fI " " \fI
Display the rascsi version. Display the rascsi version.
.TP .TP
.BR \-w\fI " "\fIFILENAME .BR \-D\fI " "\fIFILENAME
Delete an image file in the default image folder. Delete an image file in the default image folder.
.TP .TP
.BR \-x\fI " "\fICURRENT_NAME:NEW_NAME .BR \-x\fI " "\fICURRENT_NAME:NEW_NAME

View File

@ -6,31 +6,32 @@ NAME
rasctl - Sends management commands to the rascsi process rasctl - Sends management commands to the rascsi process
SYNOPSIS SYNOPSIS
rasctl -e | -k | -l | -s | -y | [-d IMAGE_FOLDER] [-g LOG_LEVEL] [-h rasctl -L | -e | -k | -l | -s | -T | [-F IMAGE_FOLDER] [-C FILE
HOST] [-p PORT] [-r RESERVED_IDS] [-v] -i ID [-c CMD] [-f FILE|PARAM] NAME:FILESIZE] [-x CURRENT_NAME:NEW_NAME] [-R CURRENT_NAME:NEW_NAME]
[-n NAME] [-t TYPE] [-u UNIT] [-g LOG_LEVEL] [-h HOST] [-p PORT] [-r RESERVED_IDS] [-v] -i ID [-c
CMD] [-f FILE|PARAM] [-n NAME] [-t TYPE] [-u UNIT]
DESCRIPTION DESCRIPTION
rasctl Sends commands to the rascsi process to make configuration ad rasctl Sends commands to the rascsi process to make configuration ad
justments at runtime or to check the status of the devices. justments at runtime or to check the status of the devices.
Either the -i or -l option should be specified at one time. Not both. Either the -i or -l option should be specified at one time. Not both.
You do NOT need root privileges to use rasctl. You do NOT need root privileges to use rasctl.
Note: The command and type arguments are case insensitive. Only the Note: The command and type arguments are case insensitive. Only the
first letter of the command/type is evaluated by the tool. first letter of the command/type is evaluated by the tool.
OPTIONS OPTIONS
-a FILENAME:FILESIZE -C FILENAME:FILESIZE
Create an image file in the default image folder with the speci Create an image file in the default image folder with the speci
fied name and size in bytes. fied name and size in bytes.
-d IMAGE_FOLDER -F IMAGE_FOLDER
Set the default image folder. Set the default image folder.
-g LOG_LEVEL -L LOG_LEVEL
Set the rascsi log level (trace, debug, info, warn, err, criti Set the rascsi log level (trace, debug, info, warn, err, criti
cal, off). cal, off).
-h HOST -h HOST
@ -38,13 +39,13 @@ OPTIONS
-e List all images files in the default image folder. -e List all images files in the default image folder.
-k Lists all available network interfaces provided that they are -N Lists all available network interfaces provided that they are
up. up.
-l List all of the devices that are currently being emulated by -l List all of the devices that are currently being emulated by
RaSCSI, as well as their current status. RaSCSI, as well as their current status.
-m CURRENT_NAME:NEW_NAME -R CURRENT_NAME:NEW_NAME
Rename an image file in the default image folder. Rename an image file in the default image folder.
-p PORT -p PORT
@ -53,14 +54,14 @@ OPTIONS
-r RESERVED_IDS -r RESERVED_IDS
Comma-separated list of IDs to reserve. Comma-separated list of IDs to reserve.
-s Display server-side settings like available images or supported -s Display server-side settings like available images or supported
device types. device types.
-y Display all device types and their properties. -T Display all device types and their properties.
-v Display the rascsi version. -v Display the rascsi version.
-w FILENAME -D FILENAME
Delete an image file in the default image folder. Delete an image file in the default image folder.
-x CURRENT_NAME:NEW_NAME -x CURRENT_NAME:NEW_NAME
@ -73,7 +74,7 @@ OPTIONS
d(etach): Detach disk d(etach): Detach disk
i(nsert): Insert media (removable media devices only) i(nsert): Insert media (removable media devices only)
e(ject): Eject media (removable media devices only) e(ject): Eject media (removable media devices only)
p(rotect): Write protect the medium (not for CD-ROMs, which p(rotect): Write protect the medium (not for CD-ROMs, which
are always read-only) are always read-only)
u(nprotect): Remove write protection from the medium (not for u(nprotect): Remove write protection from the medium (not for
CD-ROMs, which are always read-only) CD-ROMs, which are always read-only)
@ -83,18 +84,18 @@ OPTIONS
-b BLOCK_SIZE -b BLOCK_SIZE
The optional block size. For SCSI drives 512, 1024, 2048 or 4096 The optional block size. For SCSI drives 512, 1024, 2048 or 4096
bytes, default size is 512 bytes. For SASI drives 256 or 1024 bytes, default size is 512 bytes. For SASI drives 256 or 1024
bytes, default is 256 bytes. bytes, default is 256 bytes.
-f FILE|PARAM -f FILE|PARAM
Device-specific: Either a path to a disk image file, or a param Device-specific: Either a path to a disk image file, or a param
eter for a non-disk device. See the rascsi(1) man page for per eter for a non-disk device. See the rascsi(1) man page for per
mitted file types. mitted file types.
-t TYPE -t TYPE
Specifies the device type. This type overrides the type derived Specifies the device type. This type overrides the type derived
from the file extension of the specified image. See the from the file extension of the specified image. See the
rascsi(1) man page for the available device types. For some rascsi(1) man page for the available device types. For some
types there are shortcuts (only the first letter is required): types there are shortcuts (only the first letter is required):
hd: SCSI hard disk drive hd: SCSI hard disk drive
rm: SCSI removable media drive rm: SCSI removable media drive
@ -104,16 +105,16 @@ OPTIONS
daynaport: DaynaPORT network adapter daynaport: DaynaPORT network adapter
-n VENDOR:PRODUCT:REVISION -n VENDOR:PRODUCT:REVISION
The vendor, product and revision for the device, to be returned The vendor, product and revision for the device, to be returned
with the INQUIRY data. A complete set of name components must be with the INQUIRY data. A complete set of name components must be
provided. VENDOR may have up to 8, PRODUCT up to 16, REVISION up provided. VENDOR may have up to 8, PRODUCT up to 16, REVISION up
to 4 characters. Padding with blanks to the maxium length is au to 4 characters. Padding with blanks to the maxium length is au
tomatically applied. Once set the name of a device cannot be tomatically applied. Once set the name of a device cannot be
changed. changed.
-u UNIT -u UNIT
Unit number (0 or 1). This will default to 0. This option is Unit number (0 or 1). This will default to 0. This option is
only used when there are multiple SCSI devices on a shared SCSI only used when there are multiple SCSI devices on a shared SCSI
controller. (This is not common) controller. (This is not common)
EXAMPLES EXAMPLES

View File

@ -1,114 +0,0 @@
------------------------------------------------------------------------------
SCSI Target Emulator RaSCSII (*^..^*)
for Raspberry Pi
Powered by XM6 TypeG Technology.
Copyright (C) 2016-2020 GIMONS
------------------------------------------------------------------------------
□X68000固有の機能について
RaSCSIにはブリッジデバイスという仮想的なSCSIデバイスが実装されておりX68000と
ホストであるRaspberry Piの橋渡しを行うことができます。このブリッジデバイスと
X68000用の専用ドライバを使用して下記の機能を提供します。
・イーサーネット
Neptune-Xと同様のイーサーネット機能を提供します。SCSI接続のイーサーネット
BOXのようにRaSCSIが振舞います。Raspberry PiのTAPデバイスにパケットを中継
することで実現しています。Ether+と似たものです。
・ホストファイルシステム
X68000のエミュレーターでは標準的な機能であるWindrv相当の機能を提供します。
Raspberry Pi上のファイルシステムをリモートドライブとしてマウントすること
ができます。
□ブジッジデバイスの起動方法
RaSCSI起動時にファイル名として"BRIDGE"というキーワードを設定するとそのIDに
対してブジッリデバイスを生成します。
ex)
sudo rascsi -ID0 HDIMAGE0.HDS -ID6 BRIDGE
□専用ドライバ
配布物に含まれるRASDRIVER.XDFもしくはRASDRIVER.HDSに二つのドライバが含まれ
ています。RaSCSIでRASDRIVER.HDSをマウントし適宜コピーした方が実機への転送が
簡単でしょう。
□イーサーネット接続
イーサネットドライバ(RASETHER.SYS)がブリッジデバイスと連携してイーサーネット
のパケット送受信を行うことができます。
以下、Raspberry Piの仮想アダプタ(TAP)のIPアドレスを「192.168.68.1」として、
X68000側を「192.168.68.3」とするケースで説明します。
・X68000の設定
RASETHER.SYSはNeptune-X用ドライバを改造して作ったものですので使用方法は
全く同じです。X68000をネット接続するためには他に環境設定を行う必要があり
ます。設定方法は自力で調べていただくようお願いします。
以下実際に使用しているCONFIG.SYSとAUTOEXEC.BATの抜粋です。
[CONFIG.SYS抜粋]
PROCESS = 3 10 10
DEVICE = \NETWORK\RASETHER.SYS
[AUTOEXEC.BAT抜粋]
SET SYSROOT=A:/NETWORK/
SET temp=A:\
SET tmp=A:\
SET HOME=A:/NETWORK/ETC/
SET HOST=X68000
XIP.X
IFCONFIG.X lp0 up
IFCONFIG.X en0 192.168.68.3 netmask 255.255.255.0 up
INETDCONF.X +router 192.168.68.1 -rip
INETDCONF.X
・Raspberry Piの設定
TAPデバイスというものを利用していますのでTAPを有効にしてください。恐らく
最近のJessieであれば最初から有効なはずです。確認方法は/dev/net/tunという
ファイルが存在すれば有効となっていると判断できます。
仮想アダプタの作成方法は次の様に行います。
[/etc/rc.local等から設定]
ip tuntap add ras0 mode tap user root
ip link set ras0 up
ifconfig ras0 inet 192.168.68.1/8 up
route add -net 192.168.68.0 netmask 255.255.255.0 dev ras0
上記によってRaspberry Pi(192.168.68.1)とX68000(192.168.68.3)の間で通信が
可能になります。
インターネット等と接続する場合はRaspberry Pi側でブリッジやルーティングの
設定が必要になります。ご自身の環境に合わせて設定してください。無線LANの
場合にブリッジ構成するには色々と課題があるようなのでフォワーディングと
NAT構成等もお勧めです。作者はrc.localで次のような設定で使用しています。
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
□ホストファイルシステム連携
X68000エミュレータでよく利用されるWindrvやWindrvXMと同等の機能を提供します。
専用のRASDRV.SYSというデバイスドライバを組み込めばRaspberri Piのファイル
システムがX68000側のドライブに見えて操作できるということです。
デバイスドライバの登録は簡単です。
例えば
DEVICE = \SYS\RASDRV.SYS
この場合はデフォルトでRaspberry Piのルートディレクトリをマウントします。
デバイスドライバ起動時にどのドライブにマウントされたか表示されます。
ルートを以外をマウントする場合はディレクトリを指定して下さい。/home/pi等を
マウントするには
DEVICE = \SYS\RASDRV.SYS /home/pi
と指定します。複数のディレクトリを指定すれば別々のドライブとしてマウントする
ことが可能です。
SUSIEをご利用の方はSUSIEより先にRASDRV.SYSを組み込んで下さい。後に組み込むと
正しく認識できなくなると報告があります。
[EOF]

View File

@ -1,114 +0,0 @@
-------------------------------------------------- ----------------------------
SCSI Target Emulator RaSCSII (*^..^*)
for Raspberry Pi
Powered by XM6 TypeG Technology.
Copyright (C) 2016-2020 GIMONS
-------------------------------------------------- ----------------------------
□ Regarding the functions unique to the X68000
RaSCSI is equipped with a virtual SCSI device called a bridge device,
You can bridge the host Raspberry Pi. With this bridge device
The following functions are provided by using the dedicated driver for X68000.
・Ethernet
It provides the same Ethernet function as Neptune-X. SCSI-connected Ethernet
RaSCSI behaves like a BOX. Relay packets to the Raspberry Pi TAP device
It is realized by doing. Similar to Ether+.
・Host file system
The emulator of X68000 provides a standard function equivalent to Windrv.
Mount the file system on the Raspberry Pi as a remote drive
I can.
□ How to activate the Bridge Device
If you set the keyword "BRIDGE" as the file name when RaSCSI starts up, it will be assigned to that ID.
Generate a Buzzilli device for it.
ex)
sudo rascsi -ID0 HDIMAGE0.HDS -ID6 BRIDGE
□ Dedicated driver
Two drivers are included in RASDRIVER.XDF or RASDRIVER.HDS included in the distribution
I am. It is better to mount RASDRIVER.HDS with RaSCSI and copy it appropriately to transfer to the actual device
It will be easy.
□ Ethernet connection
Ethernet driver (RASETHER.SYS) works with bridge device to connect to Ethernet
You can send and receive packets.
Below, the IP address of the virtual adapter (TAP) of Raspberry Pi is "192.168.68.1",
The case where the X68000 side is set to "192.168.68.3" will be explained.
-X68000 settings
RASETHER.SYS is made by modifying the driver for Neptune-X.
Exactly the same. In order to connect the X68000 to the internet, it is necessary to set other environment settings.
I will. Please check the setting method by yourself.
Below is an excerpt of CONFIG.SYS and AUTOEXEC.BAT that are actually used.
[Excerpt from CONFIG.SYS]
PROCESS = 3 10 10
DEVICE = \NETWORK\RASETHER.SYS
[Excerpt from AUTOEXEC.BAT]
SET SYSROOT=A:/NETWORK/
SET temp=A:\
SET tmp=A:\
SET HOME=A:/NETWORK/ETC/
SET HOST=X68000
XIP.X
IFCONFIG.X lp0 up
IFCONFIG.X en0 192.168.68.3 netmask 255.255.255.0 up
INETDCONF.X +router 192.168.68.1 -rip
INETDCONF.X
・Raspberry Pi settings
I am using a TAP device, so please enable TAP. perhaps
If you're using Jessie these days, it should work from the beginning. The confirmation method is /dev/net/tun
If the file exists, it can be determined that it is valid.
The method of creating a virtual adapter is as follows.
[Set from /etc/rc.local etc.]
ip tuntap add ras0 mode tap user root
ip link set ras0 up
ifconfig ras0 inet 192.168.68.1/8 up
route add -net 192.168.68.0 netmask 255.255.255.0 dev ras0
By the above, communication between Raspberry Pi (192.168.68.1) and X68000 (192.168.68.3)
It will be possible.
When connecting to the Internet etc., bridge and routing on the Raspberry Pi side
Settings are required. Please set according to your environment. Wifi
In this case, there seem to be various problems in constructing a bridge.
NAT configuration is also recommended. The author uses it in rc.local with the following settings.
echo 1 >/proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
□ Host file system cooperation
It provides the same functions as Windrv and WindrvXM that are often used in the X68000 emulator.
Raspberri Pi files if you include a dedicated device driver called RASDRV.SYS
It means that the system can be seen and operated as a drive on the X68000 side.
Registering a device driver is easy.
For example
DEVICE = \SYS\RASDRV.SYS
In this case, mount the root directory of Raspberry Pi by default.
The drive mounted when the device driver is started is displayed.
If you want to mount other than root, please specify the directory. /home/pi etc.
To mount
DEVICE = \SYS\RASDRV.SYS /home/pi
Specify. If you specify multiple directories, they will be mounted as separate drives.
It is possible.
If you are using SUSIE, please install RASDRV.SYS before SUSIE. When incorporated later
There are reports that it can not be recognized correctly.
[EOF]

View File

@ -26,8 +26,8 @@ else
CXXFLAGS += -O3 -Wall -Werror -DNDEBUG CXXFLAGS += -O3 -Wall -Werror -DNDEBUG
BUILD_TYPE = Release BUILD_TYPE = Release
endif endif
CFLAGS += -iquote . -MD -MP CFLAGS += -iquote . -D_FILE_OFFSET_BITS=64 -MD -MP
CXXFLAGS += -std=c++17 -Wno-psabi -iquote . -MD -MP CXXFLAGS += -std=c++17 -Wno-psabi -iquote . -D_FILE_OFFSET_BITS=64 -MD -MP
## EXTRA_FLAGS : Can be used to pass special purpose flags ## EXTRA_FLAGS : Can be used to pass special purpose flags
CFLAGS += $(EXTRA_FLAGS) CFLAGS += $(EXTRA_FLAGS)

View File

@ -72,8 +72,11 @@ DeviceFactory& DeviceFactory::instance()
return instance; return instance;
} }
Device *DeviceFactory::CreateDevice(PbDeviceType type, const string& filename, const string& ext) Device *DeviceFactory::CreateDevice(PbDeviceType type, const string& filename, const string& extension)
{ {
string ext = extension;
std::transform(ext.begin(), ext.end(), ext.begin(), [](unsigned char c){ return std::tolower(c); });
// If no type was specified try to derive the device type from the filename and extension // If no type was specified try to derive the device type from the filename and extension
if (type == UNDEFINED) { if (type == UNDEFINED) {
if (ext == "hdf") { if (ext == "hdf") {

View File

@ -32,6 +32,7 @@
#include "spdlog/sinks/stdout_color_sinks.h" #include "spdlog/sinks/stdout_color_sinks.h"
#include <spdlog/async.h> #include <spdlog/async.h>
#include <sys/sendfile.h> #include <sys/sendfile.h>
#include <dirent.h>
#include <ifaddrs.h> #include <ifaddrs.h>
#include <string> #include <string>
#include <sstream> #include <sstream>
@ -117,7 +118,6 @@ void Banner(int argc, char* argv[])
FPRT(stdout," hdn : SCSI HD image (NEC GENUINE)\n"); FPRT(stdout," hdn : SCSI HD image (NEC GENUINE)\n");
FPRT(stdout," hdi : SCSI HD image (Anex86 HD image)\n"); FPRT(stdout," hdi : SCSI HD image (Anex86 HD image)\n");
FPRT(stdout," nhd : SCSI HD image (T98Next HD image)\n"); FPRT(stdout," nhd : SCSI HD image (T98Next HD image)\n");
FPRT(stdout," hda : SCSI HD image (APPLE GENUINE)\n");
FPRT(stdout," mos : SCSI MO image (MO image)\n"); FPRT(stdout," mos : SCSI MO image (MO image)\n");
FPRT(stdout," iso : SCSI CD image (ISO 9660 image)\n"); FPRT(stdout," iso : SCSI CD image (ISO 9660 image)\n");
@ -527,6 +527,45 @@ void GetAllDeviceTypeProperties(PbDeviceTypesInfo& device_types_info)
GetDeviceTypeProperties(device_types_info, SCDP); GetDeviceTypeProperties(device_types_info, SCDP);
} }
void GetAvailableImages(PbImageFilesInfo& image_files_info)
{
image_files_info.set_default_image_folder(default_image_folder);
// filesystem::directory_iterator cannot be used because libstdc++ 8.3.0 does not support big files
DIR *d = opendir(default_image_folder.c_str());
if (d) {
struct dirent *dir;
while ((dir = readdir(d))) {
if (dir->d_type == DT_REG || dir->d_type == DT_LNK || dir->d_type == DT_BLK) {
string filename = default_image_folder + "/" + dir->d_name;
struct stat st;
if (dir->d_type == DT_REG && !stat(filename.c_str(), &st)) {
if (!st.st_size) {
LOGTRACE("File '%s' in image folder '%s' has a size of 0 bytes", dir->d_name,
default_image_folder.c_str());
continue;
}
if (st.st_size % 512) {
LOGTRACE("Size of file '%s' in image folder '%s' is not a multiple of 512", dir->d_name,
default_image_folder.c_str());
continue;
}
} else if (dir->d_type == DT_LNK && stat(filename.c_str(), &st)) {
LOGTRACE("Symlink '%s' in image folder '%s' is broken", dir->d_name,
default_image_folder.c_str());
continue;
}
GetImageFile(image_files_info.add_image_files(), dir->d_name);
}
}
closedir(d);
}
}
void GetAvailableImages(PbServerInfo& server_info) void GetAvailableImages(PbServerInfo& server_info)
{ {
PbImageFilesInfo *image_files_info = new PbImageFilesInfo(); PbImageFilesInfo *image_files_info = new PbImageFilesInfo();
@ -534,26 +573,7 @@ void GetAvailableImages(PbServerInfo& server_info)
image_files_info->set_default_image_folder(default_image_folder); image_files_info->set_default_image_folder(default_image_folder);
if (!access(default_image_folder.c_str(), F_OK)) { GetAvailableImages(*image_files_info);
for (const auto& entry : filesystem::directory_iterator(default_image_folder, filesystem::directory_options::skip_permission_denied)) {
if (entry.is_regular_file() && entry.file_size() && !(entry.file_size() & 0x1ff)) {
GetImageFile(image_files_info->add_image_files(), entry.path().filename());
}
}
}
}
void GetAvailableImages(PbImageFilesInfo& image_files_info)
{
image_files_info.set_default_image_folder(default_image_folder);
if (!access(default_image_folder.c_str(), F_OK)) {
for (const auto& entry : filesystem::directory_iterator(default_image_folder, filesystem::directory_options::skip_permission_denied)) {
if (entry.is_regular_file() && entry.file_size() && !(entry.file_size() & 0x1ff)) {
GetImageFile(image_files_info.add_image_files(), entry.path().filename());
}
}
}
} }
void GetNetworkInterfacesInfo(PbNetworkInterfacesInfo& network_interfaces_info) void GetNetworkInterfacesInfo(PbNetworkInterfacesInfo& network_interfaces_info)
@ -687,7 +707,13 @@ bool SetDefaultImageFolder(const string& f)
// If a relative path is specified the path is assumed to be relative to the user's home directory // If a relative path is specified the path is assumed to be relative to the user's home directory
if (folder[0] != '/') { if (folder[0] != '/') {
const passwd *passwd = getpwuid(getuid()); int uid = getuid();
const char *sudo_user = getenv("SUDO_UID");
if (sudo_user) {
uid = stoi(sudo_user);
}
const passwd *passwd = getpwuid(uid);
if (passwd) { if (passwd) {
folder = passwd->pw_dir; folder = passwd->pw_dir;
folder += "/"; folder += "/";
@ -742,7 +768,7 @@ string SetReservedIds(const string& ids)
s << id; s << id;
} }
LOGINFO("Reserved IDs set to: %s", s.str().c_str()); LOGINFO("Reserved ID(s) set to %s", s.str().c_str());
} }
else { else {
LOGINFO("Cleared reserved IDs"); LOGINFO("Cleared reserved IDs");
@ -864,7 +890,7 @@ bool DeleteImage(int fd, const PbCommand& command)
return ReturnStatus(fd, false, "Can't delete image file '" + filename + "': " + string(strerror(errno))); return ReturnStatus(fd, false, "Can't delete image file '" + filename + "': " + string(strerror(errno)));
} }
LOGINFO("%s", string("Deleted image file '" + filename + "'").c_str()); LOGINFO("Deleted image file '%s'", filename.c_str());
return ReturnStatus(fd); return ReturnStatus(fd);
} }
@ -908,7 +934,7 @@ bool RenameImage(int fd, const PbCommand& command)
return ReturnStatus(fd, false, "Can't rename image file '" + from + "' to '" + to + "': " + string(strerror(errno))); return ReturnStatus(fd, false, "Can't rename image file '" + from + "' to '" + to + "': " + string(strerror(errno)));
} }
LOGINFO("%s", string("Renamed image file '" + from + "' to '" + to + "'").c_str()); LOGINFO("Renamed image file '%s' to '%s'", from.c_str(), to.c_str());
return ReturnStatus(fd); return ReturnStatus(fd);
} }
@ -943,24 +969,35 @@ bool CopyImage(int fd, const PbCommand& command)
from = default_image_folder + "/" + from; from = default_image_folder + "/" + from;
to = default_image_folder + "/" + to; to = default_image_folder + "/" + to;
struct stat st; struct stat st_dst;
if (!stat(to.c_str(), &st)) { if (!stat(to.c_str(), &st_dst)) {
return ReturnStatus(fd, false, "Image file '" + to + "' already exists"); return ReturnStatus(fd, false, "Image file '" + to + "' already exists");
} }
struct stat st_src;
if (lstat(from.c_str(), &st_src)) {
return ReturnStatus(fd, false, "Can't access source image file '" + from + "': " + string(strerror(errno)));
}
// Symbolic links need a special handling
if ((st_src.st_mode & S_IFMT) == S_IFLNK) {
if (symlink(filesystem::read_symlink(from).c_str(), to.c_str())) {
return ReturnStatus(fd, false, "Can't copy symlink '" + from + "': " + string(strerror(errno)));
}
LOGINFO("Copied symlink '%s' to '%s'", from.c_str(), to.c_str());
return ReturnStatus(fd);
}
int fd_src = open(from.c_str(), O_RDONLY, 0); int fd_src = open(from.c_str(), O_RDONLY, 0);
if (fd_src == -1) { if (fd_src == -1) {
return ReturnStatus(fd, false, "Can't open source image file '" + from + "': " + string(strerror(errno))); return ReturnStatus(fd, false, "Can't open source image file '" + from + "': " + string(strerror(errno)));
} }
struct stat st_src;
if (fstat(fd_src, &st_src) == -1) {
return ReturnStatus(fd, false, "Can't read source image file '" + from + "': " + string(strerror(errno)));
}
int fd_dst = open(to.c_str(), O_WRONLY | O_CREAT, st_src.st_mode); int fd_dst = open(to.c_str(), O_WRONLY | O_CREAT, st_src.st_mode);
if (fd_dst == -1) { if (fd_dst == -1) {
close (fd_dst); close(fd_src);
return ReturnStatus(fd, false, "Can't open destination image file '" + to + "': " + string(strerror(errno))); return ReturnStatus(fd, false, "Can't open destination image file '" + to + "': " + string(strerror(errno)));
} }
@ -975,7 +1012,7 @@ bool CopyImage(int fd, const PbCommand& command)
close(fd_dst); close(fd_dst);
close(fd_src); close(fd_src);
LOGINFO("%s", string("Copied image file '" + from + "' to '" + to + "'").c_str()); LOGINFO("Copied image file '%s' to '%s'", from.c_str(), to.c_str());
return ReturnStatus(fd); return ReturnStatus(fd);
} }
@ -1008,10 +1045,10 @@ bool SetImagePermissions(int fd, const PbCommand& command)
} }
if (protect) { if (protect) {
LOGINFO("%s", string("Protected image file '" + filename + "'").c_str()); LOGINFO("Protected image file '%s'", filename.c_str());
} }
else { else {
LOGINFO("%s", string("Unprotected image file '" + filename + "'").c_str()); LOGINFO("Unprotected image file '%s'", filename.c_str());
} }
return ReturnStatus(fd); return ReturnStatus(fd);
@ -1532,29 +1569,25 @@ bool ParseArgument(int argc, char* argv[], int& port)
opterr = 1; opterr = 1;
int opt; int opt;
while ((opt = getopt(argc, argv, "-IiHhG:g:D:d:B:b:N:n:T:t:P:p:R:r:F:f:")) != -1) { while ((opt = getopt(argc, argv, "-IiHhb:d:n:p:r:t:D:F:L:")) != -1) {
switch (tolower(opt)) { switch (opt) {
// The three options below are kind of a compound option with two letters
case 'i': case 'i':
case 'I':
is_sasi = false; is_sasi = false;
max_id = 7; max_id = 7;
id = -1; id = -1;
continue; continue;
case 'h': case 'h':
case 'H':
is_sasi = true; is_sasi = true;
max_id = 15; max_id = 15;
id = -1; id = -1;
continue; continue;
case 'b': { case 'd':
if (!GetAsInt(optarg, block_size)) { case 'D': {
cerr << "Invalid block size " << optarg << endl;
return false;
}
continue;
}
case 'd': {
char* end; char* end;
id = strtol(optarg, &end, 10); id = strtol(optarg, &end, 10);
if (*end || id < 0 || max_id < id) { if (*end || id < 0 || max_id < id) {
@ -1564,14 +1597,22 @@ bool ParseArgument(int argc, char* argv[], int& port)
continue; continue;
} }
case 'f': case 'b': {
if (!GetAsInt(optarg, block_size)) {
cerr << "Invalid block size " << optarg << endl;
return false;
}
continue;
}
case 'F':
if (!SetDefaultImageFolder(optarg)) { if (!SetDefaultImageFolder(optarg)) {
cerr << "Folder '" << optarg << "' does not exist or is not accessible"; cerr << "Folder '" << optarg << "' does not exist or is not accessible";
return false; return false;
} }
continue; continue;
case 'g': case 'L':
log_level = optarg; log_level = optarg;
continue; continue;
@ -1739,7 +1780,7 @@ static void *MonThread(void *param)
switch(command.operation()) { switch(command.operation()) {
case LOG_LEVEL: { case LOG_LEVEL: {
LOGTRACE(string("Received " + PbOperation_Name(command.operation()) + " command").c_str()); LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str());
string log_level = GetParam(command, "level"); string log_level = GetParam(command, "level");
bool status = SetLogLevel(log_level); bool status = SetLogLevel(log_level);
@ -1753,7 +1794,7 @@ static void *MonThread(void *param)
} }
case DEFAULT_FOLDER: { case DEFAULT_FOLDER: {
LOGTRACE(string("Received " + PbOperation_Name(command.operation()) + " command").c_str()); LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str());
string folder = GetParam(command, "folder"); string folder = GetParam(command, "folder");
if (folder.empty()) { if (folder.empty()) {
@ -1770,7 +1811,7 @@ static void *MonThread(void *param)
} }
case DEVICES_INFO: { case DEVICES_INFO: {
LOGTRACE(string("Received " + PbOperation_Name(command.operation()) + " command").c_str()); LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str());
PbResult result; PbResult result;
result.set_status(true); result.set_status(true);
@ -1786,7 +1827,7 @@ static void *MonThread(void *param)
} }
case DEVICE_TYPES_INFO: { case DEVICE_TYPES_INFO: {
LOGTRACE(string("Received " + PbOperation_Name(command.operation()) + " command").c_str()); LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str());
PbResult result; PbResult result;
result.set_status(true); result.set_status(true);
@ -1797,7 +1838,7 @@ static void *MonThread(void *param)
case SERVER_INFO: { case SERVER_INFO: {
LOGTRACE(string("Received " + PbOperation_Name(command.operation()) + " command").c_str()); LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str());
PbResult result; PbResult result;
result.set_status(true); result.set_status(true);
@ -1807,7 +1848,7 @@ static void *MonThread(void *param)
} }
case IMAGE_FILES_INFO: { case IMAGE_FILES_INFO: {
LOGTRACE(string("Received " + PbOperation_Name(command.operation()) + " command").c_str()); LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str());
PbImageFilesInfo *image_files_info = new PbImageFilesInfo(); PbImageFilesInfo *image_files_info = new PbImageFilesInfo();
GetAvailableImages(*image_files_info); GetAvailableImages(*image_files_info);
@ -1819,7 +1860,7 @@ static void *MonThread(void *param)
} }
case NETWORK_INTERFACES_INFO: { case NETWORK_INTERFACES_INFO: {
LOGTRACE(string("Received " + PbOperation_Name(command.operation()) + " command").c_str()); LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str());
PbNetworkInterfacesInfo *network_interfaces_info = new PbNetworkInterfacesInfo(); PbNetworkInterfacesInfo *network_interfaces_info = new PbNetworkInterfacesInfo();
GetNetworkInterfacesInfo(*network_interfaces_info); GetNetworkInterfacesInfo(*network_interfaces_info);
@ -1894,13 +1935,16 @@ int main(int argc, char* argv[])
// Create a thread-safe stdout logger to process the log messages // Create a thread-safe stdout logger to process the log messages
auto logger = stdout_color_mt("rascsi stdout logger"); auto logger = stdout_color_mt("rascsi stdout logger");
// ~/images is the default folder for device image file. For the root user /home/pi/images is the default. // ~/images is the default folder for device image files, for the root user it is /home/pi/images
const int uid = getuid(); int uid = getuid();
const char *sudo_user = getenv("SUDO_UID");
if (sudo_user) {
uid = stoi(sudo_user);
}
const passwd *passwd = getpwuid(uid); const passwd *passwd = getpwuid(uid);
if (uid && passwd) { if (uid && passwd) {
string folder = passwd->pw_dir; default_image_folder = passwd->pw_dir;
folder += "/images"; default_image_folder += "/images";
default_image_folder = folder;
} }
else { else {
default_image_folder = "/home/pi/images"; default_image_folder = "/home/pi/images";

View File

@ -182,6 +182,7 @@ message PbDeviceTypesInfo {
message PbImageFile { message PbImageFile {
string name = 1; string name = 1;
bool read_only = 2; bool read_only = 2;
// The file size in bytes, 0 for block devices
int64 size = 3; int64 size = 3;
} }

View File

@ -574,10 +574,10 @@ int main(int argc, char* argv[])
if (argc < 2) { if (argc < 2) {
cerr << "SCSI Target Emulator RaSCSI Controller" << endl; cerr << "SCSI Target Emulator RaSCSI Controller" << endl;
cerr << "version " << rascsi_get_version_string() << " (" << __DATE__ << ", " << __TIME__ << ")" << endl; cerr << "version " << rascsi_get_version_string() << " (" << __DATE__ << ", " << __TIME__ << ")" << endl;
cerr << "Usage: " << argv[0] << " -i ID [-u UNIT] [-c CMD] [-t TYPE] [-b BLOCK_SIZE] [-n NAME] [-f FILE|PARAM] "; cerr << "Usage: " << argv[0] << " -i ID [-u UNIT] [-c CMD] [-C FILE] [-t TYPE] [-b BLOCK_SIZE] [-n NAME] [-f FILE|PARAM] ";
cerr << "[-d IMAGE_FOLDER] [-g LOG_LEVEL] [-h HOST] [-p PORT] [-r RESERVED_IDS] "; cerr << "[-F IMAGE_FOLDER] [-L LOG_LEVEL] [-h HOST] [-p PORT] [-r RESERVED_IDS] ";
cerr << "[-a FILENAME:FILESIZE] [-w FILENAME] [-m CURRENT_NAME:NEW_NAME] [-x CURRENT_NAME:NEW_NAME] "; cerr << "[-C FILENAME:FILESIZE] [-w FILENAME] [-R CURRENT_NAME:NEW_NAME] [-x CURRENT_NAME:NEW_NAME] ";
cerr << "[-e] [-k] [-l] [-v] [-y]" << endl; cerr << "[-L] [-k] [-l] [-v] [-y]" << endl;
cerr << " where ID := {0-7}" << endl; cerr << " where ID := {0-7}" << endl;
cerr << " UNIT := {0|1}, default is 0" << endl; cerr << " UNIT := {0|1}, default is 0" << endl;
cerr << " CMD := {attach|detach|insert|eject|protect|unprotect|show}" << endl; cerr << " CMD := {attach|detach|insert|eject|protect|unprotect|show}" << endl;
@ -613,7 +613,7 @@ int main(int argc, char* argv[])
opterr = 1; opterr = 1;
int opt; int opt;
while ((opt = getopt(argc, argv, "a:b:c:d:f:g:h:i:m:n:p:r:t:u:x:w:eklsvy")) != -1) { while ((opt = getopt(argc, argv, "elsvNTD:L:R:a:b:c:f:h:i:n:p:r:t:u:x:C:F:L:")) != -1) {
switch (opt) { switch (opt) {
case 'i': case 'i':
device->set_id(optarg[0] - '0'); device->set_id(optarg[0] - '0');
@ -623,7 +623,7 @@ int main(int argc, char* argv[])
device->set_unit(optarg[0] - '0'); device->set_unit(optarg[0] - '0');
break; break;
case 'a': case 'C':
command.set_operation(CREATE_IMAGE); command.set_operation(CREATE_IMAGE);
image_params = optarg; image_params = optarg;
break; break;
@ -645,12 +645,12 @@ int main(int argc, char* argv[])
} }
break; break;
case 'd': case 'F':
command.set_operation(DEFAULT_FOLDER); command.set_operation(DEFAULT_FOLDER);
default_folder = optarg; default_folder = optarg;
break; break;
case'e': case 'e':
command.set_operation(IMAGE_FILES_INFO); command.set_operation(IMAGE_FILES_INFO);
break; break;
@ -658,7 +658,7 @@ int main(int argc, char* argv[])
param = optarg; param = optarg;
break; break;
case 'k': case 'N':
command.set_operation(NETWORK_INTERFACES_INFO); command.set_operation(NETWORK_INTERFACES_INFO);
break; break;
@ -670,7 +670,7 @@ int main(int argc, char* argv[])
} }
break; break;
case 'g': case 'L':
command.set_operation(LOG_LEVEL); command.set_operation(LOG_LEVEL);
log_level = optarg; log_level = optarg;
break; break;
@ -683,7 +683,7 @@ int main(int argc, char* argv[])
list = true; list = true;
break; break;
case 'm': case 'R':
command.set_operation(RENAME_IMAGE); command.set_operation(RENAME_IMAGE);
image_params = optarg; image_params = optarg;
break; break;
@ -743,11 +743,11 @@ int main(int argc, char* argv[])
image_params = optarg; image_params = optarg;
break; break;
case 'y': case 'T':
command.set_operation(DEVICE_TYPES_INFO); command.set_operation(DEVICE_TYPES_INFO);
break; break;
case 'w': case 'D':
command.set_operation(DELETE_IMAGE); command.set_operation(DELETE_IMAGE);
image_params = optarg; image_params = optarg;
break; break;