Autor Thema: [gelöst] "ehenkes" os dev tutorial - seltsamer fehler im kernel  (Gelesen 3062 mal)

Gamepower

  • Beiträge: 41
    • Profil anzeigen
Gespeichert
hallöle :)

ich habe einige zeit nicht mehr an mein "MinOS" kernel gearbeitet... also hab ich mein projekt vorerst geworfen und verfolge das os-dev tutorial von herrn henkes. nun habe ich folgendes problem: ich habe diesen kernel abgetippt, der sich auch ohne fehlermeldungen kompilieren lässt. allerdings, wenn ich den befehl "help" eingebe, kommt dort die fehlermeldung, das der befehl nicht existiert.

hier ersteinmal meine adaption des kernels:

; MyOS Kernel Vers. 0.0.3 - 11 Juni 2009

;;;;;;;;;;;;;;;;;
; Realmode Code ;
;;;;;;;;;;;;;;;;;

org 0x8000 ; Kernel Startadresse
[BITS 16] ; 16 Bit Code

; RealMode Bereich des Kernels
RealMode:
xor ax, ax ; Segmente einrichten
mov es, ax
mov ds, ax
mov ss, ax
mov sp, ax

mov si, welcome
call print_string

add sp, -0x40 ; Input Buffer auf 64 Zeichen setzen

loop_start:
mov si, prompt ; Eingabeaufforderung Zeigen
call print_string

mov di, sp ; Hole Eingaben
call get_string
jcxz loop_start ; Leere Zeile? Wenn ja, ignorieren und zum Start zurück

mov si, sp
mov di, cmd_hi ; "hi" Kommando
call strcmp
je .helloworld

mov si, sp
mov di, cmd_questionmark ; "?" Kommando
call strcmp
je .help

mov si, sp
mov di, cmd_exit ; "exit" Kommando
call strcmp
je .exit

mov si, sp
mov di, cmd_pm ; "pm (protected mode)" Kommando
call strcmp
je .pm

mov si, badcommand
call print_string
jmp loop_start

.helloworld:
mov si, msg_helloworld
call print_string
jmp loop_start

.help:
    mov si, msg_help
    call print_string
    jmp loop_start

.exit:
mov si, msg_exit
call print_string
xor ax, ax
int 0x16 ; Warte auf Tastendruck
jmp 0xffff: 0x0000 ; Neustart

.pm:
call clrscr
mov si, msg_pm
call print_string
call Waitingloop

