Lowlevel

Lowlevel => Lowlevel-Coding => Thema gestartet von: noob am 01. May 2006, 11:22

Titel: binarys laden...
Beitrag von: noob 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!!
Titel: binarys laden...
Beitrag von: Legend 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?
Titel: binarys laden...
Beitrag von: noob am 01. May 2006, 12:05
jep kann ich! mein fs (RLXFS) steht soweit hab schon pfadaufloesung und alles also das ist kein prob
Titel: binarys laden...
Beitrag von: DarkThing 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.
Titel: binarys laden...
Beitrag von: noob 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
Titel: binarys laden...
Beitrag von: Jidder 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.)
Titel: binarys laden...
Beitrag von: noob 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!!
Titel: binarys laden...
Beitrag von: bluecode am 07. May 2006, 12:14

call 0x8000:0x0000
Titel: binarys laden...
Beitrag von: Coffee am 07. May 2006, 12:21
na lol das war ja wohl nicht das problem oder :D
Titel: binarys laden...
Beitrag von: noob 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....
Titel: binarys laden...
Beitrag von: noob 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
Titel: binarys laden...
Beitrag von: nooooooooos 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
Titel: binarys laden...
Beitrag von: noob 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
Titel: binarys laden...
Beitrag von: Coffee am 07. May 2006, 18:13
LL3^^(glaube du meinst das)
Titel: binarys laden...
Beitrag von: nooooooooos 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
Titel: binarys laden...
Beitrag von: stafe 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 ...
Titel: binarys laden...
Beitrag von: noob 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?
Titel: binarys laden...
Beitrag von: nooooooooos 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
Titel: binarys laden...
Beitrag von: noob 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....
Titel: binarys laden...
Beitrag von: nooooooooos 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
Titel: binarys laden...
Beitrag von: noob am 09. May 2006, 19:33
danke habs hingebracht!!

aber nun muss mein kernel auch wieder den gewohnten verlauf nehmen koenen wie mach ich das am besten dass mein kernel dann wieder so weiterlauft wie gehabt... ich kann zwar wieder in funnktionen im kernel springen doch die funken nicht mehr so wie sie sollten...
Titel: binarys laden...
Beitrag von: nooooooooos am 09. May 2006, 20:18
Ja das ist schwierig.....
Könntest du mal ein bisschen Code von deinem Kernel posten (nur die Hauptroutine)??

Aber du könntest deinen Interrupt so machen, dass er nicht direkt auf den Kernel zeigt, sondern in eine eigene Routine. Diese Routine verändert die Rücksprung-Adresse auf dem Stack dann so, dass mittels IRET in den Kernel gesprungen wird.

Ein anderes Problem könnte sein, dass du einen nicht freien Interrupt benützt. Ich würde da einen über  0x30 nehmen.


Gruss
Nooooooooooos
Titel: binarys laden...
Beitrag von: nore am 10. May 2006, 21:12
wie wäre es denn mit einer kleinen routine im kernel, die einfach den stackpointer erhöht, um die rücksprungadresse des ints zu löschen? die wird per int angesprochen und steht direkt vor der stelle, an der es nach dem programm weitergehen soll.
Titel: binarys laden...
Beitrag von: noob am 17. May 2006, 20:36
ich hab noch ne frage wie geb ich den interrupt in der IVT genau an ich wollte den interrupt

0x31 haben den hab ich folgendermassen in der IVT registriert:

 printf("Initialisiere Interrupts...");
   
    int buffer = ds;

    edx=(cs<<16)+interruptHandler;
    asm{
        mov cx,0x0
        mov ds,cx
        mov dword ptr[0xC4], edx
    }

    ds = buffer;

    printf("OK\n");


kann das so stimmen?

waenn ich dann in den interrupt springe und die ausgabe aufrufe:

int interruptHandler(void){
    konsole_main();

    printf("hallo\n");

    asm{
        siret
    }
}

kommen lauter so komische zeichen die eingabe funkt aber komischerweise nur irgendwo aufm bildschirm wird der curser gesetzt und dann kann man weiterschreiben...... was kann ich machen damit ich da sauber wieder rauskomme? ich glaub da muss ich irgendwas aufm stack aendern damit das ganze wieder passt oder? bidde bidde helft mir...
danke!

@nore tschuldigung aber ich kann dir nicht ganz folgen... ich will vom int aus ja gar nicht mehr zurueckspringen ich will wieder in den kernel springen
Titel: binarys laden...
Beitrag von: Jidder am 18. May 2006, 01:15
Keine Ahnung. Kommt auf den Compiler an. Du solltest dir die Dokumentation anschauen, oder die Disassembly.

Du brauchst unbedingt einen Wrapper, denn du darfst nicht einfach so Register ändern. Du musst sie vorher sichern. Das einfachste wäre den Wrapper für Interrupthandler komplett in Assembler zu schreiben. Meinetwegen auch Inline Assembler:

