\ ***************************************************** \ * * \ * BOOTMA-2.FTH * \ * * \ * Zutaten fuer FAT-Reparatur und Bootmanager unter * \ * Turbo-FORTH-83 und ZF * \ * * \ * Fred Behringer - Forth-Gesellschaft - 15.11.2008 * \ * * \ ***************************************************** \ Fuer Turbo-Forth: FORTH INCLUDE BOOTMAST.FTH INCLUDE BOOTMA-2.FTH [ret]. \ Hierbei ist die erste Include-Datei die aus Heft 3/2008 und die zweite \ die hier zu besprechende. Man beachte, dass man hier bis zum letzten \ INCLUDE (man darf natuerlich auch alles kleinschreiben) alle Eingaben \ 'schachteln' kann, ohne per [ret] 'absetzen' zu muessen. \ Fuer ZF: ZF [ret] [ret] FLOAD BOOTMAST.FTH [ret] FLOAD BOOTMA-2.FTH [ret]. In \ BOOTMAST.FTH muss vorher attributs off per \ auskommentiert werden. Bei ZF, \ zumindest in der erweiterten Fassung der Lokalen Forth-Gruppe Moers, geht die \ Schachtelung der Kommandozeilen-Eingaben nicht, ohne dass man zwischendurch \ per [ret] absetzt. Die Eingabe von ZF muss sogar zweimal quittiert werden. \ Glossar \ getbootactive ( -- ) Bootsektor der aktivierten Partition nach sectbuf \ (showboot16-1) ( -- ) Ersten Textteil des Bootsektors anzeigen \ (showboot16-2) ( -- ) Zweiten Textteil des Bootsektors bei FAT16 anzeigen \ (showboot32-1) ( -- ) Ersten Textteil des Bootsektors anzeigen \ (showboot32-2) ( -- ) Zweiten Textteil des Bootsektors bei FAT32 anzeigen \ (showboot) ( n -- ) Bootsektor dumpen. n=10h: 4 Zeilen, 20h: 6 Zeilen \ (showboot16) ( -- ) Inhalt von sectbuf als FAT16-Bootsektor anzeigen \ (showboot32) ( -- ) Inhalt von sectbuf als FAT32-Bootsektor anzeigen \ showboot16 ( n -- ) Wie (showboot16), aber erst Bootsektor von HD holen \ showboot32 ( n -- ) Wie (showboot32), aber erst Bootsektor von HD holen \ showbootactive16 ( -- ) Wie showboot16, aber auf aktivierte Partition bezogen \ showbootactive32 ( -- ) Wie showboot32, aber auf aktivierte Partition bezogen hex \ getbootactive laedt den Bootsektor der (ersten) aktiven Partition in den \ Puffer sectbuf . 'Normalerweise' ist das eine primaere Partition. Ist die \ erste aktivgeschaltete Partition (beabsichtigt oder nicht) die erweiterte \ Partition, dann wird deren erstes logisches Laufwerk angesprochen und der \ zugehoerige Bootsektor nach sectbuf geholt. Ist keine (der 4 moeglichen!) \ Partitionen aktiv, dann wird getbootactive mit einer Fehlermeldung verlassen. : getbootactive ( -- fl ) getmbr \ MBR nach sectbuf holen sectbuf 1ae + \ Ausgangsposition im Puffer 4 0 \ 4 relevante Zeilen im MBR do 10 + dup c@ 0 <> \ Partition aktiv? if 2 + @ 1 swap (getsect) 0 leave \ Ja, dann Bootsektor nach sectbuf then \ und raus. loop 0 <> if cr ." Keine Partition aktiv!" 0 \ Sonst Fehlermeldung. else 1 then ; \ (showboot16) interpretiert den Inhalt des Puffers sectbuf als Bootsektor eines \ logischen Laufwerks der erweiterten Partition und zeigt den darin enthaltenen \ Festplatten-Informationsteil mit bildschirmgerechten Erlaeuterungen am \ Bildschirm an. Achtung: (showboot16) kuemmert sich nicht darum, ob im Puffer \ sectbuf wirklich ein brauchbares Abbild eines Bootsektors liegt. Vor Aufruf \ von (showboot16) muss man daher gegebenenfalls den Bootsektor des \ interessierenden Laufwerks erst per n getboot von der Festplatte in den Puffer \ sectbuf holen. n=1 ist dabei das erste Laufwerk der erweiterten Partition, mit \ entsprechender Durchnummerierung fuer die weiteren Laufwerke. \ Im Teil 1 dieser Artikelserie (VD-Heft 3/2008) interessierten bei getboot nur \ die logischen Laufwerke der erweiterten Partition. Ich moechte aber hier auf \ die primaeren Partitionen nicht verzichten und habe soeben mit dem Forth-Wort \ getbootactive ( -- ) ein Mittel zum Schreiben des Bootsektors der momentan \ gerade aktivierten primaeren Partition in den Puffer sectbuf eingefuehrt. \ (showboot16) geht nur auf den Inhalt des Puffers sectbuf ein und braucht also \ keinen Unterschied zwischen getboot und getbootactive zu machen. In showboot16 \ dagegen (siehe unten) wird je nach Gegebenheit entweder auf getboot oder \ getbootactive umgeschaltet. (Es lebe die Unfaehigkeit des Entwicklers, schon \ beim ersten Zusammenstellen eines VD-Artikels eventuelle Vorhaben fuer weitere \ Artikel vorauszusehen!) \ Wie in Teil 1 dieser Artikelserie soll auch hier mein Hauptaugenmerk auf FAT16 \ gerichtet bleiben. Da sich aber die Bootsektoren bei FAT16 von denen bei FAT32 \ nicht besonders stark unterscheiden, bietet es sich an, schon hier auch auf \ die Verhaeltnisse bei FAT32 einzugehen. Bei den im Listing eingefuehrten \ Forth-Worten sind das die Stellen, an welchen in den Wort-Namen 16 durch 32 \ ersetzt ist. \ (showboot16-1) ist der erste Teil der Bildschirmanzeige von (showboot16) . \ Dieser erste Teil ist bei (showboot32) derselbe wie bei (showboot16) . Bei \ (showboot16) setzt hier nach Druecken einer Taste (mit Ausnahme von [ret]) der \ zweite Teil, naemlich (showboot16-2), ein. Bei (showboot32) schiebt sich hier \ als zweiter Teil (showboot32-2) ein. : (showboot16-1) ( -- ) ." Ofs Lng Inhalt" cr ." 000 3 Sprung zum Boot-Code (EB 3C 90 = JMP 003E NOP)." cr ." 003 8 OEM-Name, z.B. MSDOS6.2 oder MSWIN4.1 ." cr ." 00B 2 Bytes pro Sektor, i.A. 200 (512d)." cr ." 00D 1 Sektoren pro Cluster." cr ." 00E 2 Anzahl reservierter Sektoren (mit Bootsektor, also stets >= 1)." cr ." 010 1 Anzahl der FATs (i.A. 2)." cr ." 011 2 Max. Eintraegezahl im Stammverz. Bei FAT32 ungenutzt und = 0000." cr ." 013 2 Gesamtsektorzahl (max. 65535d) fuer Part. < 32MB. Bei > 32MB ist" cr ." es 0 und der Wert steht bei 020 (4 Bytes). Bei FAT32 ungenutzt." cr ." 015 1 Media-Descriptor-Byte. Seit Windows Server 2003 veraltet." cr ." 016 2 Sektorzahl/FAT. Bei FAT32 stets gleich 0000 (siehe Offset 24)." cr ." 018 2 Sektoren pro Spur." cr ." 01A 2 Anzahl der Seiten bzw. Schreib-Lese-Koepfe." cr ." 01C 4 Bei HDs Zahl der Sektoren zwischen MBR und Bootsektor der ersten" cr ." prim. Partition. Bei nicht partitionierten Medien stets 0000." cr ." 020 4 Gesamtsektoranzahl (lo/hi) fuer Partitionen > 32MB." cr ; : (showboot16-2) ( -- ) ." Ofs Lng Inhalt" cr ." 024 1 Phys. Laufwerksnummer (00 bei Disketten, 80, 81,... bei HDs)." cr ." Ist nur fuer Bootlaufwerke relevant, da diese Nummer beim Booten" cr ." fuer BIOS-Aufrufe zum Zugriff auf das Medium benutzt wird." cr ." 025 1 Reserviert (stets 00 bei FAT 12/16)." cr ." 026 1 Erweiterte Bootsignatur." cr ." 027 4 Dateisystems-ID (Seriennummer). Dient der Unterscheidung" cr ." verschiedener Medien (z.B. bei Wechselmedien)." cr ." 02B 0B Name des Dateisystems (max. 11d Zeichen, durch Leerzeichen" cr ." aufgefuellt). Veraltet. Wird durch einen speziellen" cr ." Verzeichniseintrag im Stammverzeichnis abgeloest." cr ." 036 8 FAT-Art, mit Leerzeichen aufgefuellt, z.B.: 'FAT12 '," cr ." 'FAT16 '." cr ." 03E 1C0 Beginn des Bootprogramms." cr ." 1FE 2 BIOS-Bootsektorsignatur. Enthaelt die Hex-Bytes 55 AA, anhand" cr ." derer das BIOS beim Booten einen gueltigen Bootsektor erkennt." cr ; : (showboot32-1) ( -- ) (showboot16-1) ; : (showboot32-2) ( -- ) ." Ofs Lng Inhalt" cr ." 024 4 Anzahl der Sektoren pro FAT" cr ." 028 2 FAT-Flags" cr ." 02A 2 FAT-32-Version. Derzeit stets 0000 bei Microsoft." cr ." 02C 4 Clusternummer, an der das Stammverzeichnis beginnt. Meistens 2." cr ." 030 2 Sektornummer des 'FS-Information-Sectors' (in der Regel: 1)" cr ." 032 2 Sektornummer der Bootsektorkopie (in der Regel: 6)" cr ." 034 0C Reserviert fuer spaetere Erweiterungen. Derzeit stets 0." cr ." 040 1 Phys. BIOS-Laufwerksnummer" cr ." 041 1 Reserviert" cr ." 042 1 Signatur" cr ." 043 4 Dateisystems-ID (Seriennummer)" cr ." 047 0B Name des Dateisystems (ungenutzt)" cr ." 052 8 FAT-Version. Stets: 'FAT32 '" cr ." 05A 1A4 x86-Maschinencode des Bootloaders" cr ." 1FE 2 BIOS-Bootsektorsignatur. Enthaelt die Hex-Bytes 55 AA ." cr ; \ Bei Eingabe von 10 (showboot) wird ein Dump der ersten 4 Zeilen ausgegeben. \ Das wird bei Interpretation als FAT16-Bootsektor (10h = 16d) eingesetzt. Bei \ Eingabe von 20 (showboot) werden 6 Zeilen gedumpt, was bei Interpretation als \ FAT32-Bootsektor (20h = 32d) zum Einsatz kommt. Der Unterschied kommt bei den \ gleich folgenden Forth-Worten (showboot16) und (showboot32) zum Tragen. : (showboot) ( n -- ) \ n=10h: 4 Zeilen des Bootsektors, n=20h: 6 Zeilen sectbuf over 10 = if 40 else 60 then dump \ (cursor) \ Gibt es nur in Turbo-Forth #out @ #line @ \ Geht sowohl in Turbo-Forth wie auch in ZF nip over 10 = if 5 else 7 then - 0 swap at cr \ at gibt es in Turbo-Forth und auch in ZF ." Offset 0" \ (cursor) \ Gibt es nur in Turbo-Forth #out @ #line @ \ Geht sowohl in Turbo-Forth wie auch in ZF swap 30 + swap at ." 0" cr \ at gibt es in Turbo-Forth und auch in ZF ." 000: " cr ." 010: " cr ." 020: " cr ." 030: " cr 20 = if ." 040: " cr ." 050: " cr then cr ; \ Menuegesteuerte Bildschirmanzeige der Festplatten-Informationen des im Puffer \ sectbuf gespeicherten Bootsektors. Dieser muss vorher per n getboot oder \ getbootactive in den Puffer geholt worden sein. Die Anzeige geht vom \ DOS-ueblichen Bildschirm-Modus von 80 Zeichen mal 25 Zeilen aus und \ interpretiert den Bootsektor als unter FAT16 geschrieben. : (showboot16) ( -- ) begin dark 10 (showboot) (showboot16-1) 18 spaces ." [Taste]: Teil2 [Return]: Raus " key 0d = if exit then dark 10 (showboot) (showboot16-2) 18 spaces ." [Taste]: Teil1 [Return]: Raus " key 0d = if exit then again ; \ Menuegesteuerte Bildschirmanzeige der Festplatten-Informationen des im Puffer \ sectbuf gespeicherten Bootsektors. Dieser muss vorher per n getboot oder \ getbootactive in den Puffer geholt worden sein. Die Anzeige geht vom \ DOS-ueblichen Bildschirm-Modus von 80 Zeichen mal 25 Zeilen aus und \ interpretiert den Bootsektor als unter FAT32 geschrieben. : (showboot32) ( -- ) begin dark 10 (showboot) (showboot32-1) 18 spaces ." [Taste]: Teil2 [Return]: Raus " key 0d = if exit then dark 20 (showboot) (showboot32-2) 18 spaces ." [Taste]: Teil1 [Return]: Raus " key 0d = if exit then again ; \ showboot16 leitet die Bildschirmanzeige des Bootsektors n der erweiterten \ Partition ein. Wird der Laufwerk-Parameter n vergessen, dann wird (soweit \ auf dem Datenstack nicht noch ein weiterer Eintrag uebriggeblieben ist) an \ Stelle des vergessenen Parameters der spezielle Wert n = 1 genommen. : showboot16 ( n -- ) depth 0 = if 1 then getboot (showboot16) ; \ showboot32 wirkt wie showboot16, nur dass die Anzeige als unter FAT32 erfolgt \ zu interpretieren ist. : showboot32 ( n -- ) depth 0 = if 1 then getboot (showboot32) ; : showbootactive16 ( -- ) getbootactive if (showboot16) then ; : showbootactive32 ( -- ) getbootactive if (showboot32) then ;