Zum Inhalt

Disketten-Abbilder erstellen

📅 Erstellt: 21.08.2026 🔄 Aktualisiert: 22.08.2026

Linux

Um Diskettenabbilder zu erstellen und zu befüllen, also R/W zu bearbeiten nutze ich Linux.
Es geht hier hauptsächlich um 1,44 MB 3,5" Disketten-Abbilder für MS-DOS, FAT12 Format.

Für das Erstellen und Bearbeiten von FAT12-Diskettenimages (.IMG / .IMA) unter Arch Linux benötigt man ein einziges Toolset: mtools (ergänzt durch dosfstools).

Image anlegen und formatieren

Software installieren

sudo pacman -S mtools dosfstools

Leere Diskettenimages anlegen & formatieren

Zuerst erstellst man mit dd eine völlig leere Imagedatei der Diskette und formatiert sie anschließend mit mformat:

  • 3,5" High Density (1,44 MB / 1440 KB):

    # 1. Leeres Image erzeugen (1440 KiB)
    dd if=/dev/zero of=disk144.img bs=1K count=1440
    
    # 2. FAT12-Formatierung mit Mtools
    mformat -f 1440 -i disk144.img -v "HALLOWELT" ::
    

  • 5,25" High Density (1,2 MB / 1200 KB):

    # 1. Leeres Image erzeugen (1200 KiB)
    dd if=/dev/zero of=disk120.img bs=512 count=2400
    
    # 2. FAT12-Formatierung mit Mtools
    mformat -f 1200 -i disk120.img -v "DISKEN_NAME" ::
    

Hinweis: Das :: am Ende der mtools-Befehle steht für das Hauptverzeichnis innerhalb des Images

Hintergrund: Manpage von mformat zum Größenformat
Auszug:

Description
     The mformat command is used to add an MS-DOS file system to a low-level formatted diskette.
     ...
Options
    ...
    f
        1200   1200K, double-sided, 15 sectors per track, 80 cylinders (for 5 1/4 HD)
        1440   1440K, double-sided, 18 sectors per track, 80 cylinders (for 3 1/2 HD)
    ...

Dateien lesen, schreiben & verwalten (R/W)

Hier wird der Kommandozeilenweg aufgezeigt, es gibt aber noch eine komfortablere Möglichkeit! Mehr dazu später.

Mit den mtools-Befehlen arbeitet man direkt im Image. Der Parameter -i gibt immer das Ziel-Image an:

  • Inhalt anzeigen:

    mdir -i disk144.img ::
    

    Auszug:
    ❯ mdir -i disk144.img 
     Volume in drive : is HALLOWELT  
     Volume Serial Number is 1315-87A1
    Directory for ::/
    
    No files
                              1 457 664 bytes free
    

  • Dateien vom PC ins Image kopieren:

    mcopy -i disk144.img AUTOEXEC.BAT CONFIG.SYS ::
    

  • Ordner im Image erstellen:

    mmd -i disk144.img ::TREIBER
    

  • Dateien in Unterordner kopieren:

    mcopy -i disk144.img MOUSE.COM ::TREIBER/
    

  • Datei aus dem Image auf den PC kopieren:

    mcopy -i disk144.img ::AUTOEXEC.BAT ./AUTOEXEC.TXT
    

  • Datei im Image löschen:

    mdel -i disk144.img ::UNNOETIG.TXT
    

  • Label (Diskettenname) ändern/löschen:

    mlabel -i disk144.img
    

Das Image bootfähig machen (MS-DOS)

Unter MS-DOS reichen zwei Dinge für eine bootfähige Diskette:

  1. Ein MS-DOS Bootsektor (Sektor 0).
  2. Die Systemdateien IO.SYS, MSDOS.SYS und COMMAND.COM im Hauptverzeichnis.

Da das direkte Erzeugen eines echten MS-DOS 6.22 Bootsektors unter Linux ohne den originalen DOS-Befehl SYS.COM fehleranfällig ist, nutzt man in der Praxis am besten ein Template:

In einer bestehenden DOS-Installation z.B. auf dem MiSTER FPGA oder einem echten PC oder hier in 86Box lege ich eine leere, formatierte Diskette, oder eine Kopie des oben erzeugten Disketten-Abbildes ein und führe im DOS C:\ ein sys c: a: aus.
4df01ccbd1198fff3cf3a5d38abf41c8.png

Eine lesbare Namensgebung zum Auseinanderhalten wäre hier sinnvoll: disk144_sys_dos622de.img bzw. disk120_sys_dos622de.img

Tipp: die Templates schreibgeschützt machen mit chmod -w disk* und sichern mit tar czvf LeerImages.tgz disk*

Auszug:

❯ ll
.rwxr-xr-x 1,2M marquisor 21 Aug 03:28  disk120.img
.rwxr-xr-x 1,2M marquisor 21 Aug 03:37  disk120_sys_dos622de.img
.rwxr-xr-x 1,5M marquisor 21 Aug 03:28  disk144.img
.rwxr-xr-x 1,5M marquisor 21 Aug 03:33  disk144_sys_dos622de.img

❯ chmod -w disk*

❯ ll
.r-xr-xr-x 1,2M marquisor 21 Aug 03:28  disk120.img
.r-xr-xr-x 1,2M marquisor 21 Aug 03:37  disk120_sys_dos622de.img
.r-xr-xr-x 1,5M marquisor 21 Aug 03:28  disk144.img
.r-xr-xr-x 1,5M marquisor 21 Aug 03:33  disk144_sys_dos622de.img