cli ; Interrups leeren
lgdt [gdtr] ; Lade die GDT per GDTR (Eingerichtet in der Datei "gdt.asm"

in al, 0x92 ; A20-Gate per schnellen A20 Port 92 einschalten
cmp al, 0xff ; Falls 0xFF zurück gegeben wird, ist der Port nicht Verfügbar...
je .no_fast_A20 ; ... in diesem fall, zu diesem Punkt springen...

; andernfalls geht es hier weiter:
or al, 2 ; A20-Gate Bit setzen (Bit 1)
and al, ~1 ; Init-Bit setzen
out 0x92, al
jmp .A20_done

; Steht kein schneller A20-Gate zur Verfügung...? Dann benutzt der Kernel den Weg über den KBC Chip
.no_fast_A20:
call empty_8042
mov al, 0xD1 ; KBC Kommando: Schreibe auf Output Port
call empty_8042

mov al, 0xDF ; Schreibe dies auf KBC Output Port zum einschalten des A20 Gate
out 0x60, al
call empty_8042

; Umschalten in den A20-Gate beenden
.A20_done:
mov eax, cr0
or eax, 1
mov cr0, eax
jmp 0x8:ProtectedMode


empty_8042:
call Waitingloop
in al, 0x64 ; Kein echter KBC...?
cmp al, 0xFF
je .done

test al, 1 ; something in Input Buffer
jz .no_output
call Waitingloop
in al, 0x60 ; Wenn ja, Buffer lesen...
jmp empty_8042 ; ... dann nocheinmal

.no_output:
test al, 2 ; Kommando Buffer leer?
jnz empty_8042 ; Wenn nein, dann Buffer als nicht leer markieren und zur "Leerungsroutine" springen

.done:
ret

print_string:
mov ah, 0x0E

.loop_start:
lodsb ; Hole ein Byte von SI
test al, al ; Alle Zeichen geholt? Wenn ja, dann...
jz .done ; Funktion verlassen
int 0x10 ; Wenn nein, dann Zeichen ausgeben...
jmp .loop_start ; ... Anschliessend nochmal von vorn

.done:
ret

get_string:
xor cx, cx
.loop_start:
xor ax, ax
int 0x16 ; Auf Tastendruck warten
cmp al, 8 ; Rücktaste gedrückt?
je .backspace ; Wenn ja, entsprechend behandeln
cmp al, 13 ; Entertaste gedrückt?
je .done ; Wenn ja, entsprechend behandeln
cmp cl, 63 ; 63 Zeichen eingegeben?
je .loop_start ; Wenn ja, nur noch Rücktaste und Enter erlauben
mov ah, 0x0E
int 0x10 ; Gebe Zeichen aus
stosb ; Speichere Zeichen in Puffer
inc cx
jmp .loop_start

.backspace:
jcxz .loop_start ; Leer (Keine Zeichen auf dem Bildschirm) ? Wenn ja, Rücktaste ignorieren
dec di
mov byte [di], 0 ; Lösche ein Zeichen
dec cx ; Reduziere Speicherplatz für Zeichenkette
mov ah, 0x0E
int 0x10 ; Rücktaste auf dem Bildschirm zeigen
mov al, ' '
int 0x10 ; Gebe "Rücktastenzeichen" (Leerzeichen) aus
mov al, 8
int 0x10 ; Zeige erneut die Rücktaste auf dem Bildschirm
jmp .loop_start

.done:
mov byte [di], 0 ; NULL terminator
mov ax, 0x0E0D
int 0x10
mov al, 0x0A
int 0x10 ; Neue Zeile
ret

strcmp:
.loop_start:
mov al, [si] ; Hole ein Zeichen von SI
cmp al, [di] ; Sind SI und DI identisch?
jne .done ; Nein? Wir sind fertig

test al, al ; Keine Zeichen mehr zu prüfen?
jz .done ; Wenn ja, sind wir fertig

inc di ; DI um 1 verringern
inc si ; SI um 1 verringern
jmp .loop_start

.done:
ret

clrscr:
; Funktion, um den Bildschirm zu "leeren"
mov ax, 0x0600
xor cx, cx
mov dx, 0x174F
mov bh, 0x07
int 0x10
ret

;;;;;;;;;;;;;;;;;;;;;;;
; Protected Mode Code ;
;;;;;;;;;;;;;;;;;;;;;;;

[Bits 32]

ProtectedMode:
mov ax, 0x10
mov ds, ax ;Daten Desciptor -> Daten, Stack und Extra Segment
mov ss, ax
mov es, ax
xor eax, eax ; NULL Descriptor -> FS und GS
mov fs, ax
mov gs, ax
mov esp, 0x200000 ; Setze Stack Limit auf 2MB

call clrscr_32
mov ah, 0x01

.endlessloop:
call Waitingloop
inc ah
and ah, 0x0f
mov esi, msg_pm2 ; Nachricht "Betriebssystem läuft im Protected Mode"
call PutStr_32
cmp dword [PutStr_Ptr], 25 * 80 * 2 + 0xB8000
jb .endlessloop
mov dword [PutStr_Ptr], 0xB8000 ; Text Zeiger Wrapper
jmp .endlessloop

Waitingloop:
mov ebx, 0x9FFFF
.loop_start:
dec ebx
jnz .loop_start
ret

PutStr_32:
; PM Mode Textausgabe
mov edi, [PutStr_Ptr]
.nextchar:
lodsb
test al, al
jz .end
stosw
jmp .nextchar
.end:
mov [PutStr_Ptr], edi
ret

clrscr_32:
mov edi, 0xb8000
mov [PutStr_Ptr], edi
mov ecx, 40 * 25
mov eax, 0x07200720 ; 2 Werte -> Weisser Text auf schwarzen Hintergrund | 0x20 -> Freier Platz
rep stosd
ret

PutStr_Ptr dd 0xb000

; Man läd die Adresse des Textes, den man haben möchte, über "[PutStr_Ptr]
; für die Textaugaben. Der Text muss NULL terminiert sein.
; you want to print in esi and the attributes in ah
; lodsb loads one byte from esi into al, then increments esi,
; then it checks for a NUL terminator,
; then it moves the char into the write position in video memory,
; then increments edi and writes the attributes,
; loops until it finds NUL pointer at which point it breaks ...

;;;;;;;;;;;;;;;;
; Textausgaben ;
;;;;;;;;;;;;;;;;

welcome db 'MinOS Vers. 0.03', 13, 10, 0
msg_helloworld db 'Hello World on MinOS Vers. 0.03', 13, 10, 0
badcommand db 'Unbekannter Befehl', 13, 10, 0
prompt db '> ', 0
cmd_hi db 'hi', 0
cmd_help db 'help', 0
cmd_questionmark db '?', 0
cmd_exit db 'exit', 0
cmd_pm db 'pm', 0
msg_help db 'Befehle: hi, help, ?, pm, exit', 13, 10, 0
msg_exit db 'Computer wurde herunter gefahren. Du kannst ihm nun ausschalten. Alternativ druecke eine Taste, um ihm neuzustarten.', 13, 10, 0
msg_pm db 'Schalte in den Protected Mode.', 13, 10, 0
msg_pm2 db 'MinOS arbeitet im Protected Mode.  ', 0

;;;;;;;;;;;;
; Includes ;
;;;;;;;;;;;;

%include "gdt.asm"

;;;;;;;;;;;;;;;
; Kernel Ende ;
;;;;;;;;;;;;;;;

times 1024-($-$$) hlt

hab ich mich da einfach nur irgendwo vertippt, was nasm nicht anmeckert, weil nasm alles sieht was es sehen muss...? ach ja, ich kompiliere mit nasm, nicht nasmw...

---

[ot]
herr henkes schreibt ein wirklich klasse tutorial. alles ist schön schrittweise strukturiert und erklärt.
« Letzte Änderung: 07. July 2009, 22:04 von Gamepower »

Gamepower

  • Beiträge: 41
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 07. July 2009, 22:02 »
Du hast den vergleich mit cmd_help oben weg gelassen, vergleichst nur mit dem Fragezeichen. Schau mal etwas weiter unten im Tutorial
http://www.henkessoft.de/OS_Dev/OS_Dev1.htm#mozTocId146145

... da findest Du beide Befehle cmd_help und cmd_questionmark sowie die auch ansonsten optimierte Variante:

  mov si, buffer
  mov di, cmd_help  ; "help" command
  call strcmp
  jz .help

  mov si, buffer
  mov di, cmd_questionmark  ; "?" command
  call strcmp
  jz .help

huch... da hab ich doch echt was beim abtippen übersehen... danke dir :) nun klapps auch mit dem befehl.

ich nehm mir dann mal den c-kernel vor :)

---

[ot] mich würde, im späteren verlauf die api interissieren. ich hoffe, da kommt noch mehr. und, fat12/ fat15/ fat32 hätte ich auch gerne im tutrial :)

wenn das drinn ist, kann ich dann ein kleinen texteditor einbauen :)

 

Einloggen