Autor Thema: kernel.bin auf 512 Bytes vergrößern.  (Gelesen 9001 mal)

sebi2020

  • Beiträge: 130
    • Profil anzeigen
    • Infortus OS
Gespeichert
« am: 02. November 2009, 19:56 »
Hallo, ich habe mir dass Tutorial im Magazin ausgabe 1 durchgelesen. Habe ein kleines Problem mit qemu. So wie ich es im Tutorial gelesen habe, kann qemu immer nur Sektorenweise lesen (also 512 Byte)... Jetzt habe ich meinen Bootloader (der genau ein Sektor groß ist) und den kernel der nur 118 Byte umfasst. Wie schaffe ich es jetzt Die datei auf 512 Byte zu bringen, so dass qemu sie überhaupt lesen kann?

mfg Sebi
« Letzte Änderung: 02. November 2009, 19:59 von sebi2020 »
Please press any-key...
Verflucht wo ist any-key? hier? ach Mist, das war Escape...

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 02. November 2009, 20:02 »
Wie erstellst du denn die kernel.bin?
Dieser Text wird unter jedem Beitrag angezeigt.

sebi2020

  • Beiträge: 130
    • Profil anzeigen
    • Infortus OS
Gespeichert
« Antwort #2 am: 02. November 2009, 20:34 »
mit nasm:
nasm -f bin -o kernel.bin kernel.asmdie times direktive wird komischerweise ignoriert, ich habe sie in die kernel.asm reinkopiert. aber anscheinend füllt nasm trotztdem den rest nicht mit nullen auf.
Please press any-key...
Verflucht wo ist any-key? hier? ach Mist, das war Escape...

stultus

  • Beiträge: 486
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 02. November 2009, 20:42 »
Hört sich eher komisch an, Quelltext wäre gut ;)

Ansonsten liegt das Problem nicht bei qemu, sondern schlichtergreifend daran, dass die Bootsignatur am Ende des ersten Sektors gesucht wird - und ein Sektor ist bei Disketten nunmal 512 Bytes lang ;)
MSN: planetconquestdm@hotmail.de
ICQ: 190-084-185

... Wayne?

sebi2020

  • Beiträge: 130
    • Profil anzeigen
    • Infortus OS
