Autor Thema: Anfängerfrage  (Gelesen 4180 mal)

nore

  • Beiträge: 76
    • Profil anzeigen
Gespeichert
« am: 26. December 2005, 13:06 »
Hi, sry wenn's so ne Frage schonmal gab, hab lange hier im Forum gesucht und nichts entsprechendes gefunden.  
Mein Titel ist auch nicht sehr gut gewählt, aber ich wusste nicht, wie ich's ausdrücken soll.

Hier mein Problem:
ich habe zunächst den bootloader und auch den code vom kernel komplett aus dem lowlvl magazin übernommen. dann habe ich eine funktion hinzugefügt, die zeichenketten in einen puffer einliest und diese dann mit anderen zeichenketten vergleicht und entsprechend etwas tut. also wenn man "reboot" eingibt, dann startet der rechner neu, wenn man "fuck" eingibt, wird "you!" ausgebeben (waren nur kleine tests ;) ). das hat auch alles noch funktioniert.
dann hab ich mir ein paar sachen über fat12 durchgelesen und wollte einbauen, dass man eine diskette formatieren kann. dazu hab ich ersteinmal alle informationen, die in den bootsector kommen direkt in meinen assembler quelltext geschrieben, hinter die anderen variablen.
und ab da funktioniert es nicht mehr.
den bootloader hab ich ,glaub ich, so umgeändert, dass er genug von der diskette einliest.
ich hab leider nicht so viel ahnung von assembler. aber könnte es irgendwas mit den calls zu tun haben, weil die funktionen ja jetzt um einiges weiter weg von dem call sind.

wie ihr seht, bin ich noch nicht sehr weit und es ist ziemlich frustrierend für mich, dass ich nicht weiterkomme. deshalb wär ich euch sehr dankbar, wenn ihr mir helfen könntet.

nore

  • Beiträge: 76
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 30. December 2005, 15:12 »
bootloader: (fast 1 zu 1 aus dem lowlvl mag)
org 0x7C00 ; Unsere Startadresse

; -----------------------------------------
; Unser Bootloader
; -----------------------------------------

start:
                ; Erst brauchen wir einen Stack.
cli             ; Keine Interrupts!
mov ax, 0x9000  ; Stackadresse
mov ss, ax      ; SS = 9000 (unser Stack)
mov sp, 0       ; SP = 0000  (der Stackpointer)
sti             ; Interrupts zulassen

; Bootlaufwerk aus DL speichern
mov [bootdrv], dl

;Lade unseren Kernel
call load

;Springe zu diesem Kernel
mov ax, 0x1000 ; Die Adresse des Programms
mov es, ax     ; Segmentregister updaten
mov ds, ax
push ax
mov ax, 0
push ax
retf

; ----------------------------------------------
; Funktionen und Variablen
; ----------------------------------------------

bootdrv db 0 ;Das Bootlaufwerk
loadmsg db "Loading...",13,10,0

; Einen String ausgeben:
putstr:
lodsb             ; Byte laden
or al,al
jz short putstrd  ; 0-Byte? -> Ende!

mov ah,0x0E       ; Funktion 0x0E
mov bx,0x0007     ; Attribut-Byte (wird nicht benötigt)
int 0x10          ; schreiben
jmp putstr        ; Nächstes Byte
putstrd:
retn

; Lade den Kernel vom Bootlaufwerk
load:

; Diskdrive reset (Interrupt 13h, 0)
push ds            ; Sichere DS
mov ax, 0          ; Die gewünschte Funktion (reset)
mov dl, [bootdrv]  ; Dieses Laufwerk ist gewünscht
int 13h            ; Den Interrupt ausführen
pop ds             ; DS wiederherstellen
jc load            ; Geht nicht? -> Noch mal!

load1:
mov ax,0x1000      ; ES:BX = 10000
mov es,ax
mov bx, 0

; Sektoren lesen (Interrupt 13h, 2)
mov ah, 2       ; Funktion 2 (Lesen)
mov al, 12       ; Lese 12 Sektoren
mov cx, 2       ; Cylinder=0, Sector=2
mov dx, 0       ; Head=0, Laufwerk=0
int 13h         ; ES:BX =  Daten vom Laufwerk
jc load1        ; Fehler? Noch mal!
mov si,loadmsg
call putstr     ; Meldung ausgeben
retn

times 512-($-$$)-2 db 0   ; Dateilänge: 512 Bytes
dw 0AA55h                 ; Bootsignatur


