Beiträge anzeigen

Diese Sektion erlaubt es dir alle Beiträge dieses Mitglieds zu sehen. Beachte, dass du nur solche Beiträge sehen kannst, zu denen du auch Zugriffsrechte hast.


Nachrichten - [MM]

Seiten: 1 2 [3] 4 5 ... 7
41
Offtopic / Lernen
« am: 19. February 2006, 22:01 »
Ich kann was den Anfang beim OS-Dev angeht nur auf das PM-Tutorial meiner hochgeschätzten Lehranstalt verweisen:
http://www.fh-zwickau.de/doc/prmo/pmtutor/text/index.htm

MM
42
Lowlevel-Coding / Eigener C++ Compiler
« am: 19. February 2006, 21:54 »
Hallo, habe in den letzten Tagen meinen aktuellen C-Compiler zu einem C++ Compiler aufgebohrt. Neben C und Assembler Code kann man nun auch die meisten fortgeschrittenen Techniken der OO nutzen (ich hatte keine Lust mir eine Lib für dynamische Listen in C zu schreiben, da man mit C++ ja auch einfach eine Klasse List machen kann...).

Wäre nett, wenn der Eine oder Andere sich das Teil mal ansehen würde und mir seine Meinung schreibt (oder auch wenn was nicht geht):
http://wwwstud.fh-zwickau.de/~micmo/compiler.html
oder direkt
http://www.fh-zwickau.de/~micmo/files/coding/dc2.zip

MM
43
Lowlevel-Coding / Seltsamer Opcode von loop
« am: 17. February 2006, 20:00 »
Im Real-Mode sind 16-Bit Daten und Adressen Default. Im Protected-Mode wird das durch das D-Bit im Codedescriptor bestimmt.
Beispiel aus dem Real-Mode:
2477:0100 66B800000000    mov     eax,00000000
Wie man hier gut sehen kann wird der Operand Size Override (0x66) benutzt um anstelle von ax auf eax zuzugreifen. läßt man ihn weg wird der Befehl als mov ax,0 interpretiert (wodurch aber 2x 0x00 dahinter übrig wären...).

Und ich würde für solche Experimente auch nicht unbedingt einen Hexeditor nehmen, sondern einen 32-Bit Debugger (ich würde den DDEB empfehlen).

@bitmaster:
Ja, die Idee hatte ich auch schon, dass ja sowohl ein Register als auch eine Adresse daran beteiligt sind, jedoch finde ich es trotzdem unlogisch dann mit der 0x67 dafür zu sorgen ecx zu benutzen und nicht wie bei jedem anderen Befehl mit der 0x66.

MM
44
Lowlevel-Coding / Assembler
« am: 17. February 2006, 19:53 »
Hallo, ich benutze die RHIDE vom DJGPP. Die hat eigentlich alles was man braucht wie erweiterbares Syntax Highlighting oder Makro Funktionen.

MM
45
Lowlevel-Coding / Seltsamer Opcode von loop
« am: 17. February 2006, 15:50 »
Der Code ist bei beiden nicht gleich, deshalb habe ich ja dazu geschrieben welches Prefixbyte ich benutz habe:
Mit Prefix 0x66:
0F10:0100 66B901000100    mov     ecx,00010001
0F10:0106 66E2FD          loop    0106


Mit Prefix 0x67:
0F10:0100 66B901000100    mov     ecx,00010001
0F10:0106 67E2FD          loop    0106


Und die Frage bezieht sich auch nicht auf einen bestimmten Assembler sondern DIREKT auf den Opcode. Mich interessiert also nicht, ob zB der masm das automatisch richtig macht oder so, sondern wie ich sagte: warum der "Address Size Override" benutzt wird um ecx anstelle von cx zu benutzen.

