Verständnisproblem mit dynamischem Speicher



  • RawWrite kann AFAIK eben nur fertige Images auf Disketten schreiben oder ein Image aus einer bestehenden Diskette erzeugen! Was ich aber doch brauche ist ein Programm, welches ein neues Image erstellen kann?! Mehrere Dateien als Input, ein Imagefile als Output?! Ich bin nun seit Stunden nach so einem Programm am suchen, aber ohne Erfolg! 😞



  • Ehrlich gesagt verstehe ich nicht ganz, was du vor hast, wozu du ein tolles Programm zum Image-Erstellen brauchst?
    Entweder linkst du deine Dateien geschickt zusammen, oder du haengst sie einfach per HexEditor (oder wenn gewusst wie mit dem copy-Befehl) hintereinander. Die so erzeugte Datei kopierst du mittels Rawrite auf Diskette - fertig.
    Selbst deinen 512Byte grossen Bootloader kannst du wie er ist mittels Rawrite in den Sektor 0 einer Diskette schreiben, um ihn auszuprobieren. Dabei rate ich allerdings zur Vorsicht, da du dir so deine wertvollen Disketten zerstoeren kannst.
    Zum ersten Rumspielen empfehle ich daher sowas wie bochs. Dem kannst du AFAIR auch deinen 512Byte Bootloader als Disketten-Image verfruehstuecken.



  • Hmmm... Wieso können denn dabei die Disketten kaputtgehen? 😮



  • AFAIK: Weil der Bootsektor normalerweise in den ersten Bytes auch Informationen ueber die Diskettengeometrie enthaelt (leider gerade wieder kein Beispiel zur Hand). Meiner Erfahrung nach reagieren viele Systeme nicht gut darauf, wenn diese zB. mit deinem Code ueberschrieben werden.



  • Und wie kann ich denn das verhindern?

    2. Ich habe mir inzwischen mal die Speicheraufteilung angesehen:http://www.in4mation.de/services/memory.html#konventionellerspeicher

    Da ist nichts davon zu erkennen, dass sich im Speicher unterhalb von 07c00h irgendetwas vom BIOS befinden würde. Ausserdem ist daraus ersichtlich, dass der Bildschirmspeicher bei a0000h anfängt, wieso also kann ich den Speicher nur bis zur Adresse 98000h benutzen?

    Ach ja noch was, wieso kann das Programm überhaupt funktionieren, ich habe doch gar kein Codesegment definiert, aber aus irgendeinem Grund funktionierts trotzdem!

    Ich verwirrt! 🙂



  • Ishildur schrieb:

    Und wie kann ich denn das verhindern?

    Indem du diese Daten in deinen Bootsektor einbaust. Schau dir mal hier den Teil zum BPB an (und den Rest vielleicht auch noch 😉 ).

    Ishildur schrieb:

    2. Ich habe mir inzwischen mal die Speicheraufteilung angesehen:http://www.in4mation.de/services/memory.html#konventionellerspeicher

    Da ist nichts davon zu erkennen, dass sich im Speicher unterhalb von 07c00h irgendetwas vom BIOS befinden würde.

    KA, warum das da nicht drin steht, aber es ist so.
    Die BDA geht auch nicht unbedingt genau bis 7C00h - wenn du darunter aber einfach nichts rumschreibst, ohne genau zu wissen was du tust, bist du auf der sicheren Seite. 🙂

    Ishildur schrieb:

    Ausserdem ist daraus ersichtlich, dass der Bildschirmspeicher bei a0000h anfängt, wieso also kann ich den Speicher nur bis zur Adresse 98000h benutzen?

    Wieder gilt: Vorsicht ist die Mutter der Porzellankiste. 😃
    Duerfte aber eigentlich auch bis A0000 problemlos klappen. Musst da oben nur mit der Segmentierung aufpassen, damit du nicht aus versehen in den Grafikspeicher kommst.



  • Hmmmm. Irgendetwas klappte mit meinem Stack nicht! Wie muss ich den Stackpointer initialisieren?

    Im Internet habe ich folgendes gefunden:

    Danach startet der eigentliche Bootloader. Zuerst basteln wir uns einen Stack, dessen Adresse wir auf 0x9000 legen. Den Stackpointer setzen wir dabei auf 0. Während wir unseren Stack zusammenbauen, dürfen wir KEINE Interrupts verwenden!

    Code:
    start:
    cli ; Keine Interrupts verwenden!
    mov ax, 0x9000 ; Adresse des Stack speichern
    mov ss, ax ; Stackadresse festlegen
    mov sp, 0 ; Stackpointer auf 0 setzen
    sti ; Jetzt lassen wir wieder Interrupts zu

    [/quote]

    Ich habe das ein wenig abgeändert:

    cli             ; disable all interrupts as there is still no stack available
    mov ax,MEM_STK  ; copy the address of the stack into ax
    mov ss,ax       ; copy ax into the stacksegment
    xor sp,sp       ; init the stack pointer by zero
    sti             ; enable all interupts
    

    Also, leider funktioniert dass nicht, sobald ich xor sp,sp oder mov sp,00h mache, startet das Programm anschliessend nicht mehr! Was ich sowieso nicht so richtig verstehen kann: Ist es nicht so, dass der Stackpointer dekrementiv ist, müsste man diesen dann nicht wennschon mit bspw. 512 initialisieren?

    Lg Ishildur



  • Ishildur schrieb:

    Hmmmm. Irgendetwas klappte mit meinem Stack nicht! Wie muss ich den Stackpointer initialisieren?[...]
    Was ich sowieso nicht so richtig verstehen kann: Ist es nicht so, dass der Stackpointer dekrementiv ist, müsste man diesen dann nicht wennschon mit bspw. 512 initialisieren?

    Habe ich eigentlich auch schon geschrieben: Stimmt, aber 0 - 2 ist im 16Bit-Register FFFE. Dahin wird auch der erste Wert dann gespeichert.
    Warum dein Code nicht startet, kannst du dir zB. im Bochs debugger anzeigen lassen. Ansonsten kann ich auch nur raten - welchen Wert hat denn zB. MEM_STK?

    Noch eine Anmerkung: AFAIK wird beim Setzen von SS automatisch das Interrupt-Flag bis zur Ausfuehrung des uebernaechsten Befehls geloescht. Ein cli/sti um die 2 Befehle zur Stack-Einrichtung ist also unnoetig.



  • Hmmm, OK, das Problem mit dem Stack konnte ich lösen, ich dachte eben, dass die CPU den Stackpointer vom definierten Stackpointer herunterzählt...

    Irgendwie kriege ich das mit der Diskette lesen nicht gebacken! Woher weiss ich denn, von welchem Track und aus welchem Sektor ich lesen muss? Ist die Sektorgrösse nicht von der Formatierung abhängig?
    Ausserdem, wenn ich nun 15 KBytes auslesen, will, woher weiss ich dann wieviele Tracks und Sektoren dass sind?

    Gibts vielleicht irgendwo ein gutes Tutorial in Bezug auf das lesen von Diskette ohne Dateisystem?

    Lg Ishildur



  • Ishildur schrieb:

    Irgendwie kriege ich das mit der Diskette lesen nicht gebacken! Woher weiss ich denn, von welchem Track und aus welchem Sektor ich lesen muss?

    Du weisst, in welcher Reihenfolge die Daten/Programmteile in deinem Image liegen. Weisst du das nicht, solltest du dir darueber erstmal klar werden.
    Fuer Disketten wird dann AFAIK immer die chs-Adressierung verwendet...
    Wenn du dir dazu noch den Artikel ueber LBA durchliest, wird die Sache hoffentlich klarer... Die Werte fuer die Diskettengeometrie stehen im BPB.

    Ishildur schrieb:

    Ist die Sektorgrösse nicht von der Formatierung abhängig?

    Nein. Von der Laufwerksgeometrie. AFAIK ist das aber eigentlich immer mit der Blockgroesse gleichzusetzen, welche eigentlich auch immer 512 Byte betraegt (mir ist zumindest keine Ausnahme bekannt).

    Ishildur schrieb:

    Ausserdem, wenn ich nun 15 KBytes auslesen, will, woher weiss ich dann wieviele Tracks und Sektoren dass sind?

    Teile die 15kiloByte durch die Blockgroesse. Die so gewonnene Anzahl von Bloecken kannst du mit Hilfe der Laufwerksgeometrie-Daten und der Umrechnungsformel LBA/chs von Wikipedia weiter umrechnen.

    Ishildur schrieb:

    Gibts vielleicht irgendwo ein gutes Tutorial in Bezug auf das lesen von Diskette ohne Dateisystem?

    Kenne keines. Vielleicht bei den OS-Dev-Links.


Anmelden zum Antworten