Autor Thema: binarys laden...  (Gelesen 18982 mal)

noob

  • Beiträge: 63
    • Profil anzeigen
Gespeichert
« am: 01. May 2006, 11:22 »
hi!

ich will nun mit meinem real mode os binarys also programme ausführen!(natuerlich single task) wie mache ich das am besten? wo finde ich dazu tuts?

danke!!

Legend

  • Beiträge: 635
    • Profil anzeigen
    • http://os.joachimnock.de
Gespeichert
« Antwort #1 am: 01. May 2006, 11:56 »
Also die erste Frage: Kannst du schon Dateien laden (nicht nur speziell Binarys)? Also z.B. ne Textdatei laden und auf dem Bildschirm ausgeben?
*post*

noob

  • Beiträge: 63
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 01. May 2006, 12:05 »
jep kann ich! mein fs (RLXFS) steht soweit hab schon pfadaufloesung und alles also das ist kein prob

DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 01. May 2006, 12:45 »
Du musst nur die Datei an einen freien Bereich im Arbeitsspeicher laden, evtl. ein paar Segment Register anpassen und dorthin springen. Damit das Programm dem OS mitteilen kann, dass es beendet werden kann solltest du noch eine entsprechende API-Funktion bereitstellen.

DOS sucht sich soweit ich weiß ein freies Segment raus, und lädt das Programm dann nach Segment:0x100. Man muss also dem Programm nur ein ORG 0x100 vorranstellen, damit die Adressierung funktioniert.

noob

  • Beiträge: 63
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 06. May 2006, 21:29 »
ok habs geschaft eine bin zu laden das broblem ist nur wie komm ich wieder in der kernel zurueck davon hab ich nun ueberhaupt keinen plan!!!!

thx

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 06. May 2006, 21:32 »
jmp segment:offset

wobei die adresse im kernel liegt.

oder

int 0x21

wobei 0x21 ein interrupt ist den du im kernel gehookt hast. (die zahl 0x21 darfst du beliebig gegen andere ungenutzte interrupts austauschen.)
Dieser Text wird unter jedem Beitrag angezeigt.

noob

  • Beiträge: 63
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 07. May 2006, 12:00 »
@PorkChicken tut mir leid das versteh ich nicht ganz...

was heisst:
Zitat

wobei 0x21 ein interrupt ist den du im kernel gehookt hast. (die zahl 0x21 darfst du beliebig gegen andere ungenutzte interrupts austauschen.)


kann ich das nicht auch mit einem far call machen?

und dann mit retf zurueckspringen?

bidde bidde zeigt mir wer wie ich zu der addresse 0x8000:0x0000 mit einem far call springen kann!!

DANKE!!

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #7 am: 07. May 2006, 12:14 »

call 0x8000:0x0000
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

Coffee

  • Beiträge: 470
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 07. May 2006, 12:21 »
na lol das war ja wohl nicht das problem oder :D

noob

  • Beiträge: 63
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 07. May 2006, 13:08 »
nee auf call 0x8000:0x0000 bin ich auch schon gekommen aber da sagt mir bochs dann: offset outside of CS limits und ich glaube dass da das proble ist das ich ueber ein e segmentgrenze springe und dadurch breuchte ich einen far jump....

noob

  • Beiträge: 63
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 07. May 2006, 16:36 »
hi!

hab nun einen far call gemacht das funkt auch ganz gut nur mit retf komm ich nich zurueck weis jemand wie viel ich zum stackpointer addieren muss damit ich bei der ruecksprungadresse bin???

danke

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 07. May 2006, 17:14 »
Wenn du einen Far-CALL gamacht hast, sollte das ret eigentlich ohne zusätzliches addieren des Stackpointers funktionieren.

Es könnte aber sein, dass SP irgendwo verändert wird, z.B. einmal wird etwas gepusht aber nicht mehr gepoppt usw. Und sonst wäre es gut wenn du mal ein bisschen Code bringen würdest.

Ansonsten kannst du das mit dem Beenden auch einfach so machen, dass du mit einem weiteren Far-Call wieder in den Kernel springst. Oder du dannst in der Interrupt-Table einen Interrupt anlegen, der auf den Kernel verweist. Dann musst du diesen Interrupt nur noch aufrufen und du bist wieder im Kernel.


Ich hoffe ich konnte helfen
Nooooooooooooooooooooos

noob

  • Beiträge: 63
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 07. May 2006, 18:12 »
ok ich hab verstanden... waenn ich einen interrupt handler hab, der im kernel ist, ... dann kann ich diesen aus dem programm aus aufrufen und komm dadurch in den kernel zurueck... un dkann dadurch dann im kernel weitermachen... sehe ich das so richtig!

wie schreibe ich aber solch einen interrupt handler? wie registriere ich diesen in der interrupt vektor tabelle? hat jemand vl ein tutorial dafuer?

ps: mein os is im real mode