kernel: (auch zu großen teilen ausm lowlvl mag, nur bischen umgeändert zum rumspielen)
; ---------------------------------------------------
; Makros
; ---------------------------------------------------

%macro printf 1
mov al, 0x01
mov si, %1
int 0x21
%endmacro

%macro getstr 1
mov al, 0x02
mov di, %1
int 0x21
%endmacro

%macro shcmp 1
 mov di, shpuf     ; string 1 = shellpuffer (muss nullterminiert sein)
 mov si, %1         ; string 2 = befehl
 call compstr      ; strings vergleichen
 cmp ah, 0         ; wenn alles gleich
%endmacro


; ---------------------------------------------------
; Unser Kernel
; ---------------------------------------------------

mov ax, 1000h ; Segmentregister updaten
mov ds, ax
mov es, ax

start:
mov si, msg
call putstr   ; Schicke Bootmessage :)

call regint

printf msg_1    ; Noch eine Message :D

call shell

printf msg_2    ; Noch eine Message :D

call getkey   ; Warte auf einen Tastendruck
jmp reboot    ; Reboot

; -------------------------------------------------
; Funktionen und Variablen
; -------------------------------------------------

msg db 13,10,"system is booting...",13,10,0
msg_1 db "loading shell...",13,10,0
msg_2 db "press any key for reboot",13,10,0

shpuf db 0                                          ; shell-variablen
times 254 db 0
shellmsg db "dave shell 0.01 is ready",13,10,0

sh_reboot db "reboot",13,10,0
sh_fuck db "fuck",13,10,0
sha_you db "you!",13,10,0
sh_files db "files",13,10,0
sha_files db "Ist die Floppy-Diskette mit FAT12 formatiert? (j)a, (n)ein",13,10,0
 
format_start dw 0          ; diskettenformatierung
db 0          ; JmpBoot
db "noreos  " ; OSName
dw 0xFF       ; BystesPerSec
db 1          ; SecPerClus
dw 1          ; RsvdSecCnt
db 2          ; NumFATs
dw 224        ; RootEntCnt
dw 2880       ; TotSec
db 0xF0       ; MediaType
dw 9          ; FATSize
dw 18         ; SecPerTrack
dw 2          ; NumHeads
dd 0          ; HiddenSec
dd 0          ; TotSec32
db 0          ; DrvNum
db 0          ; Reserved
db 0x29       ; BootSig
dd 0          ; VolumeID
times 11 db 20h ; VlumeLabel
db "FAT12"
times 3 db 20h  ; FileSysType
times 448 db 0  ; Dateilänge: 512 Bytes
dw 0AA55h       ; Bootsignatur
times 9216 db 0 ;

   

; Stringausgabe
putstr:
lodsb            ; Byte laden
or al,al
jz short putstrd ; 0-Byte? -> Ende!
mov ah,0x0E      ; Funktion 0x0E
mov bx,0x0007    ; Atrribut-Byte
int 0x10         ; schreiben
jmp putstr       ; nächstes Byte
putstrd:
retf

; Warte auf einen Tastendruck
getkey:
mov ah, 0 ; Funktion 0
int 016h  ; Ausführen
retf

; Rebooten (HEX Dump).
reboot:
db 0EAh
dw 0000h
dw 0FFFFh

_int0x21:

 _int_0x21_ser0x01: ; string ausgeben
 cmp al, 0x01
 jne _int0x21_ser0x01_end
 _int0x21_ser0x01_start:
 lodsb
 or al, al
 jz _int0x21_end
 mov ah, 0x0E
 mov bh, 0x00
 mov bl, 0x07
 int 0x10
 jmp _int0x21_ser0x01_start
 _int0x21_ser0x01_end:


 _int_0x21_ser0x02:  ; string in shpuf einlesen
 cmp al, 0x02
 jne _int0x21_ser0x02_end
 mov cx, 0
 _int0x21_ser0x02_start:
 call getkey                ; zeichen einlesen
 mov ah,0x0E                ; Funktion 0x0E
 mov bx,0x0007              ; Atrribut-Byte
 int 0x10                   ; zeichen wieder ausgeben (echo)
 stosb                      ; in den shell-puffer schreiben
 inc cx
 cmp cx, 253
 jz _int0x21_ser0x02_full
 cmp al, 13                 ; wenn enter gedrückt wurde
 jz _int0x21_ser0x02_term
 jmp _int0x21_ser0x02_start

 _int0x21_ser0x02_full:
 mov al, 13
 mov ah,0x0E             ; Funktion 0x0E
 mov bx,0x0007           ; Atrribut-Byte
 int 0x10                ; cr ausgeben
 stosb                   ; cr an shpuf anfügen
 _int0x21_ser0x02_term:
 mov al, 10
 mov ah,0x0E             ; Funktion 0x0E
 mov bx,0x0007           ; Atrribut-Byte
 int 0x10                ; nl ausgeben
 stosb                   ; nl an shpuf anfügen
 mov al, 0
 stosb                   ; nullterminieren
 jmp _int0x21_end
 _int0x21_ser0x02_end:


 _int0x21_end:
 iret