❯ tar czvf LeerImages.tgz disk*
disk120.img
disk120_sys_dos622de.img
disk144.img
disk144_sys_dos622de.img

Alternativ kann man mit mformat -B bootsektor.bin ... einen Bootsektor injizieren, falls eine Bootsektor-Datei einer DOS-Version vorliegt. Darum kümmere ich mich hier jetzt aber nicht, da mir die oben erklärte Methode bereits ausreichend und einfach genug erscheint.

Quellen: Wikipedia, Google, mtools, dosfstools Hilfe/Dokumentation, Gemini Flash Erweitert KI (2026-08-21) persönlich überarbeitet

Mit Dolphin (oder anderem Filemanager) das Image bearbeiten

Dafür wird udisksctl benutzt. Der Ablauf ist:
1. Virtuelles Loop-Gerät erstellen:
udisksctl loop-setup -f diskette.img

  1. Die Diskette kann nun in Dolphin eingehangen und bearbeitet werden, optional für andere Filemanager:
    udisksctl mount -b /dev/loop0

  2. Diskette aushängen in Dolphin oder optional Befehl:
    udisksctl unmount -d /dev/loop0

  3. Loop-Gerät löschen:
    udisksctl loop-delete -b /dev/loop0

Beispiel einer erstellten Diskette für 386 Benchmarks:

❯ mdir -i 386Bench.img
 Volume in drive : is HALLOWELT  
 Volume Serial Number is 1315-87A1
Directory for ::/

3DBENCH  EXE     54036 1990-09-07  11:28 
3DBENCH  HED      1634 1990-08-17  11:24 
3DBENCH  PAL      1792 1990-08-08   9:40 
3DBENCH  PC1     24914 1990-08-31  14:36 
3DBENCH  PC2      9422 1990-09-04   7:14 
3DBENCH  SHP      9319 1990-09-03  13:01 
3DBENCH  WLD      7151 1990-09-03  13:16 
AUTOEXEC BAT      1013 2015-01-22  18:42 
COMMAND  COM     54645 1994-05-31   4:22 
DOS4GW   EXE    265396 2014-01-05  21:27 
DRVSPACE BIN     66294 1994-05-31   4:22 
IO       SYS     40774 1994-05-31   4:22 
MSDOS    SYS     38138 1994-05-31   4:22 
NORTON   INI       530 2015-01-22  17:51 
PCPBENCH DAT    411402 2014-01-05  21:27 
PCPBENCH EXE    111814 2014-01-05  21:27 
SPEED600 EXE     43518 1993-03-05  11:00 
SYSINFO  EXE    151112 1991-08-05   4:01 
TOPBENCH EXE     87364 2013-11-24  12:19 
TOPBENCH LOG        48 2015-01-22  18:01 
       20 files           1 380 316 bytes
                             72 192 bytes free

Mehrteilige Archive erstellen und auf Disketten kopieren

Um mehrteilige Archive komfortabel in DOS entpacken zu können bedient man sich am besten dem ARJ- oder RAR-Format. Auch hierfür gibt es Linuxpacker. ARJ kann sogar DOS-kompatible selbstextrahierende Archive mit einer .EXE Datei erzeugen, wenn man der Kommandozeile als Header eine echte 16-Bit DOS ARJSFX.EXE mitgibt.