MM
46
Lowlevel-Coding / Seltsamer Opcode von loop
« am: 17. February 2006, 01:09 »
Hallo, ich habe heute mit erstaunen festgestellt, dass beim loop Befehl die Bedeutung der Prefix-Bytes offenbar umgedreht zu sein scheint:
Dieser Code geht nur ein mal durch die Schleife (ich gehe von einem 16-Bit Codesegment aus (gelöschtes D-Bit) oder im RealMode):
mov ecx,0x10001
mark:
loop mark ; Mit Prefix 0x66


Dieser Code geht 0x10001 mal durch die Schleife:
mov ecx,0x10001
mark:
loop mark ; Mit Prefix 0x67


Laut Intel ist der Prefix 0x66 für Operand Size Overrides und 0x67 für Address Size Overrides. Warum wird also wenn ich ecx ansprechen will der Prefix für das Ändern der Adressgröße verwendet und nicht das für den Operand?

Damit ist aber noch nicht genug: Wenn ich das Loop in einem Codeteil verwenden will der an einer Adresse über 0xFFFF liegt, so muss ich den Prefix 0x66 (zusätzlich) verwenden. Ich hätte die Belegung der beiden Präfixe genau umgekehrt erwartet.

Könnte da Jemand zur Klärung beitragen?

MM
47
Lowlevel-Coding / Zeiger auf lokale Variablen
« am: 11. February 2006, 18:49 »
Hm, stimmt da gibt es ja das Bit No. 2 (User/Supervisor). So sollte es gehen...

MM
48
Lowlevel-Coding / Zeiger auf lokale Variablen
« am: 11. February 2006, 18:04 »
Ja, dass das mit einem flachen Speichermodell am einfachsten funktioniert sehe ich auch so, nur wie ließen sich dann Parameter bei API-Aufrufen von der Applikation an den Kernel weiterreichen (wenn beide je ihren eigenen 4GB Adressraum hätten)?
Ich meine wenn die Anwendung zB einen Zeiger auf die Adresse 0x1234 übergibt und der Kernel dann seine eigene Pagetabelle läd um arbeiten zu können, dann liegt da ja was ganz anderes (wie könnte man die Kernelfunktion so überhaupt aufrufen, wenn sie nicht im virtuellen Adressraum der Anwendung liegt?).
Wäre es da nicht sinnvoll wenn der Kernel mit seinem Code/Daten/Stack/Heap zB bei 0-512MB liegt und alle Anwendungen den Bereich von 512MB-4GB nutzen würden?
Wobei ich mir aber noch nicht ganz sicher bin, wie man dann den Bereich von 0-512MB schützen sollte, da wenn man ihn einfach in der Pagetabelle der Anwendung freilassen würde ich ja auch nicht per Interrupt in das Codesegment des Kernels springen könnte.
Hast du da auch eine Idee SSJ7Gohan?

MM
49
Lowlevel-Coding / Zeiger auf lokale Variablen
« am: 11. February 2006, 14:10 »
Hallo, ich bin grade am Grübeln wie man das folgende Problem am besten Lösen kann:
Mal angenommen man hat diese zwei Funktionen:

int gvar;
void func(int *ptr){
  *ptr=0;
}
void main(void){
  int lvar;
  func(&lvar);
  func(&gvar);
}

Die Variable lvar befindet sich auf dem Stack und gvar im Datensegment. Wenn man nun keine Far-Zeiger verwendet (also nur 32-Bit Adressen) so müssen Stack und Datensegment sich ja überlappen, so dass man auch mit ds: auf die Adresse von lvar zugreifen kann (der Stack befindet sich also im Datensegment).
Weiß jemand von euch, wie dieses Problem zB bei Windows gelöst wird? Eventuell genauso?

Für normale Anwendungen funktioniert dieses Konzept zumindest recht gut, jedoch jetzt will ich einen Kernel schreiben, dessen API-Funktionen per Interrupt aufgerufen werden. Das Problem ist nun, dass ich zwar das Datensegment des Kernels in der API-Funktion laden kann, jedoch weiterhin das Stacksegment des Aufrufers benutzen muss. Dadurch würde das Programm abstürtzen, wenn wie in func() auf einen Zeiger einer lokalen Variable zugegriffen würde.
Wie könnte man dieses Problem am elegantesten lösen?