Coffee

  • Beiträge: 470
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 07. May 2006, 18:13 »
LL3^^(glaube du meinst das)

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 07. May 2006, 18:23 »
Ja genau so. Das erstellen eines Interrups ist eigentlich nicht so schwer:

Die IVT liegt an der Stelle 0000:0000. Ein Eintrag (1 DW) für einen Interrupt enthält die logische Adresse vom Ziel des Interruptaufrufs. Wenn du nun einen Interrupt definieren willst, musst du zuerst einen freien Interrupt suchen (z.B. 0x30). Und dann musst du dorthin das DW mit der Adresse des Interrupt-Handler schreiben. Beispiel:mov ax,0x0
mov dx,ax
mov DWORD[0x30],ADRESSE


Gruss
Noooooooooooos

stafe

  • Beiträge: 35
    • Profil anzeigen
    • http://www.staticos.at.tf
Gespeichert
« Antwort #15 am: 08. May 2006, 14:30 »
Hallo,

Du musst eingach einen freien Interrupt verwenden um dem Kernel Informationen zu übergeben. Bsp.: int 0x33

Du müsstest bei deinen ISRs einen ISR für deinen Systemintrrupt einbauen von dem aus du eine funktion aufrufst mit der du die übergebenen Infos verarbeiten kannst:

Bsp.:

[ASM]
...


extern _system_int
global _dein_int
_dein_int:
cli
call _system_int
sti
iretd



In der Funktion system_int() kannst du dann die von deinem Programm veränderten Register (eax,ebx,ecx,edx) auslesen (mit inline ASM) und die Informationen verarbeiten. In meinem OS habe ich es so gemacht dass ich in eax die INT_Funktion (also was das OS tun soll) schreibe und (ebx,ecx,edx) als Parameter verwende.

[C]
...

void system_int()
{
unsigned long EAX,EBX,ECX,EDX;

// Infos aus Registern holen, und in EAX,EBX,... speichern

if( EAX == 0x01 )
Textausgabe( "Hallo Welt" );
}


So jetzt müsstest du noch ein kleines Programm schreiben das den Systeminterupt aufruft und eax auf 1 setzt ... Dann müsste am Bildschirm der Text "Hallo Welt" zu sehen sein. Hier nochn kleines bsp. wie das Programm aussehen könnte:

[C]

int main()
{
asm( "movl $0x1,%eax" );
asm( "int $0x33" ); // Statt int 33h musst du deinen SYSINTERRUPT angeben

while( 1 );
return;
}


Wenn du das hast erstellst du eine Binary und lädst diese an eine geeignete Speicherstelle in deinmem OS ... anschließend musst du nur noch zu dieser Speicherstelle springen und dein Programm wird ausgeführt ... Hoffe ich konnte dir weiterhelfen ...
mfG Stafe

noob

  • Beiträge: 63
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 08. May 2006, 20:51 »
ok da verstehe ich nun danke!

aber ich kann leider in das mov keine 0x1000:0x810F(dort ist die addresse meiner funktion) reinschreiben wie bekomme ich das auf eine addresse damit ich es im mov verwaenden kann?

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 08. May 2006, 21:07 »
Ich würd das mal so machen aber sicher bin ich mir nicht:mov ax,Segment
sal eax,16
mov ax,Offset


Gruss
Nooooooooooos

noob

  • Beiträge: 63
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 08. May 2006, 21:12 »
Zitat von: nooooooooos
Ich würd das mal so machen aber sicher bin ich mir nicht:mov ax,Segment
sal eax,16
mov ax,Offset


Gruss
Nooooooooooos


koenntest du mir das erklaeren das versteh ich nicht....

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 09. May 2006, 12:28 »
Also ich würde denken, dass in diesem DWORD an höherer Stelle das Segment und an niedriger Stelle das Offset stehen muss. (Da bin ich mir aber nicht 100% sicher; Es könnte ev. auch umgekehrt sein)
Das sähe dann so aus:
|||||||||||||||| ||||||||||||||||
\  SEGMENT     /  \ OFFSET     /

Beim hereinschreiben der Daten in EAX ergibt sich ein kleines Problem. Die höheren 16-Bits von EAX kann man leider nicht separat ansprechen. Das geht NUR mit dem niedrigerem Teil, welchen man mit ax anspricht. Etwa so:
32Bit eax |||||||| |||||||| |||||||| ||||||||

16Bit ax                    |||||||| ||||||||

8Bit ah/al                  \ AH  /  \ AL   /      

Darum müssen wir das Segment (muss ja in den höheren Teil) zuerst in den niedrigeren Teil von EAX schreiben und dann mittels Schiebebefehlen (in diesem Falle SAL) in den höheren Teil befördern.

Dann müssen wir noch das Offset in den niedrigeren Teil von eax schreiben, was ja auch ohne Probleme geht.

Dann haben wir in EAX die Daten welche wir dann, wie gesagt so in die IVT schreiben:mov ax,0x0
mov dx,ax
mov DWORD[0x30],ADRESSE


Gruss
Nooooooooooos

 

Einloggen