Gespeichert
« Antwort #4 am: 02. November 2009, 20:55 »
Okay, ich schreib hier nochmal den ganzen Quelltext rein, also hier der vom Bootloader, der im ersten Sektor liegt und genau 512 Bytes lang ist (da funktioniert es komischwerweise mit den 512 Bytes.
Hier der Bootloader aus der ausgabe:
    org 0x7C00 ; Unsere Startadresse
 
    ; -----------------------------------------
    ; Unser Bootloader
    ; -----------------------------------------
 
    jmp 0x0000:start
    start:
                    ; Erst brauchen wir einen Stack.
    cli             ; Keine Interrupts!
    mov ax, 0x9000  ; Stackadresse
    mov ss, ax      ; SS = 0x9000 (unser Stack)
    mov sp, 0       ; SP = 0x0000  (der Stackpointer)
    sti             ; Interrupts zulassen
 
    ; Segmentregister initialisieren (für Zugriff auf bootdrv notwendig)
    mov ax, 0x0000
    mov es, ax
    mov ds, ax
 
    ; Bootlaufwerk aus DL speichern
    mov [bootdrv], dl
 
    ;Lade unseren Kernel
    call load
 
    ;Springe zu diesem Kernel
    mov ax, 0x1000 ; Die Adresse des Programms
    mov es, ax     ; Segmentregister updaten
    mov ds, ax
    jmp 0x1000:0x0000
 
    ; ----------------------------------------------
    ; Funktionen und Variablen
    ; ----------------------------------------------
 
    bootdrv db 0 ;Das Bootlaufwerk
    loadmsg db "Laden...",13,10,0
 
    ; Einen String ausgeben:
    putstr:
    lodsb             ; Byte laden
    or al,al
    jz short putstrd  ; 0-Byte? -> Ende!
 
    mov ah,0x0E       ; Funktion 0x0E
    mov bx,0x0007     ; Attribut-Byte (wird nicht benötigt)
    int 0x10          ; schreiben
    jmp putstr        ; Nächstes Byte
    putstrd:
    retn
 
    ; Lade den Kernel vom Bootlaufwerk
    load:
    ; Diskdrive reset (Interrupt 13h, 0)
    mov ax, 0          ; Die gewünschte Funktion (reset)
    mov dl, [bootdrv]  ; Dieses Laufwerk ist gewünscht
    int 13h            ; Den Interrupt ausführen
    jc load            ; Geht nicht? -> Noch mal!
 
    load1:
    mov ax,0x1000      ; ES:BX = 0x10000
    mov es,ax
    mov bx, 0
 
    ; Sektoren lesen (Interrupt 13h, 2)
    mov ah, 2         ; Funktion 2 (Lesen)
    mov al, 5         ; Lese 5 Sektoren
    mov cx, 2         ; Cylinder=0, Sector=2
    mov dh, 0         ; Head=0
    mov dl, [bootdrv] ; Laufwerk aus Vorgabe
    int 13h           ; ES:BX =  Daten vom Laufwerk
    jc load1          ; Fehler? Noch mal!
    mov si,loadmsg
    call putstr       ; Meldung ausgeben
    retn
    times 512-($-$$)-2 db 0   ; Dateilänge: 512 Bytes
    dw 0AA55h                 ; Bootsignatur
Und hier der kernel:

    mov ax, 0x1000 ; Segmentregister updaten
    mov ds, ax
    mov es, ax
 
    start:
    mov si, msg
    call putstr   
 
    mov si,msg_boot
    call putstr   
 
    call getkey   ; Warte auf einen Tastendruck
    jmp reboot    ; Reboot
 
    msg db "Herzlich Willkommen zu StupidOS 0.1",13,10,0
    msg_boot db "Beliebige Taste druecken...",10,0
 
    ; Stringausgabe
    putstr:
    lodsb            ; Byte laden
    or al,al
    jz short putstrd ; 0-Byte? -> Ende!
    mov ah,0x0E      ; Funktion 0x0E
    mov bx,0x0007   
    int 0x10         
    jmp putstr       
    putstrd:
    retn
 
    getkey:
    mov ah, 0 ; Funktion 0
    int 0x16  ; Ausführen
    ret
 
    reboot:
    jmp 0xffff:0x0000
    times 512 db 0
(118 Bytes statt 512 Bytes)
habe dann alles zu einer datei verpackt (Windows):
copy /b bootloader.bin + kernel.bin myOS.img
Please press any-key...
Verflucht wo ist any-key? hier? ach Mist, das war Escape...

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 02. November 2009, 21:01 »
Wenn ich deinen Kernel assembliere, bekomme ich aber 629 Bytes, nicht nur 118. Das ist auch ungefähr, was zu erwarten ist, denn du füllst am Ende nicht nur auf (vergleich den Code mit dem Bootsektor), sondern fügst einfach fest 512 Nullen ein.

Gibt es übrigens einen Grund, warum du das Tut aus dem Magazin benutzt und nicht die neueren Tutorials?
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

sebi2020

  • Beiträge: 130
    • Profil anzeigen
    • Infortus OS
Gespeichert
« Antwort #6 am: 02. November 2009, 21:08 »
hm sehr komisch, selbst dieses "fest" anlegen bewirkt bei mir überhaupt nichts. er tut überhaupt garnichts bei mir. (Arbeitet mit Vista). naja und ich habe die aus dem magazin genommen, weil ich sie am verständlichsten fand. Ich habe im Wiki das Gefühl mich ständig hin und her klicken zu müssen, um an bestimmten stellen weiter zu machen. Naja, ich frage mich jetzt, warum er nicht mal die 0en fest einfügt. ich habe es noch mal versucht zu assemblieren und es kommt bei mir immer noch 118 Bytes raus. Sagt zumindest Vista.

EDIT:
Habe die Dateien noch mal in ein anderes Verzeichniss kopiert. Jetzt nicht mehr. Lag wahrscheinlich an der UAC.
« Letzte Änderung: 02. November 2009, 21:12 von sebi2020 »
Please press any-key...
Verflucht wo ist any-key? hier? ach Mist, das war Escape...

stultus

  • Beiträge: 486
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 02. November 2009, 21:13 »
Merkwürdig. Entweder nasm hat unter Vista ne Macke, oder es legt ohne zutun sparse-files an und gibt die benutzte Größe - was aber mehr sein sollte, bei Blockgrößen jenseits der 512 Bytes. Steht wenn du ins Eigenschaftenmenü der Datei gehst irgendwo eine andere Größe?

Zum Wiki, wir haben da einige sehr aktive Autoren, wenn man denen nur sagt was gewünscht ist oder besser gemacht werden könnte. Also, konkretisieren! :)
MSN: planetconquestdm@hotmail.de
ICQ: 190-084-185

... Wayne?

DerHartmut

  • Beiträge: 236
    • Profil anzeigen
    • Mein Blog
Gespeichert
« Antwort #8 am: 02. November 2009, 21:23 »
Genau. Wenn was hakt, einfach den Leuten, die hier stehen sagen ;-)
$_="krJhruaesrltre c a cnp,ohet";$_.=$1,print$2while s/(..)(.)//;
Nutze die Macht, nutze Perl ;-)