MM
50
Lowlevel-Coding / Welchen Assembler nehmt ihr?
« am: 25. January 2006, 20:37 »
Ich benutze als IDE die RHIDE vom DJGPP und als Assembler/C-Compiler meinen selbstgeschriebenen DC2 da ich so ein Maximum an Kontrolle darüber habe wie der Code erstellt wird. Außerdem kann ich ja jederzeit neue Funktionen oder Befehle einbauen falls sie benötigt werden.
Und die RHIDE benutze ich weil ich für LowLevel-Programmierung irgendwie auf den TurboC Charme stehe.

MM
51
OS-Design / Idee für Kernelmodule
« am: 08. January 2006, 13:05 »
Du meinst also, dass deine Module dann immer virtuell an der gleichen Adresse liegen?
Interessant, aber was würde passieren, wenn dein Modul einen Zeiger auf irgendwelche globalen Daten des Moduls an ein anderes Modul weiterreicht? Dann stünde an der Adresse ja was ganz anderes...

MM
52
OS-Design / Idee für Kernelmodule
« am: 07. January 2006, 21:25 »
Hallo, ich habe vor diverse Funktionen meines Kernels in Module auszulager und mein bisheriges Konzept sah so aus, dass ich im Datensegment des Kernels beim Laden eines Moduls speicher allociere und das Modul an diese Stelle lade. Dann wird ein Codesegment eingerichtet, welches den Code des Moduls umfasst (immernoch im Kerneldatensegment). Als Daten und Stacksegment soll das des Kernels mitbenutzt werden. Um auf globale Daten des Moduls zugreifen zu können (welche per standard ja bei Offset 0 beginnen würden) habe ich es so gemacht, dass in Modulen beim Zugriff auf globale Daten noch edx auf die Adresse draufgezählt wird (wo der Offset der Moduldaten im Kerneldatensegment drinsteht).
Dies funktioniert auch soweit ganz gut, nun ist nur das Problem, dass ich nun alle Libs die ich so habe ein zweites mal compilieren müsste um eine spezielle Modulversion zur Verfügung zu stellen (mit +edx für globale Daten).
Hat da Jemand eine besser Idee?
Wie ich in einigen Threads gelesen habe ersetzen einige von euch nach dem Laden des Moduls alle Adressen mit dem richtigen Offset, das scheint mir aber etwas zu aufwändig zu sein, ebenso wie ein extra Datensegment für jedes Modul zu spendieren.

MM
53
Lowlevel-Coding / ASMler gesucht
« am: 03. January 2006, 15:11 »
Eigentlich komisch, dass gerade in diesem Forum die Frage nach dem "Warum" gestellt wird: Warum sollte man sich dran setzen ein eigenes Betriebssystem zu schreiben, es gibt doch auch schon eine Menge die auch ganz passabel funktionieren...
Und vor allem denke ich auch, dass es zum "Low Level" dazu gehört nicht nur fertige Komponenten (oder Räder  :wink: ) zu benutzen, dann könnte man auch gleich Java programmieren...

MM
54
Lowlevel-Coding / ASMler gesucht
« am: 03. January 2006, 12:55 »
Sicher gibt es schon eine Menge, aber man benutzt doch am liebsten Tools die man selber geschrieben hat, oder?
Außerdem lernt man noch ne Menge dabei. Und ich konnte meinen Assembler zB als Grundlage für meinen C Compiler benutzen und so einen C Compiler gibt es bestimmt nicht...

MM
55
Lowlevel-Coding / ASMler gesucht
« am: 31. December 2005, 13:13 »
Hallo,

ich hab mal (unter anderem) einen Makro-Asembler geschrieben:
http://wwwstud.fh-zwickau.de/~micmo/compiler.html
(ganz unten auf der Seite nach meinen Compilern)

Ist zwar nicht in Assembler sondern in C geschrieben, aber eventuell hilft es euch ja weiter...