printf("Initialisiere Interrupts...");
   
    int buffer = ds;

    asm {
         jmp skip_wrapper
wrapper:
         pusha
         push ds
         push es
         push fs
         push gs
         call interruptHandler
         pop gs
         pop fs
         pop es
         pop es
         popa
         iret ; <------- das iret in dem handler brauchst du dann nicht mehr
skip_wrapper:
    }

    edx=(cs<<16)+wrapper;
    asm{
        mov cx,0x0
        mov ds,cx
        mov dword ptr[0xC4], edx
    }

    ds = buffer;

    printf("OK\n");


(achja ungetestet und guck auch auf die uhrzeit ^^)
Titel: binarys laden...
Beitrag von: bitmaster am 18. May 2006, 01:31
Zitat
(achja ungetestet und guck auch auf die uhrzeit ^^)
Jo, sollte wohl ein "pop es" durch ein "pop ds" ersetzt werden. ;)

bitmaster
Titel: binarys laden...
Beitrag von: Jidder am 18. May 2006, 11:38
jupp und die Flags sollten auch noch gepusht und gepoppt werden. ;)
Titel: binarys laden...
Beitrag von: bitmaster am 18. May 2006, 12:09
Zitat von: PorkChicken
jupp und die Flags sollten auch noch gepusht und gepoppt werden. ;)
^^ Nee, das macht der "int" Befehl automatisch. Der legt die Flags und die Rücksprungadresse auf dem Stack. Der "iret" springt dann zurück und läd die Flags wieder.

bitmaster
Titel: binarys laden...
Beitrag von: Jidder am 18. May 2006, 12:53
Richtig ... naja die Uhrzeit, die Uhrzeit ... ;)
Titel: binarys laden...
Beitrag von: bitmaster am 18. May 2006, 13:36
Zitat von: PorkChicken
Richtig ... naja die Uhrzeit, die Uhrzeit ... ;)
Die Uhrzeit war 10:38 Uhr. ^^
Titel: binarys laden...
Beitrag von: Jidder am 18. May 2006, 14:09
nee, da hab ich noch geschlafen. Wenn dann 11:38 Uhr (wir haben Sommerzeit), also kurz nach dem Aufstehen. Da bin ich noch nicht ganz so fit. ;)
Titel: binarys laden...
Beitrag von: noob am 18. May 2006, 20:55
Zitat von: PorkChicken

printf("Initialisiere Interrupts...");
   
    int buffer = ds;

    asm {
         jmp skip_wrapper
wrapper:
         pusha
         push ds
         push es
         push fs
         push gs
         call interruptHandler
         pop gs
         pop fs
         pop es
         pop es
         popa
         iret ; <------- das iret in dem handler brauchst du dann nicht mehr
skip_wrapper:
    }

    edx=(cs<<16)+wrapper;
    asm{
        mov cx,0x0
        mov ds,cx
        mov dword ptr[0xC4], edx
    }

    ds = buffer;

    printf("OK\n");



erstmal danke PorkChicken fuer deine antwort aber eins verstehe ich nicht... mit jmp skip_wrapper ueberspringst du ja alle pushs und popps? weiters frage ich mich warum muss ich alle segment register sichern ich nehm doch nur ds her... tja und wo genau soll ich diesen wrapper hernehmen? waenn ich den interrupt aufrufe? das kann ich mir nicht vorstellen denn ich brauch ja sowieso wieder einen anderen stack im kernel ich will ja von meinem interrupt aus nicht mehr zurueck in das programm...

tja... entschuldigt meine begriffstutzigkeit aber ich kann erst was programmieren waenn ichs verstehe...

danke nochmal fuer eure super hilfe!!
Titel: binarys laden...
Beitrag von: bitmaster am 18. May 2006, 23:02
@noob: Sorry, aber scheinst noch nicht viel mit OS Programmierung am Hut zu haben. Ja man springt zum "skip_wrapper" um dem Interrupt die Adresse zuzuweisen. Da wird da ja noch nicht ausgelöst. Erst wenn du mit "int XXh" den aufrufst, wird der Code mit den push/pop's ausgeführt. Warum er alle Segmentregister abspeichert? Weil er/wir ja nicht wissen was der code von "interruptHandler" macht. Wenn der natürlich nur ds verändert, brauchst du die anderen nicht abspeichern.

bitmaster
Titel: binarys laden...
Beitrag von: bitmaster am 18. May 2006, 23:03
Zitat von: PorkChicken
nee, da hab ich noch geschlafen. Wenn dann 11:38 Uhr (wir haben Sommerzeit), also kurz nach dem Aufstehen. Da bin ich noch nicht ganz so fit. ;)
so so ^^
Titel: binarys laden...
Beitrag von: noob am 19. May 2006, 11:40
Zitat von: bitmaster
@noob: Sorry, aber scheinst noch nicht viel mit OS Programmierung am Hut zu haben.
bitmaster


