Disketa bez diskety
Disketa je stále dôležitý nástroj pre správu počítačov, najmä tých starších, ktoré nemajú CD/DVD mechaniku, či nedokážu z nej bootovať. No v mnohých počítačoch však už disketová mechanika nie je. Tak sa poďme pozrieť ako s disketou pracovať bez disketovej mechaniky.
Riešením je tzv. obraz diskety. Jedná sa vlastne o súbor, ktorý obsahuje celý obsah diskety a viac-menej môže plne nahradiť fyzickú disketovú mechaniku (za istých okolností sa dá z neho aj bootovať). Ja som sa do problémov s chýbajúcou disketovou mechanikou dostal práve kvôli bootovaniu, pretože som si chcel pripraviť bootovacie obrazy diskiet, ktoré som si pripravoval pre použitie na sieťový boot (PXELinux).
Vytvorenie obrazu
Ak máte k dispozícii fyzickú mechaniku, je obraz diskety najjednoduchšie získať jej prekopírovaním do súboru, na čo poslúži príkaz dd, napr.:
dd if=/dev/fd0 of=disketa.img
Parameter if udáva vstupný súbor (input file) a parameter of zase súbor výstupný (output file). Áno, pripomínam, že v linuxe je všetko (ohľadom súborového systému) súbor, teda aj disketová mechanika (teda disketa) je súbor. Ale ani keď disketovú mechaniku nemáte, nie je nič stratené, pretože rovnaký príkaz dokáže vytvoriť obraz diskety, samozrejme prázdny:
dd if=/dev/zero of=disketa.img bs=1k count=1440
Teda nie prázdny, ale obsahujúci samé nuly. Keďže však v tomto prípade súbor s nulami (/dev/zero) nekončí, je treba mu zadať kedy má skončiť. V tomto prípade má prekopírovať 1440 (count) blokov, každý o veľkosti 1 kB (bs), to je dohromady 1440 kB. Teda mnohým dobre známa veľkosť bežnej diskety. Jednoduchým zmenením hodnoty count možno riadiť veľkosť vzniknutého obrazu diskety. Chcete disketu s veľkosťou 770 kB? Žiadny problém:
dd if=/dev/zero of=disketa770.img bs=1k count=770
Alebo radšej disketu s veľkosťou 2.8 MB? Prosím:
dd if=/dev/zero of=disketa770.img bs=1k count=2880
Ak Vás napadlo, že takto si môžete vytvoriť disketu ľubovoľnou veľkosťou, máte pravdu. Ale..
Formátovanie obrazu
Jedna vec je disketu vytvoriť, druhá však je, že ju treba naformátovať. Keďže som chcel cez PXE bootovať MS-DOS (respektíve jeho klony ako FreeDOS a pod), potrebujem disketu naformátovať súborovým systémom FAT, no a tu to už s tou ľubovoľnosťou veľkosti nie je až také jednoduché. Preto v ďalšom popise ostanem pri štandardných veľkostiach, konkrétne 1,4 a 2,8 MB.
Na formátovanie súbúrúvého systému FAT v Linuxe poslúži príkaz mkdosfs, ktorý je v Debiane súčasťou balíka dosfstools. Jeho použitie je pomerne jednoduché, pre naformátovanie našej 1,4 MB diskety (teda jej obrazu) stačí zadať príkaz:
mkdosfs -n MojDisk disketa.img
Tento príkaz automaticky vyberie vhodnú veľkosť FAT (12, 16 alebo 32), čo je v tomto prípade FAT12 a nastaví meno diskety (label) na MojDisk. nastavenie mena diskety nie je povinné, ale ja si diskety rád popisujem aj takto... Inou možnosťou (ktorú ešte budem spomínať neskôr) je použitie programu mformat, z balíka mtools. Ak by ste si teraz tento obraz zapísali na disketu, napríklad takto:
dd if=disketa.img of=/dev/fd0
a túto vložili do nejakej mechaniky, zistíte, že máte plne funkčnú DOS-ovskú disketu, ale prázdnu – veď sme ju len naformátovali.
Pripájanie obrazu
Aby sme na obraz diskety moli aj zapisovať súbory, je teba ho pripojiť do nejakého adresára. Na pripájanie zariadení je v adresárovej štruktúre vyčlenený adresár /mnt, prípadne /media. Teda, radšej to výslovne napíšem, určitenepripájajte zariadenia priamo do týchto adresárov, ale vytvorne si v nich podadresár a pripájajte do neho! Na pokusné pripájanie však dávam prednosť adresáru /tmp, čím si doma šetrím prácu so zmazaním adresára na pripájanie. Takže vytvorme si tam podadresár:
mkdir /tmp/disketa
a do toho adresára teraz môžme pripojiť náš obraz diskety, a to pomocou zariadenia loop:
mount -o loop disketa.img /tmp/disketa
teraz všetko, čo zapíšeme do adresára /tmp/disketa, vlastne zapisujeme do nášho obrazu diskety. Príkaz mount automaticky vyberie prvé prázdne zariadenie /dev/loopX. Ak z nejakého dôvodu treba zadať konkrétne zariadenie, možno mu ho definovať v príkaze, napríklad pre /dev/loop6 by to vazeralo takto:
mount -o loop=/dev/loop6 disketa /tmp/disketa
Celé to však má jeden háčik, a tým sú prístupové práva, respektíve vlastníctvo súborov. Samozrejme súborový systém FAT nič také nepozná, ale Linux áno a pracuje s prístupovými právami aj pri tomto súborovom systéme. A keďže toto pripájanie bolo zatiaľ robiť ako root, všetky súbory a adresáre pripojeného obrazu vlastní práve root, čo môže spôsobiť problémy pri zapisovaní. Riešením by mohlo byť pridanie záznamu do /etc/fstab, ktorý by povoľoval pripojenie aj bežnému používateľovi, čo však iste nie je dobrý nápad pre dočasné pokusy.
Za lepšie riešenie považujem zadanie používateľa a jeho skupiny pri pripájaní. Avšak príkaz mount neumožňuje zadať používateľa a skupinu pomocou ich mena, len pomocou ich identifikačných čísel. Preto najprv potrebujeme zistiť pod akým číslom nás pozná systém, čo vyčítame z výstupu príkazu id:
id uid=1000(slavko) gid=1000(slavko) skupiny=4(adm),7(lp),20(dialout),24(cdrom),25(floppy),...
Tento príkaz vypíše okrem mena a čísla používateľa aj mená a čísla všetkých skupín, do ktorých používateľ patrí. Nás však teraz zaujímaju len dva údaje, ktoré som zvýraznil vo výpise červenou farbou. Tieto hodnoty (väčšinou stačí UID) stačí pridať do parametrov pripojenia obrazu a problém s právami prestane existovať:
mount -o loop -o uid=1000 disketa.img /tmp/disketa
Po zapísaní dát do obrazu (teda do pripojeného adresára) je treba pred ďalším použitím odpojiť, pretože inak sa ľahko stane, že údaje nebudú skutočne zapísané v súbore obrazu diskety, ale osanú niekde vo vyrovnávacej pamäti:
umount /tmp/disketa
Bootovacia dvojdisketa
Trochu iná situácia je, keď chceme vytvoriť bootovaciu disketu, teda jej obraz. Tu si bez nejakého originálu (rozumejme existujúci bootovací disk, či jeho obraz) nepomôžeme, pretože Linux prosto neobsahuje veci, ktoré je potrebné na takú bootovaciu disketu vložiť. Ak použijete na vytvorenie obrazu vyššie spomínaný príkaz dd z reálnej diskety, ktoré je bootovacia, bude aj jej obraz bootovací. Ak takú disketu k dispozícii nemáte alebo nemáte k dispozícii disketovú mechaniku, treba sa popozerať po internete. Dobrým začiatkom môžu byť stránky ako AllBootDisks.com, či BootDisk.com, či iné zdroje...
Každopádne, keď som si chcel vyrobiť bootovaciu dvojdisketu (2,8 MB), internet mi nepomohol a musel som si ju vyrobiť sám. Tu však už je príkaz mkdosfs krátky a do hry vstupuje balík mtools so svojimi príkazmi mformat a mcopy. Príkaz mformat dokáže pri formátovaní prekopírovať bootsektor z inej diskety (obrazu) a mcopy zase dokáže na takto naformátovanú disketu prekopírovať (okrem iných aj) potrebné systémové súbory. Ale poďme pekne poporiadku.
Ako celkom prvé si musíme zohnať obraz bootovacej diskety, povedzme, že ho máme a volá sa diskboot.img a je uložený v rovnakom adresári ako obraz našej dvojdiskety (disketa.img), ktorú sme si vytvorili príkazom:
dd if=/dev/zero of=disketa.img bs=1k count=2880
Jeho naformátovanie spolu s prekopírovaním bootsektoru dosiahneme príkazom:
mformat -i disketa.img -f 2880 -B diskboot.img ::
Parametrami príkazu vravíme, aby naformátoval obraz diskety (-i disketa.img), a to na veľkosť 2880 kB (-f 2880) a skopíroval zavádzací sektor z nášho bootovacieho obrazu (-B diskboot.img). Tá dvojitá dvojbodka na konci je dôležitá, pretože nahradzuje DOS-ové označenie zariadenia (napr. A:), aby príkaz mformat vedel, že nemá hľadať disketovú mechaniku, ale použiť zadaný obraz.
Po naformátovaní je treba prekopírovať (najmä) systémové súbory z pôvodného bootovacieho obrazu. Ak Vás napadne obrazy pripojiť a použť cp, tak nebudete úspešný, disketa nenaštartuje, pretože systémové súbory musia byť na konkrétnom mieste, čo cp nezaistí. Ale zaistí to príkaz mcopy, ktorému však musíme najprv nastaviť disketu, z ktorej má súbory kopírovať. Toto nastavenie je treba urobiť v konfiguračnom súbore /etc/mtools.conf, kde mu nastavíme DOS-ovské písmeno mechaniky tak, aby odkazovalo na náš pôvodný bootovací obraz:
#drive a: file="/dev/fd0" exclusive #drive a: file="/dev/loop0" exclusive
drive a: file="/celá/cesta/k/diskboot.img" exclusive
Prvý riadok, ktorý je zakomentovaný znakom #, je pôvodný riadok tohoto konfiguračného súboru. Druhý riadok je tiež zakomentovaný a teda nebude braný do úvahy, je tu len ako ukážka použitia zariadenia loop. Použité bude vlastne len nastavenie tretieho riadku, kde je treba zadať úplnú cestu k nášmu bootovaciemu obrazu. Toto nastavenie umožní, že v príkaze mcopy bude možné k súborom na obraze diskety pomocou DOS-ovskéh písmena a:. teraz môžme prekopírovať celý obsah bootovacej diskety na našu dvojdisketu:
mcopy -i disketa.img a: ::
V prípade, že chcete rekurzívne kopírovať aj obsah adresárov, treba pridať voľbu -s:
mcopy -s -i disketa.img a: ::
Teraz je naša dvojdisketa použiteľná ako bootovacia. Ak máte nainštalovaný virtualizačný nástroj qemu, môžete bootovanie z obrazu vyskúšať zadaním:
qemu -fda disketa.img -m 64 -boot a
Trojdisketa?
Hoci známy štandardný rozmer diskety končí dvojnásobnou veľkosťou (2880 kB), nie je to ani zďaleka koniec, viz. napríklad floopy.c v zdrojáku jadra. Mňa však veľké diskety zaujímali najmä kvôli PXE. Spolu so zadaním geometrie disku je možné vytvoriť prakticky ľubovoľne veľkú disketu, ktorú možno po sieti nabootovať pomocou memdisk. Ako ju však vytvoriť? Na stránke The GUI project sú k dispozícii dva skripty, mkfloppyimage.sh a newmkfloppyimg.sh. Oba robia v podstate to isté, ale ten s new na začiatku to robí trošku príjemnejšie a keď ho spustíte s parametrom -h, vypíše popis použitia.. A čo robia?
Vytvárajú obrazy diskiet skoro ľubovoľnej veľkosti a potebujú k tomu iný obraz bootovacej diskety s veľkosťou 1440 alebo 2880 kB. A to ešte nei je všetko, pretože na konci vypíšu parametre, ktoré je treba zadať pre správnu funkciu v memdisk. Napísal som "skoro ľubovoľnú veľkosť", tento môj záver vychádza z toho, že skripty sú pripravené na tvorbu naozaj veľkých diskiet a požadovaná veľkosť diskety sa zadáva v MB. Tieto sú v skripte prepočítané na kB, takže po malej úprave skriptu je to naozaj veľkosť ľubovoľná.
Moja úprava mkfloppyimage.sh#!/bin/bash # Last updated: 5.Augusta 2009 if [ $(id -u) -ne 0 ]; then echo "Spúšťať ako root!!!" exit 2 fi if [ $# -ne 3 ]; then echo "Použitie: $(basename $0) newimage oldimage size[kB]" exit 1 fi NEWIMAGE=$1 OLDIMAGE=$2 SIZEKB=$3 MKDOSFS=$(which mkdosfs) ((NUMSECT= SIZEKB << 1)) MNTNEW=`mktemp -d /tmp/new.XXXXXX` # Create a mountpoint MNTOLD=`mktemp -d /tmp/old.XXXXXX` # Create a mountpoint # Create the filesystem OUTLINE=`$MKDOSFS -I -v -C $NEWIMAGE $SIZEKB | grep heads` HEADS=`echo $OUTLINE | cut -f3 -d' '` SECTORS=`echo $OUTLINE | cut -f6 -d' '` ((CYLINDERS= NUMSECT / HEADS / SECTORS )) # Copy contents from old image to new image mount -o loop $NEWIMAGE $MNTNEW mount -o loop $OLDIMAGE $MNTOLD cp -r $MNTOLD/* $MNTNEW umount $MNTNEW umount $MNTOLD rmdir $MNTNEW rmdir $MNTOLD # Create the boot sector of the new image # copy the first 512 bytes from the OLD image # except the bytes 11 through 61 (inclusive) -- if starting at 0 # of bytes 12 through 62 (inclusive) -- if starting at 1 # dd starts counting at 1 -- Thanks to Christian Schneider # for pointing this bug (which should not cause any damage) # copy uptil the 12th byte (not including the 12th byte) dd if=$OLDIMAGE of=$NEWIMAGE bs=1 count=11 conv=notrunc 2>/dev/null # copy from 63 (i.e. skip first 62 bytes) to 512 bytes # hence we need to copy 512-62=450 bytes dd if=$OLDIMAGE of=$NEWIMAGE bs=1 skip=62 seek=62 conv=notrunc count=450 2>/dev/null # Print the details echo "Your floppy image is in $NEWIMAGE. When using it in iso/pxelinux, dont forget to add" echo "\"floppy c=$CYLINDERS s=$SECTORS h=$HEADS\" to the argument of memdisk"
Obraz diskety vo wine
Občas sa mi stane, že dostanem obsah diskety k dispozícii ako samorozbaľovací archív, ktorý treba spustiť a sám svoj obsah prekopíruje priamo na disketu. Výbroná vec. V emulátore wine mi to niekedy funguje, ale – nemám disketovú mechaniku, čiže tento samorozbaľovací nástroj sa nemá kam rozbaliť. Prečo ho však jeho obsah nerozbaliť do obrazu?
Je to prosté. Stačí v adresári ~/.wine/dosdevices/ vytvoriť adresár a: (áno aj z dvojbodkou). Prípadne vytvoriť adresár inde a na tento vytvoriť symbolický odkaz, ale to je na jednorázovú akciu zbytočne zložité... Takže adresár:
mkdir ~/.wine/dosdevices/a:
Do tohoto adresára pripojíme náš obraz diskety tak, aby používateľ bol vlastníkom súborov:
mount -o loop -o uid=1000 -o gid=1000 disketa.img /home/slavko/.wine/dosdevices/a:
Teraz už zápisu na disketu prostredníctvom wine nič nebráni. Možno len funkčnosť samotného programu, teda, či bude vo wine fungovať, ale to je o tom, ako program pristupuje k diskete.Bez problému mi funguje vytvorenie univerzálneho NetBootDisk-u, pravdepodobne pretože pristupuje na úrovni súborového systému. Rozbaľovanie archívov z AllBootDisks a podobných už nefunguje a končí chybou "The current image format is not supported by the disk drive".

