Lowlevel

Lowlevel => Lowlevel-Coding => Thema gestartet von: Gamepower am 07. July 2009, 21:33

Titel: [gelöst] "ehenkes" os dev tutorial - seltsamer fehler im kernel
Beitrag von: Gamepower am 07. July 2009, 21:33
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 (http://www.henkessoft.de/OS_Dev/OS_Dev1.htm#mozTocId412221) 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.
Titel: Re: "ehenkes" os dev tutorial - seltsamer fehler im kernel
Beitrag von: Gamepower 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 :)