MM
56
Lowlevel-Coding / Diskette: int 13h im PM
« am: 18. December 2005, 23:43 »
Gna, immer diese Extrawünsche...
Aber gut, hier der Code mit dem bei diesem Projekt der Floppy-Controller gesucht wurde:
detect_basic_hw_string: db "detecting basic hardware: ",0A,0D,0
create_temp_pmode_env: db "creating temporary pmode environment... ",0
start_pmode: db "starting protected mode... ",0

hw_start:
hw_cpu_id_string: dd 0,0,0 ; Prozessor ID-String (o0 l13).
db 0
hw_cpu_version: dd 0 ; Informationen ?ber die Version (o13 l4).
hw_cpu_features: dd 0 ; Informationen ?ber die Features (o17 l4).
hw_cpu_speed: dd 0 ; ungef„hre MHz Zahl (o21 l4).
hw_memory: dd 0 ; KB an Speicher (o25 l4).
hw_fdc: db 0 ; 0=none / 1=extended fdc (o29 l1).
hw_floppys: db 0 ; Anzahl der Floppylaufwerke (o30 l1).
; Path des Bootscripts (o31 l72).
bootscript_path: db ".......................................................................",0

#define HW_SIZE 103xD

; *** PREPARE_KERNEL ***
prepare_kernel:
; Hardware suchen:
        mov     si,detect_basic_hw_string
        call    print_string

        call    detect_processor
        call    detect_memory
        call    detect_fdc
        call    detect_floppys

; Den Temp-Pmode vorbereiten:
        mov     si,create_temp_pmode_env
        call    print_string
        jmp     temp_pm

; *** DETECT_FDC ***
#define FDC_DATA   3F5 ; Data Register.
#define FDC_MSR    3F4 ; Main Status Register (input).
#define CMD_VERSION 10 ; FDC version.
detect_fdc_string: db " floppy disk controller: ",0
detect_fdc_ec_found: db "extended controller",0A,0D,0
detect_fdc_no_ec_found: db "none",0A,0D,0
detect_fdc:
        mov     bl,COLOR_WHITE
        mov     si,detect_fdc_string
        call    print_string_color

; Testet, welche FDC-Version installiert ist:
        mov     bl,CMD_VERSION
        call    sendbyte_fdc
        call    getbyte_fdc
        cmp     bl,90
        jnz     detect_fdc_no_ec

        mov     si,detect_fdc_ec_found
        call    print_string
        mov     byte ptr [hw_fdc],1
        ret
detect_fdc_no_ec:
        mov     si,detect_fdc_no_ec_found
        call    print_string
        mov     byte ptr [hw_fdc],0
        ret

; *** SENDBYTE_FDC ***
; (->bl = Byte to send)
; Sendet das Byte in bl an den FDC.
sendbyte_fdc:
        push    cx
        push    dx
        push    ax
        mov     cx,80
        mov     dx,FDC_MSR
sendbyte_fdc_loop:
        in      al,dx
        and     al,0C0
        cmp     al,80
        jnz     sendbyte_fdc_weiter
        mov     dx,FDC_DATA
        mov     al,bl
        out     dx,al
        pop     ax
        pop     dx
        pop     cx
        ret
sendbyte_fdc_weiter:
        in      al,80 ; delay
        loop    sendbyte_fdc_loop
        pop     ax
        pop     dx
        pop     cx
        ret

; *** GETBYTE_FDC ***
; (bl<- = received Byte ( FF = Timeout ))
; Empf„ngt in bl ein Byte vom FDC.
getbyte_fdc:
        push    cx
        push    dx
        push    ax
        mov     cx,80
        mov     dx,FDC_MSR
getbyte_fdc_loop:
        in      al,dx
        and     al,0D0
        cmp     al,0D0
        jnz     getbyte_fdc_weiter
        mov     dx,FDC_DATA
        in      al,dx
        mov     bl,al
        pop     ax
        pop     dx
        pop     cx
        ret