sebi2020

  • Beiträge: 130
    • Profil anzeigen
    • Infortus OS
Gespeichert
« Antwort #9 am: 02. November 2009, 21:25 »
Bei Eigenschafte steht der selbe Wert... aber ehrlich gesagt mach ich mir jetzt auch keine Gedanken mehr, habe die Datein einfach in einen Ordner kopiert, der nicht von der UAC überwacht wird. Wobei ich NASM eigentlich extra als Administrator gestartet hab... naja :-)

Also konkretisieren ist, schwer... Ich habe mir dass OS-Dev für Einsteiger durchgelesen. Naja und hier und da kam dann irgendwann GDT , IDT , IVA und ich musste mir dann halt auf den seiten zu GDT , und IDT noch mal alles durchlesen. Dann kam dort als Beispiel vielleicht zufällig was von IRQ, klickt man wieder auf den Link und dann kehrt man irgendwann zum eigentlichen Tutorial zurück und ist auch immer noch nicht viel schlauer. Dass Problem ist, dass ich finde, dass einige Sachen zu wenig beschrieben werden. Und wenn man dann durch mit dem Tutorial ist fragt man sich, wie gehts jetzt weiter?! Ich hab ehrlich gesagt keinen Anhaltspunkt. Kann natürlich auch an mir liegen. Ich meine ich habe z.B. auch schon in andren Programmiersprachen programmiert (C++,VB.net, Delphi und (PHP :-) )). Naja dann taucht dort make auf und Linker - Scripte und dann denkt man sich nur noch "Hilfe...". Weil ich kann zumindest nicht viel mit den Skripten (Linker Skripte und make-files) anfangen, und make soweit ich weiß gar nicht unter windows verwenden.

EDIT:
Und ich Frage mich warum die Kernels in C geschrieben werden , wenn es heißt LOWLEVEL ? oder darf ich C auch noch als LOWLEVEL verstehn?
« Letzte Änderung: 02. November 2009, 21:28 von sebi2020 »
Please press any-key...
Verflucht wo ist any-key? hier? ach Mist, das war Escape...

DerHartmut

  • Beiträge: 236
    • Profil anzeigen
    • Mein Blog
Gespeichert
« Antwort #10 am: 02. November 2009, 21:31 »
Also die Grundpfeiler des Internets sind halt Hyperlinks. Im OS-Dev-für-Einsteiger-Tutorial sind die wichtigsten Infos gekapselt, um sich weiter in einen Bereich einzuarbeiten sind dann die Links da. Wenn man z.B. GDT, IDT usw. usf. komplett im Artikel 4 abhandeln würde, würde er nur unnötig groß und damit auf Anfänger abschreckend wirken. Denn beides sind nicht gerade triviale Themen.

Und Links zu Make und Linkerfiles haben wir auch ;-)

Und du kannst btw so ziemlich alles als "lowlevel" titulieren, was irgendwie schön hardware-nah ist ;-)
$_="krJhruaesrltre c a cnp,ohet";$_.=$1,print$2while s/(..)(.)//;
Nutze die Macht, nutze Perl ;-)

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 02. November 2009, 21:42 »
Hast du auch die Tutorialreihe zu OS-Dev für Einsteiger gelesen oder nur den Artikel? Der Artikel hat es noch nicht ganz geschafft, die Tutorials richtig einzubinden (oder überhaupt drauf zu verweisen), das sollte man mal ändern (Hallo Wiki-Team! ;))

Das zugehörige Beispiel-OS gibt es übrigens auch in komplett unter http://git.tyndur.org/?p=tutorial.git;a=summary

Und ich Frage mich warum die Kernels in C geschrieben werden , wenn es heißt LOWLEVEL ? oder darf ich C auch noch als LOWLEVEL verstehn?
Lowlevel hat in erster Linie nichts mit der Sprache zu tun. Ein Kernel ist lowlevel und man kann ihn mit sehr vielen Sprachen schreiben. Aber auch wenn man einmal davon absieht, ist C schon eine ziemlich lowlevelige Sprache.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

sebi2020

  • Beiträge: 130
    • Profil anzeigen
    • Infortus OS
Gespeichert
« Antwort #12 am: 02. November 2009, 22:28 »
zum teil habe ich mir diese schon durchgelesen, aber ich habe jetzt ein konkretes beispiel was ich sehr abschreckend finde:
Ich lese etwas von I/O Ports. Klicke ich auf den Link bekomme ich eine Seitenlange liste von Registern etc. aber keine Beschreibung davon was I/O Ports überhaupt sind. habe zumindest im Internet was zu Memory Mapped I/O was gefunden, aber so wie ich es verstanden habe wird bei so einem Prozessor Isolated I/O verwendet. Nun stellt sich für mich die Frage, wie spricht man diese Ports an?!, wie werden Sie adressiert, gibt es dafür spezielle Opcodes? und wenn ja , wie sehen dann die memorics (oder wie sie noch mal heißen) dafür aus?!

