Ein eigenes kleines Betriebssystem
-
Hallo! Vielleicht bin ich hier nicht rcihtig, verzeit! Aber es gibt auf Tutorials.de so nen Beitrag: http://www.tutorials.de/forum/programming-tutorials/20706-ein-eigenes-kleines-betriebssystem.html
Klappt auch wunderbar, aber wie kann ich nun aus dem Bootsector herausspringen. 512 Bytes sin sehr wenig! Eine Frage: Geht das überhaupt? Wenn Ja, wie? (Bitte erklärung for Dummies
)
-
Habe es nur ueberflogen, aber sieht so aus, als wuerde das dort auch behandelt. Punkt 4. Eine Interrupt-Liste (zB. die von Ralf Brown) gibt dann genauere Auskunft ueber den int 13h.
Sonst bitte konkreter fragen. Im Gegensatz zu der von dir verlinkten Seite spezialisieren wir uns hier eher nicht auf das Verfassen von Tutorials zum Zeitvertreib.[OT]
Toll zu sehen, dass sich dieses cli/sti um das Einrichten des Stacks immer noch so hartnaeckig haelt...[/OT]
-
Danke für das! Jetzt die Konkrete frage: Wie kann ich mit Assembler z.B. auf Sektor 5 einer Diskette "linken", Also verweißen? Das geht ja mit int 13h, oder?
-
cpp_1 (anderer PC) schrieb:
Wie kann ich mit Assembler z.B. auf Sektor 5 einer Diskette "linken", Also verweißen? Das geht ja mit int 13h, oder?
Noe. Geht so nicht. Assembler spiegelt den Befehlssatz der CPU wieder und die kennt keine konkreten Datentraeger wie Disketten mit Sektoren, etc.
Die Funktionen des int 13h sind vor allem dazu gut, zum Lesen oder Schreiben auf Datentraeger (Festplatte oder Diskette) zuzugreifen.
Um nun ein Programm auf deiner Diskette zu starten, musst du es zuerst via int 13h in den Speicher laden und anschliessend an die entsprechende Stelle im Speicher springen.Konkret musst dazu erstmal das Diskettenlaufwerk zuruecksetzen mit int 13h, Funktion 0 (siehe dein Tutorial, Punkt 4, wo die Laufwerksnummer fuer dl herkommt - fuer das erste FDD ist es aber idR. 0).
Dann kannst du mit int 13h, Funktion 2 Sektoren von der Diskette in den Speicher einlesen.
Nach dem fuer int 13h erstmal verwendeten CHS-System waere "Sektor 5" praktisch Head 0, Cyl 0, Sector 5. Praktisch istz dazu vielleicht noch zu wissen, dass ein normales 1.44MB-Floppy idR. 18 Sektoren/Cyl und 2 Heads hat.Also al = 1 (number of sectors to read (must be nonzero))
CH = 0 (low eight bits of cylinder number)
CL = 5 (sector number 1-63 (bits 0-5) high two bits of cylinder (bits 6-7, hard disk only))
DH = 0 (head number)
DL = 0 (1st FDD - drive number (bit 7 set for hard disk))
ES:BX -> data buffer (wo auch immer du es hinhaben moechtest - sinnvoll waere idR. eine Adresse irgendwo zwischen 0x08000 (darunter liegt zT. BIOS-Zeug und die IVT) und 0xA0000 (ab hier startet die VGA).
-
Moin, Moin...
Nobuo T schrieb:
[OT]
Toll zu sehen, dass sich dieses cli/sti um das Einrichten des Stacks immer noch so hartnaeckig haelt...[/OT]
Klär mich doch bitte auf: Was ist so verwerflich an cli/sti, um den Stack einzurichten? Was sonst?
Gruß
Kal El
-
Ich glaube er meint, dass beim verändern des %SS die Interrupts sowieso für ein paar Takte gesperrt werden.
-
Richtig. Eine Anordnung wie
mov ss, x
mov sp, y
mit cli/sti einzurahmen ist daher etwas ueberfluessig.
-
Hallo Sososo und Nobuo T,
danke für die Info. Man lernt doch immer etwas dazu. Dass die Interrupts gesperrt werden, wenn man das Register SS ändert, war mir neu. Tja, man sollte eben die Handbücher gründlicher lesen.
Gruß
kal
-
kann man dich auch irgendwie per email oder instant messenger antreffen?
-
Email möchte ich nicht bekanntgeben und verfüge nicht über einen Instant Messenger! Tut mir leid!
-
Dann mach dir doch einfach schnell ein Googlemail Account oder so.
Es könnte ja sein, dass er etwas nützliches zu sagen hat.
-
Also, wie ich schon sagte, kann ich Assembler nicht gut (besser gesagt nicht
) und habe mir jetzt mal nen code zusammengebastelt, der nicht funktioniert (ich gleube ich habe was falsch verstanden). Bitte kann mir jemand den Code so umändern, dass er auch gehen würde und sagen was ich falsch gemacht habe. Danke.
org 0x7C00 call diskreset call kerneltoram call callkernel diskreset: int 13h AH=00h DL = 0 kerneltoram: int13h AH=02h AL = 1 CH = 0 CL = 5 DH = 0 DL = 0 ES:BX -> 0x08000 callkernel: mov ax,0x1000 mov es,ax mov bx, 0 mov ah, 2 mov al, 5 mov cx, 2 mov dx, 0 int 13h times 512-($-$$)-2 db 0 dw 0AA55h
-
schwierig hier anzufangen
was du gepostet hast, is nur zum teil assembler. außerdem fehlen returns in deinen funktionen...
schade, dass du nicht erreichbar bist. 43f699d2986b8a2f9467cc3e3204@gmx.net wäre meine adresse. ich lass sie mal eine zeit lang funktionierend.
-
cpp_1 schrieb:
(ich gleube ich habe was falsch verstanden)
Ich glaube eher, du hast davon gar nichts verstanden. :p
Daher auch meine Empfehlung: Nimm dir erstmal ein Anfaengertutorial oder Buch vor (siehe FAQ) und versuche dann beim Originalcode aus dem OS-Tutorial genau nachzuvollziehen was jede einzelne Zeile macht, und denke dann zB. mit meinen Hinweisen zu Interrupts vielleicht nochmal darueber nach, warum dies und das nun gemacht wurde.cpp_1 schrieb:
Bitte kann mir jemand den Code so umändern, dass er auch gehen würde und sagen was ich falsch gemacht habe.
Geht so nicht. Bei deinem Code ist nicht wirklich erkennbar, was er denn eigentlich machen sollte.
Deshalb beschraenke ich mich mal darauf, deinen Code ein wenig zu kommentieren...org 0x7C00 call diskreset call kerneltoram call callkernel ; ok so weit... diskreset: int 13h ; Das ist ein Assembler Mnemonic. Ruft int 13h auf. ; Ist an dieser Stelle aber reichlich nutzlos, da du VORHER nicht die ; richtigen Parameter in die Register geschrieben hast. AH=00h ; Das ist dagegen eine ungueltige Anweisung, also weder ein ;x86-Mnemonic, noch eine NASM Assembler-Anweisung. DL = 0 ; Dito. ; Da das Ganze hier wohl eine abgeschlossene Prozedur sein sollte, waere es ; sinnvoll, hier einen passenden Return-Befehl einzubauen, sonst laeuft ; es einfach weiter in die folgende Prozedur rein... kerneltoram: int13h ; Alles Folgende sind ungueltige Anweisungen AH=02h AL = 1 CH = 0 CL = 5 DH = 0 DL = 0 ES:BX -> 0x08000 ; kein Return aus der Prozedur - genau wie oben. callkernel: mov ax,0x1000 ; wow, ein paar gueltige Mnemonics... mov es,ax ; warum du die hier eingefuegt hast, wird aber wohl dein mov bx, 0 ; Geheimnis bleiben. mov ah, 2 ; Dieses Stueck code wuerde 5 Sektoren, beginnend bei 0:0:2 mov al, 5 ; von 1. Diskette in den Speicher nach 1000:0000 einlesen. mov cx, 2 mov dx, 0 int 13h ; hier wieder kein Ruecksprung, ueberhaupt keine folgenden Anweisungen mehr ; => was der PC als naechstes macht ist weitgehend undefiniert, wahrscheinlich ; wird es irgendwann abstuerzen oder in einer Endlosschleife landen. times 512-($-$$)-2 db 0 ; ok zum Abschliessen eines Bootsektors... dw 0AA55h
-
Nobuo T schrieb:
mov ax,0x1000 ; wow, ein paar gueltige Mnemonics...
musst du auch noch salz in die wunde streuen?
-
Ok, ich habe verstanden, dass ich keine Ahnung habe. Aber könnte jetzt mal jemand auch noch einen funktiniernden Code posten? Bitte! Ich wäre euch sehr dankbar!
-
Da hast du:
org 0x7C00 start: mov ax, 0x9000 ; Adresse des Stack speichern mov ss, ax ; Stackadresse festlegen mov sp, 0 ; Stackpointer auf 0 setzen mov [bootdriv], dl call load mov ax, 0x1000 ; 0x1000 ist die Speicheradresse unserer Shell mov es, ax mov ds, ax push ax mov ax, 0 push ax retf bootdriv db 0 ; Das Bootlaufwerk loadmsg db "Lade VitaXia...",13,10,0 ; Mit dieser Funktion geben wir einen String aus putstr: lodsb or al,al jz short putstrd mov ah,0x0E mov bx,0x0007 int 0x10 jmp putstr putstrd: retn ; Mit dieser Funktion laden wir unsere Shell vom Bootlaufwerk load: push ds mov ax, 0 mov dl, [bootdriv] int 13h pop ds jc load load1: mov ax,0x1000 mov es,ax mov bx, 0 mov ah, 2 mov al, 5 mov cx, 2 mov dx, 0 int 13h jc load1 mov si,loadmsg call putstr retn times 512-($-$$)-2 db 0 dw 0AA55h
c&p aus deinem Tutorial - hab ich nicht getestet, sieht aber so weit ok aus.
Und nun?
-
Und wo verweißt dieser Code jetzt auf Sektor 5 der Diskette?
-
mov al, 5
-
Werde es später ausprobieren, berichte aber heute noch ob es geklaptt hat...