Die Kommandozeile dafür: arj a -m1 -jm -v1440k -je -jc/pfad/zu/ARJSFX.EXE ARCHIV.EXE /pfad/zu/dateien/*

Arbeiten wir am Beispiel Norton Ghost 6.0:

❯ ll
.rwxr-xr-x 298k marquisor 20 Sep  1999  _INST32I.EX_
.rwxr-xr-x  28k marquisor 20 Sep  1999  _ISDEL.EXE
.rwxr-xr-x  35k marquisor 20 Sep  1999  _SETUP.DLL
.rwxr-xr-x 179k marquisor 20 Sep  1999  _SYS1.CAB
.rwxr-xr-x 5,2k marquisor 20 Sep  1999  _SYS1.HDR
.rwxr-xr-x 153k marquisor 20 Sep  1999  _USER1.CAB
.rwxr-xr-x 6,2k marquisor 20 Sep  1999  _USER1.HDR
.rwxr-xr-x  100 marquisor  6 Mai  1999  AUTOEXEC.BAT
.rwxr-xr-x   66 marquisor 24 Aug  1999  AUTORUN.INF
.rwxr-xr-x  296 marquisor  6 Mai  1999  CONFIG.SYS
.rwxr-xr-x  131 marquisor 20 Sep  1999  DATA.TAG
.rwxr-xr-x 4,1M marquisor 20 Sep  1999  DATA1.CAB
.rwxr-xr-x  42k marquisor 20 Sep  1999  DATA1.HDR
.rwxr-xr-x 5,9k marquisor 25 Aug  1999  DIS_PKT.DOS
.rwxr-xr-x 207k marquisor 20 Sep  1999  DOSGHSRV.EXE
.rwxr-xr-x 261k marquisor 24 Aug  1999  GDISK.EXE
.rwxr-xr-x 679k marquisor 20 Sep  1999  GHOST.EXE
.rwxr-xr-x 4,7k marquisor 15 Jul  1999  GHOST.ICO
.rwxr-xr-x 1,1M marquisor 16 Sep  1999  GHOST.PDF
.rwxr-xr-x  692 marquisor 20 Aug  1999  GHOSTEXP.CNT
.rwxr-xr-x 684k marquisor 24 Aug  1999  GHOSTEXP.EXE
.rwxr-xr-x  20k marquisor 23 Aug  1999  GHOSTEXP.HLP
.rwxr-xr-x 1,4k marquisor 14 Sep  1999  GHOSTSRV.CNT
.rwxr-xr-x 360k marquisor 17 Sep  1999  GHOSTSRV.EXE
.rwxr-xr-x  42k marquisor 14 Sep  1999  GHOSTSRV.HLP
.rwxr-xr-x 513k marquisor 26 Aug  1999  GHSTWALK.EXE
.rwxr-xr-x 4,7k marquisor 20 Sep  1999  LANG.DAT
.rwxr-xr-x  609 marquisor 20 Sep  1999  LAYOUT.BIN
.rwxr-xr-x 352k marquisor 14 Sep  1999  NCDSTART.EXE
.rwxr-xr-x 2,0k marquisor 21 Apr  1999  NDISREAD.ME
.rwxr-xr-x 205k marquisor 24 Aug  1999  NWGHSRV.NLM
.rwxr-xr-x  450 marquisor 20 Sep  1999  OS.DAT
.rwxr-xr-x  693 marquisor  6 Mai  1999 󱁻 PROTOCOL.INI
.rwxr-xr-x 6,3k marquisor  2 Aug  1999  RAWIO.VXD
.rwxr-xr-x  19k marquisor  7 Sep  1999  README.TXT
.rwxr-xr-x 101k marquisor 27 Nov  1999  SETUP.BMP
.rwxr-xr-x  72k marquisor 20 Sep  1999  SETUP.EXE
.rwxr-xr-x  111 marquisor 20 Sep  1999 󱁻 SETUP.INI
.rwxr-xr-x  63k marquisor 20 Sep  1999  SETUP.INS
.rwxr-xr-x   49 marquisor 20 Sep  1999  SETUP.LID
.rwxr-xr-x  17k marquisor  9 Sep  1999  USAGE.TXT
.rwxr-xr-x 971k marquisor  7 Jul  1998  w95Ws2setup.exe
.rwxr-xr-x   31 marquisor  6 Mai  1999 󱁻 WATTCP.CFG

❯ du -h
8,7M    .

Die losen Dateien haben eine Größe von 8,7 MB. Das sind ungepackt aufgerundet 7 Disketten.

Mit ARJ schaffen wir es auf 6 Archive:

/...../Norton Ghost 6.0 DE
❯ arj a -y -m1 -jm -v1440k ../NGHOST6.ARJ *
ARJ32 v 3.10, Copyright (c) 1998-2004, ARJ Software Russia. [07 Sep 2024]

Creating archive  : ../NGHOST6.ARJ
Adding    _INST32I.EX_                 99.8%    
Adding    _ISDEL.EXE                   37.3%    
Adding    _SETUP.DLL                   36.7%    
Adding    _SYS1.CAB                    99.7%    
Adding    _SYS1.HDR                    32.3%    
Adding    _USER1.CAB                   99.9%    
Adding    _USER1.HDR                   34.4%    
Adding    AUTOEXEC.BAT                 92.0%    
Adding    AUTORUN.INF                 100.0%    
Adding    CONFIG.SYS                   51.7%    
Adding    DATA.TAG                     85.5%    
Adding    DATA1.CAB                   100.0%    
    12 file(s)
Creating archive  : ../NGHOST6.A01
Adding    DATA1.CAB                  starting at position 781841  100.0%    
     1 file(s)
Creating archive  : ../NGHOST6.A02
Adding    DATA1.CAB                  starting at position 2221113  100.0%    
     1 file(s)
Creating archive  : ../NGHOST6.A03
Adding    DATA1.CAB                  starting at position 3660385  100.0%    
Adding    DATA1.HDR                    35.3%    
Adding    DIS_PKT.DOS                  52.3%    
Adding    DOSGHSRV.EXE                 94.4%    
Adding    GDISK.EXE                    91.3%    
Adding    GHOST.EXE                    94.0%    
     6 file(s)
Creating archive  : ../NGHOST6.A04
Adding    GHOST.EXE                  starting at position 553308   94.4%    
Adding    GHOST.ICO                    45.1%    
Adding    GHOST.PDF                    47.9%    
Adding    GHOSTEXP.CNT                 46.0%    
Adding    GHOSTEXP.EXE                 43.1%    
Adding    GHOSTEXP.HLP                 49.5%    
Adding    GHOSTSRV.CNT                 40.8%    
Adding    GHOSTSRV.EXE                 47.7%    
Adding    GHOSTSRV.HLP                 68.3%    
Adding    GHSTWALK.EXE                 94.7%    
    10 file(s)
Creating archive  : ../NGHOST6.A05
Adding    GHSTWALK.EXE               starting at position 291034   88.8%    
Adding    LANG.DAT                     45.8%    
Adding    LAYOUT.BIN                   66.2%    
Adding    NCDSTART.EXE                 32.5%    
Adding    NDISREAD.ME                  33.5%    
Adding    NWGHSRV.NLM                  28.8%    
Adding    OS.DAT                       37.8%    
Adding    PROTOCOL.INI                 46.2%    
Adding    RAWIO.VXD                    60.4%    
Adding    README.TXT                   32.5%    
Adding    SETUP.BMP                    68.1%    
Adding    SETUP.EXE                    47.2%    
Adding    SETUP.INI                    97.3%    
Adding    SETUP.INS                    25.3%    
Adding    SETUP.LID                   100.0%    
Adding    USAGE.TXT                    20.9%    
Adding    w95Ws2setup.exe              94.4%    
Adding    WATTCP.CFG                  100.0%    
    18 file(s)

Automatisierung (Skriptentwurf)

Hier war mal ein Skript mit Nutzung von ARJ für Linux, um Archive für DOS zu erstellen, aber:

#!/bin/bash
...
Obsolet! Siehe unten Thema "ARJ Quirks"
ARJ unter Linux ist nur begrenzt mit ARJ unter DOS kompatibel!

Hier wurde zunächst ein - wenn nötig - mehrteiliges ARJ-Archiv erstellt, dazu entsprechend viele Diskimages und die Archivdatein auf die einzelnen Disketten geschrieben.

ARJ Quirks

cb8f0c455dde282468c8f31fb6ec8a8f.png
Die vom Skript erstellten mehrteiligen Archive sind anscheinend nur sehr begrenzt mit DOS ARJ kompatibel. Pfade können nicht entpackt werden und bei jeder Datei meckert er die Binärdatei sei von einem anderen Stern - äh, Betriebssystem.
7e2ede5f8b66092fcd965ff1bd94da5c.png

Dann nehmen wir halt DOSBox :-)
Eine DOS-Version von ARJ wird hierfür benötigt und muss sich im gleichen Verzeichnis wie das Skript befinden. Ich nehme hier ARJ 2.50a.de.

Schickes Skript

Das fertige Skript create_dos_arj_ima_dosbox.sh: - create_dos_arj_ima_dosbox.sh - ARJ.EXE

#!/bin/bash

# ==============================================================================
# DOS ARJ-Packer & Floppy-IMA Generator (über DOSBox & echte ARJ.EXE)
# ==============================================================================

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SCRIPT_NAME=$(basename "$0")

if [ "$#" -lt 3 ]; then
    echo -e "\nNutzung: $SCRIPT_NAME <ARCHIVNAME_8> <QUELLORDNER> <DISKGROESSE> [PFAD_BEHALTEN 0|1]\n"
    echo "Parameter:"
    echo "  ARCHIVNAME_8  : Name ohne Endung (max. 8 Zeichen, z.B. PCKCOL)"
    echo "  QUELLORDNER   : Pfad zum Quellverzeichnis"
    echo "  DISKGROESSE   : Disketten-Größe: 1.44 (MB), 1.2 (MB), 720 (kB), 360 (kB)"
    echo "  PFAD_BEHALTEN : 0 = Nur Inhalt packen / Root ist Ordnerinhalt (Standard)"
    echo "                  1 = Quellordner als ARCHIVNAME_8 im Archiv mitpacken"
    echo ""
    echo "Beispiel:"
    echo "  $SCRIPT_NAME PCKCOL \"/home/user/PCKCOL\" 1.44 0"
    exit 1
fi

ARCHIVE_BASE="$1"
SRC_DIR="$2"
DISK_SIZE_INPUT="$3"
PRESERVE_PATH="${4:-0}"

# ------------------------------------------------------------------------------
# 1. Abhängigkeiten & ARJ.EXE prüfen
# ------------------------------------------------------------------------------
DOSBOX_BIN=""
if command -v dosbox-staging &> /dev/null; then
    DOSBOX_BIN="dosbox-staging"
elif command -v dosbox &> /dev/null; then
    DOSBOX_BIN="dosbox"
else
    echo -e "\nFehler: Weder 'dosbox-staging' noch 'dosbox' wurde gefunden. Bitte installieren."
    exit 1
fi

for cmd in dd mformat mcopy du; do
    if ! command -v $cmd &> /dev/null; then
        echo -e "\nFehler: Befehl '$cmd' wurde nicht gefunden. Bitte installieren."
        exit 1
    fi
done

ARJ_EXE=""
if [ -f "$SCRIPT_DIR/ARJ.EXE" ]; then
    ARJ_EXE="$SCRIPT_DIR/ARJ.EXE"
elif [ -f "./ARJ.EXE" ]; then
    ARJ_EXE="$(pwd)/ARJ.EXE"
fi

if [ -z "$ARJ_EXE" ]; then
    echo -e "\nFehler: 'ARJ.EXE' (16-Bit DOS Executable) wurde nicht gefunden!"
    echo "Bitte lege die DOS-Datei 'ARJ.EXE' in folgenden Ordner: $SCRIPT_DIR"
    exit 1
fi

# ------------------------------------------------------------------------------
# 2. DOS 8-Zeichen Name prüfen
# ------------------------------------------------------------------------------
if [[ ! "$ARCHIVE_BASE" =~ ^[a-zA-Z0-9_-]{1,8}$ ]]; then
    echo -e "\nFehler: Archivname '$ARCHIVE_BASE' entspricht nicht dem DOS-8-Format!"
    echo "Er darf maximal 8 Zeichen lang sein und keine Leer- oder Sonderzeichen enthalten."
    exit 1
fi

ARCHIVE_BASE="${ARCHIVE_BASE^^}"
ARCHIVE_NAME="${ARCHIVE_BASE}.ARJ"

# ------------------------------------------------------------------------------
# 3. Pfade auflösen
# ------------------------------------------------------------------------------
if [ ! -d "$SRC_DIR" ]; then
    echo -e "\nFehler: Quellverzeichnis '$SRC_DIR' wurde nicht gefunden!"
    exit 1
fi

ABS_SRC_DIR=$(cd "$SRC_DIR" && pwd)
PARENT_DIR=$(dirname "$ABS_SRC_DIR")
ORIGINAL_FOLDER_NAME=$(basename "$ABS_SRC_DIR")

# ------------------------------------------------------------------------------
# 4. Disketten-Spezifikationen festlegen
# ------------------------------------------------------------------------------
case "$DISK_SIZE_INPUT" in
    1.44|1440)
        ARJ_SPLIT="1440"
        DD_COUNT=1440
        MFORMAT_SIZE=1440
        MAX_DISK_BYTES=1457664
        ;;
    1.2|1200)
        ARJ_SPLIT="1200"
        DD_COUNT=1200
        MFORMAT_SIZE=1200
        MAX_DISK_BYTES=1213952
        ;;
    720)
        ARJ_SPLIT="720"
        DD_COUNT=720
        MFORMAT_SIZE=720
        MAX_DISK_BYTES=730112
        ;;
    360)
        ARJ_SPLIT="360"
        DD_COUNT=360
        MFORMAT_SIZE=360
        MAX_DISK_BYTES=362496
        ;;
    *)
        echo -e "\nFehler: Ungültige Diskettengröße '$DISK_SIZE_INPUT'!"
        echo "Erlaubte Werte: 1.44, 1.2, 720, 360"
        exit 1
        ;;
esac

# ------------------------------------------------------------------------------
# 5. Größenprüfung des Quellordners
# ------------------------------------------------------------------------------
FOLDER_BYTES=$(du -sb "$ABS_SRC_DIR" 2>/dev/null | awk '{print $1}')

if [ -n "$FOLDER_BYTES" ] && [ "$FOLDER_BYTES" -lt "$MAX_DISK_BYTES" ]; then
    WARN_PCT=$(( FOLDER_BYTES * 100 / MAX_DISK_BYTES ))
    echo "-------------------------------------------------------------------------------"
    echo "💡 HINWEIS: Der Quellordner belegt unkomprimiert nur ${WARN_PCT}% einer"
    echo "   Diskette ($FOLDER_BYTES von $MAX_DISK_BYTES Bytes)."
    echo "   Die Dateien würden direkt unkomprimiert auf eine Diskette passen."
    echo "-------------------------------------------------------------------------------"
fi

# ------------------------------------------------------------------------------
# 6. Trap für sicheres Aufräumen bei Abbruch
# ------------------------------------------------------------------------------
RENAMED=0
TMP_DOS_DIR=""
TMP_CONF=""

cleanup() {
    [ -n "$TMP_DOS_DIR" ] && [ -d "$TMP_DOS_DIR" ] && rm -rf "$TMP_DOS_DIR"
    [ -n "$TMP_CONF" ] && [ -f "$TMP_CONF" ] && rm -f "$TMP_CONF"
    if [ "$RENAMED" -eq 1 ] && [ -d "$PARENT_DIR/$ARCHIVE_BASE" ]; then
        echo -e "\nStelle ursprünglichen Ordnernamen wieder her..."
        mv "$PARENT_DIR/$ARCHIVE_BASE" "$ABS_SRC_DIR"
    fi
}
trap cleanup EXIT INT TERM

# ------------------------------------------------------------------------------
# 7. Isolierte Temp-Umgebung & leere DOSBox-Config anlegen
# ------------------------------------------------------------------------------
TMP_DOS_DIR=$(mktemp -d)
cp "$ARJ_EXE" "$TMP_DOS_DIR/ARJ.EXE"

TMP_CONF=$(mktemp --suffix=.conf)
cat << 'EOF' > "$TMP_CONF"
[sdl]
display = 0
[cpu]
core = dynamic
cputype = auto
cycles = max
[autoexec]
EOF

LOG_FILE="$TMP_DOS_DIR/dosbox.log"

echo "-------------------------------------------------------------------------------"
echo "1. Erstelle echtes DOS ARJ-Archiv in DOSBox ($DOSBOX_BIN): $ARCHIVE_NAME"
echo "   Split-Preset: -v$ARJ_SPLIT"
echo "-------------------------------------------------------------------------------"

if [ "$PRESERVE_PATH" -eq 1 ]; then
    if [ "$ORIGINAL_FOLDER_NAME" != "$ARCHIVE_BASE" ]; then
        if [ -e "$PARENT_DIR/$ARCHIVE_BASE" ]; then
            echo -e "\nFehler: Zielpfad '$PARENT_DIR/$ARCHIVE_BASE' existiert bereits!"
            exit 1
        fi
        mv "$ABS_SRC_DIR" "$PARENT_DIR/$ARCHIVE_BASE"
        RENAMED=1
    fi

    "$DOSBOX_BIN" -nogui -noconfig -conf "$TMP_CONF" \
        -c "MOUNT C \"$TMP_DOS_DIR\"" \
        -c "MOUNT D \"$PARENT_DIR\"" \
        -c "C:" \
        -c "D:" \
        -c "C:\ARJ.EXE a -r -y -m1 -v$ARJ_SPLIT C:\\$ARCHIVE_NAME $ARCHIVE_BASE\\*.*" \
        -c "EXIT" &> "$LOG_FILE"
else
    "$DOSBOX_BIN" -nogui -noconfig -conf "$TMP_CONF" \
        -c "MOUNT C \"$TMP_DOS_DIR\"" \
        -c "MOUNT D \"$ABS_SRC_DIR\"" \
        -c "C:" \
        -c "D:" \
        -c "C:\ARJ.EXE a -r -y -m1 -v$ARJ_SPLIT C:\\$ARCHIVE_NAME *.*" \
        -c "EXIT" &> "$LOG_FILE"
fi

# Erzeugte Archive aus dem Temp-Ordner ins aktuelle Verzeichnis holen
mv "$TMP_DOS_DIR"/${ARCHIVE_BASE}.* "$(pwd)/" 2>/dev/null

if [ ! -f "${ARCHIVE_BASE}.ARJ" ]; then
    echo -e "\nFehler beim Erstellen des ARJ-Archivs via DOSBox!"
    if [ -f "$LOG_FILE" ]; then
        echo "--- DOSBox Log ---"
        cat "$LOG_FILE"
        echo "------------------"
    fi
    exit 1
fi

# ------------------------------------------------------------------------------
# 8. Disketten-Images (.IMA) erzeugen, formatieren & befüllen
# ------------------------------------------------------------------------------
echo -e "\n-------------------------------------------------------------------------------"
echo "2. Erstelle .IMA Disketten-Image(s)"
echo "-------------------------------------------------------------------------------"

ARJ_FILES=()
[ -f "${ARCHIVE_BASE}.ARJ" ] && ARJ_FILES+=("${ARCHIVE_BASE}.ARJ")

while IFS= read -r file; do
    if [ -n "$file" ] && [ "$file" != "${ARCHIVE_BASE}.ARJ" ]; then
        ARJ_FILES+=("$file")
    fi
done < <(ls "${ARCHIVE_BASE}".A* 2>/dev/null | sort)

TOTAL_DISKS=${#ARJ_FILES[@]}
DISK_INDEX=1

for arj_part in "${ARJ_FILES[@]}"; do
    if [ "$TOTAL_DISKS" -eq 1 ]; then
        IMA_NAME="${ARCHIVE_BASE}.IMA"
        VOLUME_LABEL="${ARCHIVE_BASE:0:11}"
    else
        IDX_STR=$(printf "%02d" $DISK_INDEX)
        IMA_NAME="${ARCHIVE_BASE}_DISK${IDX_STR}.IMA"
        VOLUME_LABEL="${ARCHIVE_BASE:0:8}_${DISK_INDEX}"
    fi

    echo -n " -> Erstelle $IMA_NAME ($arj_part)... "

    dd if=/dev/zero of="$IMA_NAME" bs=1k count=$DD_COUNT status=none
    if [ $? -ne 0 ]; then echo "FEHLER (dd)"; exit 1; fi

    mformat -i "$IMA_NAME" -f $MFORMAT_SIZE -v "$VOLUME_LABEL" ::
    if [ $? -ne 0 ]; then echo "FEHLER (mformat)"; exit 1; fi

    mcopy -i "$IMA_NAME" "$arj_part" ::
    if [ $? -ne 0 ]; then echo "FEHLER (mcopy)"; exit 1; fi

    echo "OK! [Label: $VOLUME_LABEL]"
    ((DISK_INDEX++))
done

echo -e "\n-------------------------------------------------------------------------------"
echo "Fertig! Erstellte Disketten-Images:"
if [ "$TOTAL_DISKS" -eq 1 ]; then
    ls -lh "${ARCHIVE_BASE}.IMA"
else
    ls -lh ${ARCHIVE_BASE}_DISK*.IMA
fi
echo "-------------------------------------------------------------------------------"

exit 0

Auszug der Ausgabe aus dem Linuxteil:

❯ create_dos_arj_ima_dosbox.sh PCKCOL PCKCOL/ 1.44 0
-------------------------------------------------------------------------------
1. Erstelle echtes DOS ARJ-Archiv in DOSBox (dosbox): PCKCOL.ARJ
   Split-Preset: -v1440
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
2. Erstelle .IMA Disketten-Image(s)
-------------------------------------------------------------------------------
 -> Erstelle PCKCOL_DISK01.IMA (PCKCOL.ARJ)... OK! [Label: PCKCOL_1]
 -> Erstelle PCKCOL_DISK02.IMA (PCKCOL.A01)... OK! [Label: PCKCOL_2]
 -> Erstelle PCKCOL_DISK03.IMA (PCKCOL.A02)... OK! [Label: PCKCOL_3]

-------------------------------------------------------------------------------
Fertig! Erstellte Disketten-Images:
-rwxr-xr-x 1 marquisor marquisor 1,5M 22. Aug 06:23 PCKCOL_DISK01.IMA
-rwxr-xr-x 1 marquisor marquisor 1,5M 22. Aug 06:23 PCKCOL_DISK02.IMA
-rwxr-xr-x 1 marquisor marquisor 1,5M 22. Aug 06:23 PCKCOL_DISK03.IMA
-------------------------------------------------------------------------------

/net/aca/OneDrive/Projekte/RetroPC/DOS Setup/Loose Files/Packer
❯ arj l PCKCOL.ARJ
ARJ32 v 3.10, Copyright (c) 1998-2004, ARJ Software Russia. [07 Sep 2024]

Processing archive: PCKCOL.ARJ
Archive created: 2026-08-22 06:23:36, modified: 2026-08-22 06:23:36
Filename       Original Compressed Ratio DateTime modified Attributes/GUA BPMGS
------------ ---------- ---------- ----- ----------------- -------------- -----
ACE.EXE          456714     271821 0.595 01-04-13 02:00:00                 +1  
ACE.TXT           64480      18783 0.291 01-03-01 02:00:00                 +1  
ACECZC.MSG        24345       8565 0.352 01-03-26 02:00:00                 +1  
ACEDUT.MSG        25503       8548 0.335 01-03-26 02:00:00                 +1  
ACEFIN.MSG        24480       8398 0.343 01-03-26 02:00:00                 +1  
ACEGER.MSG        26219       8392 0.320 01-03-26 02:00:00                 +1  
ACEHUN.MSG        25351       8380 0.331 01-03-27 02:00:00                 +1  
ACENWG.MSG        24480       8074 0.330 01-03-27 02:00:00                 +1  
ACEPOL.MSG        24961       8407 0.337 01-03-26 02:00:00                 +1  
ACERUS.MSG        25351       8945 0.353 01-03-26 02:00:00                 +1  
ACESPA.MSG        25375       8256 0.325 01-03-26 02:00:00                 +1  
DOS32.SFX         64955      61766 0.951 01-04-13 02:00:00                 +1  
FILE_ID.DIZ        1136        556 0.489 01-04-01 02:00:00                 +1  
LICENCE.GER        3115       1244 0.399 01-03-01 02:00:00                 +1  
LICENCE.PL         2362       1070 0.453 01-03-01 02:00:00                 +1  
LICENCE.TXT        2420        962 0.398 01-03-01 02:00:00                 +1  
ORDER.FRM          3003        954 0.318 00-07-09 02:00:00                 +1  
ORDER.GER          3723       1166 0.313 00-07-09 02:00:00                 +1  
ORDER.TXT          8229       3062 0.372 01-03-01 02:00:00                 +1  
README.TXT          557        305 0.548 01-03-01 02:00:00                 +1  
UNACE.EXE         61279      60442 0.986 01-04-13 02:00:00                 +1  
UNACECZC.MSG       3298       1674 0.508 01-02-10 02:00:00                 +1  
UNACEDUT.MSG       3466       1602 0.462 00-11-20 02:00:00                 +1  
UNACEFIN.MSG       3404       1599 0.470 00-12-01 02:00:00                 +1  
UNACEGER.MSG       3577       1633 0.457 00-11-20 02:00:00                 +1  
UNACEHUN.MSG       3369       1601 0.475 01-03-27 02:00:00                 +1  
UNACENWG.MSG       3235       1515 0.468 01-03-27 02:00:00                 +1  
UNACEPOL.MSG       3345       1640 0.490 00-11-20 02:00:00                 +1  
UNACERUS.MSG       3364       1722 0.512 00-12-01 02:00:00                 +1  
UNACESPA.MSG       3543       1597 0.451 00-11-20 02:00:00                 +1  
WHATSNEW.TXT       2665       1117 0.419 01-04-01 02:00:00                 +1  
ADDENDUM.DOC      19361       6588 0.340 93-02-01 01:04:16                 +1  
APPNOTE.TXT       37084      11524 0.311 93-02-01 01:04:16                 +1  
AUTHVERI.FRM       2330        945 0.406 93-02-01 01:04:16                 +1  
HINTS.TXT         14109       5067 0.359 93-02-01 01:04:16                 +1  
INSTALL.BAT         516        278 0.539 93-02-01 01:04:16                 +1  
LICENSE.DOC        3707       1514 0.408 93-02-01 01:04:16                 +1  
OMBUDSMN.ASP        591        355 0.601 93-02-01 01:04:16                 +1  
ORDER.DOC          3304       1514 0.458 93-02-01 01:04:16                 +1  
PKCFG.EXE         28570      18958 0.664 93-02-01 01:04:16                 +1  
PKSFANSI.COM        562        492 0.875 93-02-01 01:04:16                 +1  
PKSFANSI.DOC       3434       1604 0.467 93-02-01 01:04:16                 +1  
PKUNZIP.EXE       28959      28681 0.990 93-02-01 01:04:16                 +1  
PKUNZJR.COM        2750       2480 0.902 93-02-01 01:04:16                 +1  
PKZ204G.EXE      202574     202474 1.000 93-02-01 01:04:16                 +1  
PKZIP.EXE         42552      42143 0.990 93-02-01 01:04:16                 +1  
PKZIP.ICO           766        244 0.319 93-02-01 01:04:16                 +1  
PKZIPFIX.EXE       7687       7598 0.988 93-02-01 01:04:16                 +1  
PUTAV.EXE         21041      20575 0.978 93-02-01 01:04:16                 +1  
README             2166        984 0.454 93-02-01 01:04:16                 +1  
V204G.NEW         10704       4097 0.383 93-02-01 01:04:16                 +1  
WHATSNEW.204       2430       1144 0.471 93-02-01 01:04:16                 +1  
ZIP2EXE.EXE       26851      26283 0.979 93-02-01 01:04:16                 +1  
LICENSE.TXT        4213       1638 0.389 98-04-15 08:50:00                 +1  
OMBUDSMN.ASP        586        351 0.599 98-04-15 08:50:00                 +1  
ORDER.TXT          6026       2524 0.419 98-04-15 08:50:00                 +1  
PK250C32.EXE     307489     264522 0.860 98-04-20 20:29:24                 +1  
PKZIP.HTM        141047      14047 0.100 98-04-15 08:50:00                 +1  
PKZIP25.EXE      339456     196770 0.580 98-04-15 08:50:00                 +1  
PKZIPF~1.TXT        191        136 0.712 13-02-08 04:13:40                 +1  
README.TXT         4262       1249 0.293 96-09-15 08:50:00                 +1  
SETUP.EXE        130813      72040 0.551 96-09-15 08:50:00                 +1 >
------------ ---------- ---------- -----
    62 files    2327435    1452615 0.624 

/net/aca/OneDrive/Projekte/RetroPC/DOS Setup/Loose Files/Packer
❯ mdir -i PCKCOL_DISK01.IMA 
 Volume in drive : is PCKCOL_1   
 Volume Serial Number is 7DDC-82D2
Directory for ::/

PCKCOL   ARJ   1456471 2026-08-22   6:23 
        1 file            1 456 471 bytes
                              1 024 bytes free

ACHTUNG! In MS-DOS lautet der Entpackbefehl, damit auch ALLE Archive mitgezogen werden: arj x -v -y ARCHIV.ARJ:
- x: Entpacke mit im Archiv gespeicherten Pfaden
- -v: Multiarchiv-Modus aktivieren, Folgearchive automatisch entpacken
- -y: Alle Fragen mit 'Ja' beantworten

Am "richtigen" Rechner (hier noch 86Box):
8a4bb953fa6d1e5a220ef88ee5f2c78d.png
Soweit so gut, das läuft, sehr geil! 🥳

Echte Disketten

Hier wird das Arbeiten mit echten Floppies mit Hilfe eines USB Diskettenlaufwerks beschrieben.

Formatieren und verwenden
  1. Mit lsblk herausfinden um welches Laufwerk (Block-Device) es sich handelt:

    ❯ lsblk
    NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
    ...
    sde           8:64   1   1,4M  0 disk 
    └─sde1        8:65   1   1,4M  0 part 
    ...
    

  2. Gegebenenfalls (falls eingehängt) aushängen mit:
    sudo umount /dev/sde*

  3. Schnell bzw. Standard formatieren mit:
    sudo mkfs.fat -F 12 -I -n "DOSFLOPPY" /dev/sde

  4. (ALTERNATIV) Low-Level-Formatieren über folgende Befehle:

    ❯ sudo ufiformat -f 1440 /dev/sde
    geometry: track=80, head=2, sector=18, block=512
    done  
    
    ~ 1m 20s
    
    ❯ sudo mkfs.fat -F 12 -I -n "DOSFLOPPY" /dev/sde
    mkfs.fat 4.2 (2021-01-31)
    

  5. Diskette (der Name DOSFLOPPY sollte erscheinen) kann dann eingehängt und verwendet werden

Diskimages .IMA/.IMG etc. schreiben

Hier wird wieder das Tool dd benutzt, wer hätt's gedacht:
sudo dd if=DISK.IMG of=/dev/sde bs=512 status=progress conv=fsync

Beispiel:

❯ dd if=ontrack-9.57.img of=/dev/sde bs=512 status=progress conv=fsync
1471488 Byte (1,5 MB, 1,4 MiB) kopiert, 155 s, 9,5 kB/s1474560 Byte (1,5 MB, 1,4 MiB) kopiert, 155,002 s, 9,5 kB/s

2880+0 Datensätze ein
2880+0 Datensätze aus
1474560 Byte (1,5 MB, 1,4 MiB) kopiert, 165,562 s, 8,9 kB/s

❯ udisksctl mount -b /dev/sde
Mounted /dev/sde at /run/media/marquisor/ONTRACK

❯ ls -lah /run/media/user/ONTRACK/
Permissions Size User      Date Modified Name
drwxr-xr-x     - marquisor 27 Mär  2002   NT
drwxr-xr-x     - marquisor 27 Mär  2002   OS2
.rwxr-xr-x   56k marquisor 27 Mär  2002   CDREG.EXE
.rwxr-xr-x  246k marquisor 27 Mär  2002   CDUPDATE.EXE
.rw-r--r--   22k marquisor 27 Mär  2002   CDUPDATE.HLP
.rw-r--r--   27k marquisor 27 Mär  2002   DDLOADER.BIN
.rwxr-xr-x   61k marquisor 27 Mär  2002   DM.EXE
.rwxr-xr-x  175k marquisor 27 Mär  2002   DM1.EXE
.rw-r--r--  234k marquisor 27 Mär  2002   DM1.HLP
.rw-r--r--   45k marquisor 27 Mär  2002   DM1.REC
.rwxr-xr-x   86k marquisor 27 Mär  2002   FILECOPY.EXE
.rw-r--r--  5,7k marquisor 27 Mär  2002   FILECOPY.TXT
.rw-r--r--  2,6k marquisor 27 Mär  2002   FRENCH.TXT
.rw-r--r--  2,6k marquisor 27 Mär  2002   GERMAN.TXT
.rw-r--r--  5,4k marquisor 27 Mär  2002   INT13.386
.rw-r--r--   29k marquisor 27 Mär  2002   ODIKRNL.BIN
.rw-r--r--   13k marquisor 27 Mär  2002   ONTRACKD.SYS
.rw-r--r--   16k marquisor 27 Mär  2002   ONTRACKW.386
.rw-r--r--  1,2k marquisor 27 Mär  2002  󰂺 README
.rw-r--r--   21k marquisor 27 Mär  2002   XBIOS.OVL

❯ udisksctl unmount -b /dev/sde
Unmounted /dev/sde.