EDIT: Für mich stellt sich zumindest die Frage, macht es überhaupt sinn sich mit der OS Programmierung zu befassen, wenn ich bei solchen Sachen wie Peripherie nichts verstehe. Ich mein die schönen BIOS Interupts kann ich ja im Protected Mode nciht mehr verwenden, zumindest soweit ich dass verstanden habe. oO...
« Letzte Änderung: 02. November 2009, 22:30 von sebi2020 »
Please press any-key...
Verflucht wo ist any-key? hier? ach Mist, das war Escape...

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 02. November 2009, 22:35 »
Mit IO-Ports sprichst du Hardware an. Du kannst es dir mal ganz grob als Speicher vorstellen, auf dem sowohl Hardware als auch dein Code arbeiten. Der Speicher ist 64k groß und ein Port ist ein Byte darin. Du kannst über in (von einem Port lesen) und out (schreiben) darauf zugreifen.

Memory Mapped I/O wäre, wenn du zum Zugriff auf die Hardware nicht die Ports benutzt, sondern die Geräte stattdessen einen Bereich in den normalen RAM einblenden.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

sebi2020

  • Beiträge: 130
    • Profil anzeigen
    • Infortus OS
Gespeichert
« Antwort #14 am: 02. November 2009, 22:53 »
@taljeth kennst du vielleicht einen Artikel oder ein Tutorial generell, was genauer auf dieses Thema eingeht?

Oder kennt vielleicht sonst jemand nen Artikel der genau auf die I/O Ports eingeht?

mfg Sebi
Please press any-key...
Verflucht wo ist any-key? hier? ach Mist, das war Escape...

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 02. November 2009, 23:13 »
Mehr als in meinem Beitrag oben gibt es eigentlich dazu nicht zu sagen.

Du musst nur noch von der jeweiligen Hardware wissen, welche IO-Ports sie benutzt und was man dort hineinschreiben (bzw. daraus lesen) muss. Das hat aber nichts mit dem allgemeinen Konzept IO-Port zu tun, sondern ist in den Tutorials und Artikeln zu der jeweiligen Hardware beschrieben.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 02. November 2009, 23:35 »
Hallo,


Mehr als in meinem Beitrag oben gibt es eigentlich dazu nicht zu sagen.
Naja, das stimmt nur oberflächlich betrachtet.
IO-Zugriffe sind deutlich langsamer, dafür könnten Memory-Mapped-IOs gecached werden. Jede Variante hat so ihre Vor- und Nachteile.
Zwei hintereinander folgende IO-Writes :mov dx,0x0370
mov al,11
out dx,al
out dx,al
werden immer beide komplett ausgeführt (nur so kann ein UART simpler funktionieren) wohingegen bei zwei hintereinander folgenden Speicherzugriffen wahrscheinlich der erste vom zweiten im CPU-Cache überschrieben wird und die Hardware deshalb nur den zweiten sieht. Bei Memory-Mapped-IO muss man mehr beachten dafür ists aber deutlich schneller, einer der Gründe warum moderne Hardware keine IO-Ports mehr hat.

Das der IO-Adress-Raum in Wirklichkeit 32Bit groß ist und nur der Befehlssatz der CPU das nicht unterstützt ist nur eine kleine Nebensächlichkeit am Rande.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

sebi2020

  • Beiträge: 130
    • Profil anzeigen
    • Infortus OS
Gespeichert
« Antwort #17 am: 03. November 2009, 08:06 »
Bei Memory-Mapped-IO muss man mehr beachten dafür ists aber deutlich schneller, einer der Gründe warum moderne Hardware keine IO-Ports mehr hat.
Wie wird dann auf die Hardware zugegriffen, über Memory-Mapped-IO?
Please press any-key...
Verflucht wo ist any-key? hier? ach Mist, das war Escape...

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 03. November 2009, 09:29 »
Hallo,

Wie wird dann auf die Hardware zugegriffen ....
So wie es im Datenblatt der betreffenden Hardware drin steht.
Ich wollte gestern Abend nur ein paar grundsätzliche Unterschiede (bzw. spezifische Eigenheiten) zwischen klassischem IO und Memory-Mapped-IO aufzeigen. Was Deine konkrete Hardware kann weis ich natürlich nicht.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

 

Einloggen