getbyte_fdc_weiter:
        in      al,80 ; delay
        loop    getbyte_fdc_loop
        pop     ax
        pop     dx
        pop     cx
        mov     bl,0FF ; Timeout
        ret

; *** DETECT_PROCESSOR ***
detect_processor_string: db " processor: ",0
detect_processor_speed_string1: db " ~",0
detect_processor_speed_string2: db "MHz",0A,0D,0
detect_processor:
        mov     si,detect_processor_string
        mov     bl,COLOR_WHITE
        call    print_string_color
       
; Den ID-String holen (12 Bytes in ebx,edx,ecx):
        xor     eax,eax
        cpuid
        mov     [hw_cpu_id_string],bl
        shr     ebx,8
        mov     [(hw_cpu_id_string+1)],bl
        shr     ebx,8
        mov     [(hw_cpu_id_string+2)],bl
        shr     ebx,8
        mov     [(hw_cpu_id_string+3)],bl
        shr     ebx,8
        mov     [(hw_cpu_id_string+4)],dl
        shr     edx,8
        mov     [(hw_cpu_id_string+5)],dl
        shr     edx,8
        mov     [(hw_cpu_id_string+6)],dl
        shr     edx,8
        mov     [(hw_cpu_id_string+7)],dl
        shr     edx,8
        mov     [(hw_cpu_id_string+8)],cl
        shr     ecx,8
        mov     [(hw_cpu_id_string+9)],cl
        shr     ecx,8
        mov     [(hw_cpu_id_string+0A)],cl
        shr     ecx,8
        mov     [(hw_cpu_id_string+0B)],cl

        mov     si,hw_cpu_id_string
        call    print_string

; Erweiterte Informationen holen:
        xor     eax,eax
        inc     ax
        cpuid
        mov     [hw_cpu_version],eax
        mov     [hw_cpu_features],edx

; CPU Geschwindigkeit ermitteln:

        call    detect_cpu_speed
        mov     si,detect_processor_speed_string1
        call    print_string
        mov     eax,[hw_cpu_speed]
        mov     ebx,10xD
        call    print_number
        mov     si,detect_processor_speed_string2
        call    print_string
        ret

detect_cpu_speed_lo: dd 0
detect_cpu_speed_hi: dd 0
detect_cpu_speed_delay: dd 0
detect_cpu_speed:
; Aktuelle Cycle Zahl holen:
        db 0F,31 ; RDTSC
        mov     [detect_cpu_speed_lo],eax
        mov     [detect_cpu_speed_hi],edx

; Delay von ca. 500ms:
        xor     ax,ax
        int     1A
        shl     ecx,16xD
        mov     cx,dx
        mov     [detect_cpu_speed_delay],ecx
        add     dword ptr [detect_cpu_speed_delay],9

        detect_cpu_speed_delay_loop:
        int     1A
        shl     ecx,16xD
        mov     cx,dx

        cmp     [detect_cpu_speed_delay],ecx
        jg      detect_cpu_speed_delay_loop

; Jetzt aktuelle Cycle Zahl holen und die alte davon abziehen:
        db 0F,31 ; RDTSC
        sub     eax,[detect_cpu_speed_lo]
        sbb     edx,[detect_cpu_speed_hi]

; Einen kleinen Korrekturwert hinzuf?gen:
        add     eax,600000
        adc     edx,0
       
; Nun ausrechnen wie viele Cycle der Rechner in 1000 Sekunden macht (MHz):
        mov     ecx,7A120
        div     ecx
        mov     [hw_cpu_speed],eax
        ret

; *** DETECT_MEMORY ***
detect_memory_string1: db " memory: ",0
detect_memory_string2: db "kb",0A,0D,0
detect_memory:
        mov     si,detect_memory_string1
        mov     bl,COLOR_WHITE
        call    print_string_color

; Dieser Interrupt gibt die Menge an Erweiterungsspeicher in kb zur?ck:
        mov     eax,0E801
        int     15