regint:
 push dx
 push es
 xor ax, ax
 mov es, ax
 cli
 mov word [es:0x21*4], _int0x21
 mov [es:0x21*4+2],cs
 sti
 pop es
 pop dx
 retf

shell:

 printf shellmsg           ; shell geladen message ausgeben

 shell_start:
 getstr shpuf           ; load string in shellpuffer

 shcmp sh_reboot
 jz shell_end      ; shell beenden

 shcmp sh_fuck
 jz shella_fuck    ; fuck - you!
 
 shcmp sh_files    ; dateien
 jz shella_files


 jmp shell_start
 shell_end:
 retf

shella_fuck:
 printf sha_you
 jmp shell_start

shella_files:
 printf sha_files
 call getkey
 mov ah, 6Ah
 cmp ah, al
 jz shella_files_fat12 ; ist Die Diskette schon mit FAT12 formatiert?
 mov ah, 3
 mov al, 19
 mov ch, 0
 mov cl, 0
 xor dx, dx
 mov ax, ds
 mov es, ax
 mov bx, format_start
 int 13h

 shella_files_fat12:

 jmp shell_start


compstr:
 compstr_start:
 mov ah,[si]
 mov dh,[di]
 cmp ah, dh
 jnz compstr_term
 inc si
 inc di
 mov ah, [di]
 or ah, ah
 jz compstr_end
 jmp compstr_start
 compstr_term:
 mov ah, 1
 compstr_end:
 retf

nore

  • Beiträge: 76
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 03. January 2006, 00:32 »
EDIT:
Bochs schreibt mir folgende Fehlermeldung:

====================================
Bochs is exiting with the following message:
[CPU0 ] prefetch: RIP > CS.limit
====================================

walli (de)

  • Beiträge: 1
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 12. January 2006, 12:48 »
hi, der Fehler liegt schon im Bootloader.
Bei der Anzahl der zu ladenen Sektoren hast du 12 angeben.
Die kernel.bin Datei ist aber 10463 byte groß
d.h kernel.bin benötit 21 Sektoren (10463/512 aufgerundet)

ps: Bin auch ein Anfänger, funktioniert nun aber.

nore

  • Beiträge: 76
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 14. January 2006, 22:46 »
vielen dank für die antworten.
bin eben ausm skiurlaub angekommen und deshalb etwas KO, aber morgen werd ich mich damit befassen und hier reineditieren, ob's klappt.


EDIT: ok, hab die retf in ret umgeändert. außerdem hab ich den bootloader geändert. da hatte ich wohl einfach nur die beiden ziffern vertauscht  :oops: .

aber das mit den calls und rets versteh ich nicht ganz. muss man die calls dann far machen und wie geht das? und wann muss man das überhaupt machen und wann nicht? und was ist mit near?

WhiteDragon

  • Beiträge: 124
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 17. January 2006, 12:44 »
Also sobald du dem Assembler mitteilst, dass er 32-Bit-Code verwenden soll, kannst du das far/near vergessen. So mach ich es jedenfalls...

maumo

  • Beiträge: 182
    • Profil anzeigen
    • http://maumo.50webs.com/
Gespeichert
« Antwort #6 am: 17. January 2006, 13:25 »
32bit code im 16bit real mode?
oder überseh ich da einen sprung in den pmode?

nore

  • Beiträge: 76
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 17. January 2006, 14:44 »
nein tust du nicht, ich bin im real mode und bleib da auch erstmal. ;)

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 17. January 2006, 14:45 »
32 Bit Code im Realmode ist durchaus möglich (ab dem 386, die Prozessoren darunter hatten ja keine 32 Bit Register). Nur wird dann jedem Befehl ein Prefix vorangestellt, und man kann weiterhin nur 20 Bit Addressieren (4 Bit Segmente, 16 Bit Offsets).

 

Einloggen