tja aber es ist einfach so dass ich gerne nachfage... ausserdem kann man sich das ganze ja so nicht wirklich aus tutorials lernen kann... :-( tja und mit dem os will ich mich in die os entwicklung ja einarbeiten!!!

mfg noob
Titel: binarys laden...
Beitrag von: Jidder am 19. May 2006, 12:22
der code ist natürlich nur zur veranschaulichung. ich würde nicht unbedingt interrupthandler in andere funktionen einbetten. weil ich es aber getan habe, muss ich über diesen interrupthandler (genauer: den wrapper) rüberspringen, damit er nicht ausgeführt wird, wenn die umgebende funktion ausgeführt wird.

besser ist es die wrapper in externe assembler-dateien zu tun.
Titel: binarys laden...
Beitrag von: bitmaster am 19. May 2006, 13:03
Zitat von: PorkChicken
der code ist natürlich nur zur veranschaulichung. ich würde nicht unbedingt interrupthandler in andere funktionen einbetten. weil ich es aber getan habe, muss ich über diesen interrupthandler (genauer: den wrapper) rüberspringen, damit er nicht ausgeführt wird, wenn die umgebende funktion ausgeführt wird.

besser ist es die wrapper in externe assembler-dateien zu tun.
Jo, sehe ich genau so. Aber er will doch bloß ein Interrupt (vielleicht nicht mal ein ganzer sondern nur ein Teil, also eine Nummer die man z.B. in eax oder ax, ah, al oder so angibt) der die laufende Datei beendet und zum kernel oder shell zurückspringt. Also ich glaube der möchte sowas in der Art:

cmd>: programm.exe ;Beispiel startet programm.exe

code von programm.exe:

... ;beliebiger Code
mov ax,0 ;ende z.B. Funktion 0
int 21h ;z.B. Interrupt 21h


der Code der Funktion 0 des int 21h springt dann zurück zur Shell

cmd>: ;da möchte er wieder hin

Der Code der Funktion 0 des int 21h bräuchte dann ja nur z.B. so aussehen:

int21h_0000h:
mov ax,1000h ;Segment der Shell
mov ds,ax
mov es,ax
mov ax,2000h ;Stack Segment
mov ss,ax
mov sp,0FFFFh ;Stackoffset
jmp 1000h:Shelloffset ;Shelloffset = stelle in der Shell die "cmd>: " neu zeichnet und auf neue Eingabe wartet



So das ist ein Beispiel wie ich vermute was er haben möchte.


bitmaster
Titel: binarys laden...
Beitrag von: noob am 19. May 2006, 19:53
hi!

ich hab nun alles ausprobiert aber es funkt leider nicht :-( aber ich habe eine idee! immer waenn ich den interrupt aus dem kernel heraus aufrufe dann kann ich einfach mit konsole(); in meine konsole zurueckspringen und es funkt wunderbar... aber waenn ich das aus der applikation herausmache dann geht es nicht :-( nun stellt sich fuer mich die frage was anedert sich und ich bin zu dem schluss gekommen das es irgendwie was mit dem stack hat... wie kann ich den nach dem aufruf wieder in den originalzustand zurueckversetzen?

danke!
Titel: binarys laden...
Beitrag von: nooooooooos am 19. May 2006, 20:47
Das ist schwer zu sagen. Kommt drauf an, wie du den Code lädst. Kann aber sein dass über den Interrupt das Segment oder die Flags gewechselt werden.
Titel: binarys laden...
Beitrag von: noob am 27. May 2006, 14:19
hi!

laden tu ich die bin folgendermassen:


int loadBin(char *paht){
    int seg = 0;
    int lsn = analytePath(paht);
    int i;

printf("%d\n", lsn);
   
    asm{
        mov ax, 0x8000
        mov es, ax
    }

    for(i = 0; i < 20; i++){
        readBin(seg, ((lsn) / 18) % 2, (lsn) / 36, ((lsn) % 18) +1, 1);
        seg+=512;
        lsn++;
    }

    asm {
        fcall 0x8000,0x0000
    }

    printf("_\n");

    return -1;
}


so das prog wird auch richtig geladen...

aber wie bekomm ich meine Einstellungen (stack,etc...) wieder zurueck?

danke...
Titel: Booten mit Bochs
Beitrag von: DePabba am 28. May 2006, 19:23
Hallo,

habs jetzt mich Bochs probiert.
Funktioniert einwandfrei.
Keine Ahnung, warum der PC das nicht booten will.
Aber das hier ist eh einfachar und reicht mir auch zum testen.

Danke Leutz.

Gruß
DePabba


SORRY: Falscher Thread