; Es kann sein, dass „ltere BIOS-Versionen diese Funktion noch nicht haben:
        jc      detect_memory_noE801

        and     eax,0FFFF ; 16-Bit mem unter 16mb in 1kb Bl”cken.
        and     ebx,0FFFF ; 16-bit mem ?ber 16mb in 64kb Bl”cken.
        shl     ebx, 6 ; Auf 1kb Bl”cke bringen.
        add     eax,ebx
        mov     [hw_memory],eax
        jmp     detect_memory_ende

detect_memory_noE801:
; Die SpeichergrӇe aus dem CMOS lesen:
        mov     al,17
        out     70,al
        in      al,71
        mov     [hw_memory],al
        mov     al,18
        out     70,al
        in      al,71
        mov     [(hw_memory+1)],al

detect_memory_ende:
; Den gesammten Speicher nicht nur den Erweiterten (also +1mb):
        add     dword ptr [hw_memory],1024xD
        mov     eax,[hw_memory]
        mov     ebx,10xD
        call    print_number
        mov     si,detect_memory_string2
        call    print_string
        ret

; *** DETECT_FLOPPYS ***
detect_floppys_string: db " floppy disks: ",0
detect_floppys:

        mov     si,detect_floppys_string
        mov     bl,COLOR_WHITE
        call    print_string_color

; Floppy 1 testen:
        push    es
        mov     ax,800
        xor     dx,dx
        int     13
        pop     es
        jc      detect_floppys_done ; Error.
        cmp     cx,0
        je      detect_floppys_done ; Nicht installiert.

        inc     byte ptr [hw_floppys]

; Floppy 2 testen:
        push    es
        mov     ax,800
        mov     dx,1
        int     13
        pop     es
        jc      detect_floppys_done ; Error.
        cmp     cx,0
        je      detect_floppys_done ; Nicht installiert.

        inc     byte ptr [hw_floppys]
detect_floppys_done:
        xor     eax,eax
        mov     al,[hw_floppys]
        mov     ebx,10xD
        call    print_number
        mov     si,new_line
        call    print_string
        ret


detect_fdc wird prüfen, ob eine Floppy da ist und detect_floppys prüft, ob 1 oder 2 Laufwerke installiert sind (glaub ich). Die anderen Funktionen sind für so Zeug wie Prozessorerkennung usw...

MM
57
Lowlevel-Coding / Diskette: int 13h im PM
« am: 18. December 2005, 21:27 »
hw_fdd und hw_floppys sind Variablen aus der Hardwareerkennung, in hw_fdd steht glaub ich die Versionsnummer des FDD-Controllers und in hw_floppys die Anzahl der Floppys.
Wie das initialisiert wurde dürfte für dieses Thema unerheblich sein.

MM
58
Lowlevel-Coding / Brauch hilfe zu Assembler
« am: 12. December 2005, 19:21 »
Da fällt mir auf, es soll doch bestimmt "DATA SEGMENT" heißen und nicht
"DATEN SEGMENT"

MM
59
Lowlevel-Coding / Brauch hilfe zu Assembler
« am: 12. December 2005, 17:42 »
Könnte da eventuell noch sowas wie ".model small" oder Ähnliches fehlen?
Die Meldung vom Assembler wäre wirklich ganz hilfreich.

MM
60
Lowlevel-Coding / Diskette: int 13h im PM
« am: 11. December 2005, 19:02 »
Meine Version des C Codes finde ich irgendwie grad nicht, aber dafür hab ich hier nen Link zu nem netten Democode, mit dem man sogar Disketten formatieren kann (aus dem FreeDOS32):
http://www.koders.com/c/fidCACDE05FE2F07441CF52B2104E08993FF8E8D8B5.aspx

Mir ist das zwar etwas zu unübersichtlich, aber eventuell hilft es weiter.
Ich hatte meinen Code übrigends nach der folgenden FDC Referenz geschrieben:
http://www.isdaman.com/alsos/hardware/fdc/floppy.htm

Eventuell finde ich meinen C Code ja nochmal wieder...
MM
Seiten: 1 2 [3] 4 5 ... 7

Einloggen