Lowlevel

Lowlevel => Lowlevel-Coding => Thema gestartet von: PMTheQuick am 16. June 2007, 22:03

Titel: Wieso rebootet bei diesem Code Bochs?
Beitrag von: PMTheQuick am 16. June 2007, 22:03
Hi  :-) ,

habe ein Problem. Bochs rebootet bei meinem Code ständig. Hier mal meine Files:

bootsec.asm
starter:

jmp 07c0h:main_entry

main_entry:
mov ax,cs
mov ds,ax
mov es,ax
cli
mov ss,ax
mov sp,9000h
sti

mov ah,02h
mov al,1
mov cl,2
mov ch,0
mov dl,0
mov dh,0
lea bx,[kernel]
int 13h

times 510-($-$$) db 0 ;wichtig: Hier die Datei mit so vielen Bytes füllen, bis es genau 510 sind
dw 0aa55h ;Bootsignatur anhängen
kernel:

kernel16.asm
[BITS 16] ;16 Bit Code erstellen
jmp start ;GDT überspringen

NULL_Desc:
dd 0
dd 0

CODE_Desc:
dw 0xFFFF ;Segmentgröße Byte 0/1
dw 0 ;Segmentbasisadresse Byte 0/1
db 0 ;Segmentbasisadresse Byte 2
db 10011010b ;Zugriffsberechtigungen
db 11001111b ;Zusatz + Segmentgröße Bits 16 - 19
db 0 ;Segmentbasisadresse Byte 3


DATA_Desc:
dw 0xFFFF
dw 0
db 0
db 0x92
db 0xCF
db 0

gdt:
Limit dw 0 ;Größe der GDT (wird später eingetragen)
Base dd 0 ;Adresse der GDT (wird später eingetragen)


start:

cli ;Interrupts ausschalten

mov eax, cs ;EAX auf derzeitiges Codesegment setzen
mov ds, ax ;DS auf Codesegment setzen

shl eax, 4 ;EAX mit 16 multiplizieren (Lineare Adresse
;des Codesegments errechnen)
mov [CODE_Desc+2], ax ;Lineare Adresse des Codesegmentes als
mov [DATA_Desc+2], ax ;Startadresse des Code- und Datendeskriptors
shr eax, 16 ;eintragen
mov [CODE_Desc+4], al
mov [DATA_Desc+4], al

mov eax, cs ;Startadresse der GDT errechnen
shl eax, 4
add eax, NULL_Desc

mov [Base], eax ;Startadresse der GDT eintragen
mov [Limit], WORD gdt - NULL_Desc -1 ;Größe der GDT errechnen und eintragen

lgdt [gdt] ;GDT laden

mov eax, cr0 ;In den Protected Mode schalten,
or eax, 1 ;indem Bit 0 des CR0 Registers auf 1
mov cr0, eax ;gesetzt wird

db 0xea ;FAR-JUMP zum Codesegment
dw PMODE
dw 0x8


[BITS 32] ;32 Bit Code erstellen

PMODE:
mov WORD [CODE_Desc+2], 0 ;Code Segmentstartaddresse auf 0 setzen
mov WORD [DATA_Desc+2], 0 ;Daten Segmentstartadresse auf 0 setzen
mov BYTE [CODE_Desc+4], 0 ;Code Segmentstartaddresse auf 0 setzen
mov BYTE [DATA_Desc+4], 0 ;Daten Segmentstartadresse auf 0 setzen

mov eax, 2 ;Selektor für das Datensegment erstellen
shl eax, 3

mov ds, ax ;Daten- Stack- und Extrasegment mit
mov ss, ax ;Datensegmentdeskriptor laden
mov es, ax
mov eax, 0 ;FS und GS mit Null-Deskriptor laden
mov fs, ax
mov gs, ax
mov esp, 0x1FFFFF ;Stack auf unterhalb der 2 MB Grenze setzen

jmp 0x8:0x10000 + PMODE2 ;Sprung in das "neue" Codesegment

PMODE2:
jmp END ;Zum Ende Springen

times 512-($-$$) db 0; ;Da der Linker sich nicht mit ungeraden
;Dateigrößen verträgt, wird diese Datei auf 512
;gepaddet.

END:

kernel32.asm
[Bits 32]
extern _main
global start
global _EnableA20Gate

start:

call _main

STOP:
jmp STOP

;#######################################################################

kernel.c:
int main()
{
char *Text = "Welcome to Protected Mode"; 
char *VideoMem = (char*)0xB8000; 
 
while(*Text) 

*VideoMem = *Text; 
*VideoMem++; 
*VideoMem = 7; 
*VideoMem++; 
*Text++; 


return(0);
}

link.txt
OUTPUT_FORMAT("binary")
INPUT(kernel32.obj ckernel.obj)
ENTRY(start)
SECTIONS
{
  .text  0x200 : {
    code = .; _code = .; __code = .;
    *(.text)
    . = ALIGN(1);
  }
  .data  : {
    data = .; _data = .; __data = .;
    *(.data)
    . = ALIGN(1);
  }
  .bss  :
  {
    bss = .; _bss = .; __bss = .;
    *(.bss)
    . = ALIGN(1);
  }
  end = .; _end = .; __end = .;
}

Create.bat
@echo off
echo DJGPP setzen...
set DJGPP=c:\djgpp\djgpp.env
echo ---
echo Bootloader erzeugen...
nasmw -f bin -o bootsec.bin bootsec.asm
echo ---
echo Kernel16 kompilieren...
nasmw -f bin -o kernel16.bin kernel16.asm
echo ---
echo Kernel32 kompilieren...
nasmw -f aout -o kernel32.obj kernel32.asm
echo ---
echo C-Kernel kompilieren...
gcc -ffreestanding -c -Os -o ckernel.obj kernel.c
echo ---
echo Zusammenlinken
ld -T link.txt -o c32kernel.bin
echo ---
echo Mergen
MergeKernel kernel.bin bootsec.bin kernel16.bin c32kernel.bin
echo ---
pause

Bochs-Konfig:
### Hier den Pfad anpassen für dein disk-image
floppya: 1_44=kernel.bin, status=inserted
####
romimage: file=../BIOS-bochs-latest, address=0xf0000
cpu: count=1, ips=10000000, reset_on_triple_fault=1
megs: 32
vgaromimage: file=../VGABIOS-lgpl-latest
vga: extension=vbe
boot: floppy
floppy_bootsig_check: disabled=0
log: bochsout.txt
panic: action=ask
error: action=report
info: action=report
debug: action=ignore
debugger_log: -
parport1: enabled=1, file="parport.out"
vga_update_interval: 300000
keyboard_serial_delay: 250
keyboard_paste_delay: 100000
private_colormap: enabled=0
keyboard_mapping: enabled=0, map=
i440fxsupport: enabled=1

Tools: DJGPP, MergeKernel, nasmw, Bochs

Vielen Dank im vorraus für eure Antwort  :wink: ,

Gruss
PMTheQuick  :-(
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: FreakyPenguin am 16. June 2007, 22:15
Ich würde dir empfehlen, das ganze mal mit einem Bochs mit eingebautem Debugger zu testen. Der kann dir dann die Inhalte aller Register (für dich duerfte Vorallem EIP von Interesse sein) anzeigen, und dir genauere Auskunft zu dem Fehler geben.
Den Code habe ich mir jetzt nicht genauer angeschaut.
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: PMTheQuick am 16. June 2007, 22:21
Habe mal debuggt:

check_cs: not a valid code segment !
00001325669e[CPU0 ] interrupt(): gate descriptor is not valid sys seg
00001325669e[CPU0 ] interrupt(): gate descriptor is not valid sys seg
00001325669i[CPU0 ] protected mode
00001325669i[CPU0 ] CS.d_b = 16 bit
00001325669i[CPU0 ] SS.d_b = 16 bit
00001325669i[CPU0 ] | EAX=00000011  EBX=00000200  ECX=00000002  EDX=00000000
00001325669i[CPU0 ] | ESP=00008ffe  EBP=00000000  ESI=000088ca  EDI=0000ffdf
00001325669i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
00001325669i[CPU0 ] | SEG selector     base    limit G D
00001325669i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00001325669i[CPU0 ] |  CS:07c0( 1e00| 0|  0) 00007c00 0000ffff 0 0
00001325669i[CPU0 ] |  DS:07c0( 0000| 0|  0) 00007c00 0000ffff 0 0
00001325669i[CPU0 ] |  SS:07c0( 0000| 0|  0) 00007c00 0000ffff 0 0
00001325669i[CPU0 ] |  ES:07c0( 0000| 0|  0) 00007c00 0000ffff 0 0
00001325669i[CPU0 ] |  FS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00001325669i[CPU0 ] |  GS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00001325669i[CPU0 ] | EIP=00000263 (00000263)
00001325669i[CPU0 ] | CR0=0x00000011 CR1=0 CR2=0x00000000
00001325669i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00001325669i[CPU0 ] >> jmp far 0008:0068 : EA68000800
00001325669e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00001325669i[SYS  ] bx_pc_system_c::Reset(SOFTWARE) called
00001325669i[APIC0] local apic in CPU 0 initializing
00001329409i[BIOS ] $Revision: 1.166 $ $Date: 2006/08/11 17:34:12 $
00001647564i[KBD  ] reset-disable command received
00001777395i[VBIOS]
VGABios $Id: vgabios.c,v 1.66 2006/07/10 07:47:51 vruppert Exp $

00001777466i[CLVGA] VBE known Display Interface b0c0
00001777498i[CLVGA] VBE known Display Interface b0c4
00001780423i[VBIOS] VBE Bios $Id: vbe.c,v 1.58 2006/08/19 09:39:43 vruppert Exp $
00002653162e[CPU0 ] check_cs: not a valid code segment !
00002653162e[CPU0 ] interrupt(): gate descriptor is not valid sys seg
00002653162e[CPU0 ] interrupt(): gate descriptor is not valid sys seg
00002653162i[CPU0 ] protected mode
00002653162i[CPU0 ] CS.d_b = 16 bit
00002653162i[CPU0 ] SS.d_b = 16 bit
00002653162i[CPU0 ] | EAX=00000011  EBX=00000200  ECX=00000002  EDX=00000000
00002653162i[CPU0 ] | ESP=00008ffe  EBP=00000000  ESI=000088ca  EDI=0000ffdf
00002653162i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
00002653162i[CPU0 ] | SEG selector     base    limit G D
00002653162i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00002653162i[CPU0 ] |  CS:07c0( 1e00| 0|  0) 00007c00 0000ffff 0 0
00002653162i[CPU0 ] |  DS:07c0( 0000| 0|  0) 00007c00 0000ffff 0 0
00002653162i[CPU0 ] |  SS:07c0( 0000| 0|  0) 00007c00 0000ffff 0 0
00002653162i[CPU0 ] |  ES:07c0( 0000| 0|  0) 00007c00 0000ffff 0 0
00002653162i[CPU0 ] |  FS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00002653162i[CPU0 ] |  GS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00002653162i[CPU0 ] | EIP=00000263 (00000263)
00002653162i[CPU0 ] | CR0=0x00000011 CR1=0 CR2=0x00000000
00002653162i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00002653162i[CPU0 ] >> jmp far 0008:0068 : EA68000800
00002653162e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00002653162i[SYS  ] bx_pc_system_c::Reset(SOFTWARE) called

Und das wiederholt sich x-mal. Hab jetzt mal das herausgeschnitten, ist das wichtigste. (Die Log ist nach einem Starten und 2sek laufen lassen 40KB gross  :-o ) Was will Bochs mir damit sagen?

Gruss
PMTheQuick ;)
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: FreakyPenguin am 16. June 2007, 22:25
Irgendwas Löst einen GPF aus.
Was genau, wirst du genauer wissen, wenn du deine Binary diassemblierst und schaust, was an 00000263 ist, denn dort wird der GPF ausgelöst.
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: PMTheQuick am 16. June 2007, 22:32
Das ist das Prob:
00000263  EA68000800        jmp 0x8:0x68

Bzw. oben bei Kernel 16...
jmp      0x8:0x10000 + PMODE2   ;Sprung in das "neue" Codesegment

Aber was is daran denn falsch? Das stammt direkt von TeeJay's Tut...

Gruss
PMTheQuick ;)
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: FreakyPenguin am 16. June 2007, 22:46
Dann würde ich mal auf kaputte Deskriptoren, oder falsch geladene GDT tippen.

Ich mag jetzt nicht die ganzen Deskriptoren nachrechnen. Aber ich kann dir einen link zum SMP-Trampoline-Code von LOST geben: http://lost.famkaufmann.info/websvn/filedetails.php?repname=Lost&path=%2Ftrunk%2Fsrc%2Fkernel2%2Fsrc%2Fsmp%2Frm_trampoline.asm

Dort wird auch vom Real mode in den Protected mode gewechselt.
Wenn du dich allzu stark von dem Code inspirieren lässt, solltest du die Lizenz beachten ;-)
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: PMTheQuick am 17. June 2007, 10:02
Habe jetzt mal versucht auf TeeJay's FAT12 Bootloader umzusteigen. Nur hab ich jetzt nen kleines Problemchen: Ich habe KEIN Disketten-Laufwerk.. Wie kann ich den Bootloader trotzdem benutzen? Wie binde ich es dann in Bochs ein?

Gruss
PMTheQuick ;)

OS: Windows XP, hier hab ich nur so nen Linux-Post gesehen wo so "dd,pc,mount,unmount" vorkommt...
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: FreakyPenguin am 17. June 2007, 10:54
Du brauchst ein Disketten-Image, welches du in Bochs anstatt der kernel.bin einträgst. Wie du das unter Windows am einfachsten erstellst weiss ich auch nicht.
Wenn du mal ein rohes Imge hast, kannst du es mit VFD(http://chitchat.at.infoseek.co.jp/vmware/vfd.html) als virtuelles Diskettenlaufwerk benutzen. Damit solltest du, wenn ich mich nicht irre, sogar ein Image erstellen können, indem du keinen Pfad für das Image auswählst (Image im Ram), die Änderungen darauf machst, und es danach abspeicherst.
Auf dieses virtuelle Laufwerk schreibst du dann mit Rawwrite oder dd deinen Bootloader. Danach kannst du die Kernel.bin (oder wie du sie nennen willst) direkt mit dem Explorer auf die Diskette kopieren.

Aber ich würde dir anraten, Grub zu benutzen. Damit kannst du eine Fehlerquelle ausschliessen. Der wechselt dir auch direkt in den Protected-Mode, und du kannst von Anfang an ein brauchbares Binärformat (am besten ELF) benutzen. Später kann er dir auch schon Module beim booten mitladen. Wenn du den benutzen möchtest, nimmst du am besten ein fertiges Image (z.B. von LOST) und passt es mit VFD an.
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: PMTheQuick am 17. June 2007, 17:42
ok... jetzt wollte ich grub nehmen. ich komme aber kein bisschen nach, wo es das gibt, was ich tun muss und wie ich das installen soll?  :-(

Gruss
PMTheQuick ;)
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: Homix am 17. June 2007, 17:49
jmp      0x8:0x10000 + PMODE2   ;Sprung in das "neue" Codesegment
0x10000 ist kein 16-Bit Wert mehr, auch wenn noch was dazu addiert wird *g*

Grüsse, Stefan
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: PMTheQuick am 17. June 2007, 18:18
ich hab nun einfach probs! Ich will eigentlich weiterhin meinen oberen verwenden, aber irgendso nen Ding restartet ständig. Und zwar das:

00000263  EA68000800        jmp 0x8:0x68
Wieso geht das nicht? Vorallem kann ich nirgendwo im Code jmp 0x:0x68 finden  :? Wisst ihr vielleicht eine Lösung?

Gruss
PMTheQuick ;)

@stefan2005: Aber oben kommt ja noch vor ;) [BITS 32] ;32 Bit Code erstellen

PMODE:
mov WORD [CODE_Desc+2], 0 ;Code Segmentstartaddresse auf 0 setzen
mov WORD [DATA_Desc+2], 0 ;Daten Segmentstartadresse auf 0 setzen
mov BYTE [CODE_Desc+4], 0 ;Code Segmentstartaddresse auf 0 setzen
mov BYTE [DATA_Desc+4], 0 ;Daten Segmentstartadresse auf 0 setzen

mov eax, 2 ;Selektor für das Datensegment erstellen
shl eax, 3

mov ds, ax ;Daten- Stack- und Extrasegment mit
mov ss, ax ;Datensegmentdeskriptor laden
mov es, ax
mov eax, 0 ;FS und GS mit Null-Deskriptor laden
mov fs, ax
mov gs, ax
mov esp, 0x1FFFFF ;Stack auf unterhalb der 2 MB Grenze setzen

jmp 0x8:0x10000 + PMODE2 ;Sprung in das "neue" Codesegment
;)
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: nooooooooos am 17. June 2007, 18:23
Du hast doch sicher irgendwo ein jmp...Und im Code steht für 0x68 einfach ein Label.

Jetzt musst du nur noch deinen Code disassemblieren und schauen was bei 0x68 für ein label steht...schon hast du deinen Befehl.

Warscheinlich ist das der PM-Jmp und wenn der nicht klappt liegts an irgendetwas mit der GDT den Segmenten und den Offsets...


Gruss
Noooooooooooos
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: Homix am 17. June 2007, 18:25
hi
achso, na ja ich denke das jmp 0x8:0x68 kommt von dem Code:

db  0xea    ;FAR-JUMP zum Codesegment
dw PMODE
dw 0x8

du hast ja keine Offsetadresse ala [ORG 0x???] angegeben, dann assembliert der Assembler das so als wenn der Code an Adresse 0x00 liegt.
Zwar hast du das cs und ds segment richtig gesetzt, aber wenn es um ein direkten Wert von einem Label geht, so nützt dir das nix mehr  :-D

Grüsse,
Stefan
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: nooooooooos am 17. June 2007, 18:33
hehe nein stefan2005...Der Code von TeeJay geht sowiso davon aus, dass der Kernel am Anfang eines Segmentes liegt. Und dieses Segment wird ausgelsen und in den Deskriptor geschrieben...
Deshalb solltest du den Code selber schreiben oder den Bootloader soweit anpassen, dass das stimmt...

Ich würde den Kernel und den anderen Code nach z.B. 0x9000 laden und vor dem jmp cs auf 0x9000 setzen und jmp 0 machen...(noch im Bootloader)

Gruss
Noooooooos
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: PMTheQuick am 17. June 2007, 18:49
Ah ja  :oops: Aber schon wieder das nächste Prob... Dieses Tut besteht ja nur aus Fehlern... ^^

00001311251i[CPU0 ] WARNING: Encountered an unknown instruction (signalling illegal instruction)
00001311252i[CPU0 ] BxError: instruction with opcode=0xde

Was soll denn das? Hier weiss ihc nicht mal mehr von wo das kommt  :?

Gruss
PMTheQuick ;)
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: nooooooooos am 17. June 2007, 18:53
Das gibts nur wenn bei jmps in Daten oder nicht an den Anfang eines Befehles sonder mittendrein gesprungen wird.

Zeig mal alle Dateien wo du was verändert hast...Das Tut hat keine Fehler (!) aber es ist ein bisschen blöd und man muss beim Code drumherum sehr viel beachten...(Ist aber fast immer beim PM so...)

Gruss
Noooooooooooos
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: PMTheQuick am 17. June 2007, 19:00
Habs jetzt mal ganz grob gemacht ^^ Einfach alles hochgeladen ;)

Size: 616 KB
Type: RAR
URL: http://web56.login-1.loginserver.ch/QuickOS.rar

Ich hoffe das helft euch,

Gruss
PMTheQuick ;)

EDIT: Eigentlich ist alles gleich, ausser bootsec.asm, das hab ich verändert, denn ich will keinen FAT12, sondern einen normaler Loader der Kernel16 dann aufruft ^^
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: nooooooooos am 17. June 2007, 19:06
Was hast du denn am bootsec verändert? Die Datei im Web ist identisch mit der die du mal gepostet hast....

Gruss
Noooooooooos
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: PMTheQuick am 17. June 2007, 19:18
Das am Anfang war nicht das Original!

Original ist:
;#######################################################################
;BOOTSECTOR zum laden einer binären Kernel-Datei aus dem Root-Verzeichnis

;Copyright by TeeJay (masta_ace_inc@gmx.de)

;Bei Fragen oder Problemen einfach eine Mail schreiben
;Auf Anfrage gibts auch ein eigenes DEUTSCHES Tutorial zum Thema FAT12

;#######################################################################
;INCLUDE_START

%include "Macros.asm" ;Hier sind Macors um die einzelnen lokalen Variablen und Parameter
;bequem ansprechen zu können
;Diese gelten aber nur für einen 16-Bit Stack!!!

;INCLUDE_END
;#######################################################################
;BOOTSECTOR_INFOBLOCK

jmp BOOTINFOBLOCK_END
OSName db "JAY-OS  "
BytesPerSec dw 512
SecPerClus db 1
ResvdSecCnt dw 1
NumFATs db 2
RootEntCnt dw 224
TotSec dw 2880
MediaType db 0xF0
FATSize dw 9
SecPerTrack dw 18
NumHeads dw 2
HiddenSec dd 0
TotSec32 dd 0
DrvNum db 0x00
Reserved db 0
BootSig db 0x29
VolumeID dd 1
VolumeLavel db "NO NAME    "
FileSysType db "FAT12   "
BOOTINFOBLOCK_END:

;########################################################################
;BOOTSECTOR_CODE_START

org 0x7C00 ;Code-Start-Adresse auf 0x7C00 setzen

cli ;Interruptflag löschen (keine Interrupts zulassen)
mov ax, 0x9000
mov ss, ax ;Stacksegment auf AX(0x9000) setzen
xor sp, sp ;Stackpointer auf 0 setzen
sti ;Interruptflag setzen (Interrupts wieder zulassen)



call func_FindFileSector ;Startsektor der Kerneldatei finden lassen (Rückgabe in AX)
or ax, ax ;AX = 0? -> Datei nicht gefunden
jz KernelNotFound ;Zur Ausgabe (File not found) springen

call func_ReadFATTable ;FAT-Tabelle in den Speicher lesen lassen

mov bx, 0x1000 ;Segmentadresse festlegen an die der Kernel geladen werden soll
mov dx, [RootEntCnt] ;Startsektor der Datensektoren errechnen
shl dx, 5
add dx, [BytesPerSec]
dec dx
shr dx, 9
add [Temp], dx ;Und das Ergebnis in Temp-Variable speichern


LoadKernelFile:
mov dx, [Temp] ;Startsektor der Datensektoren in DX schreiben
add dx, ax ;Zum Startsektor der Datensektoren den Startsektor der Datei addieren
dec dx ;DX um 2 verringern
dec dx ;Zweimal "dec dx" braucht weniger Bytes als einmal "sub dx, 2"
push bx ;Segmentadresse an die der Sektor gelesen werden soll auf den Stack pushen
push dx ;Sektornummer die gelesen werden soll auf den Stack pushen
call func_ReadSector ;Sektor lesen lassen
add sp, 4 ;2 Parameter vom Stack löschen

push ax ;FAT-Eintrag-Nummer auf den Stack pushen
call func_ReadFATEntry ;Wert des FAT-Eintrags lesen (Rückgabe in AX)
add sp, 2 ;1 Parameter vom Stack löschen

cmp ax, 0xFFF ;Ist das der letzte FAT-Eintrag der Kernel-Datei?
je ExecuteKernel ;Wenn Ja -> Springe zum Kernel
add bx, 32 ;Segmentadresse um 32 erhöhen. Dort wird der nächste Sektor hingelesen
jmp LoadKernelFile ;Springe wieder nach oben um nächsten Sektor der Kernel-Datei zu lesen

ExecuteKernel:
mov ax, 0x1000
push ax ;Segmentadresse an welcher der Kernel ist auf den Stack pushen
mov ax, 0
push ax ;Offsetadresse des Kernels (0) auf den Stack pushen
retf ;Einen FAR-Rücksprung zum Kernel machen

KernelNotFound:
push WORD MsgFileNotFound ;Offset der "File not Found" Meldung auf den Stack pushen
call func_PrintString ;Meldung ausgeben lassen
add sp, 2 ;1 Parameter vom Stack löschen


WaitForKeyToReboot:
mov ah, 0 ;Auf Tastendruck warten
int 0x16

Reboot:
db 0xEA ;Reboot
dw 0x0000
dw 0xFFFF

;BOOTSECTOR_CODE_END
;########################################################################
;DATABLOCK_START

MsgFileNotFound db "File not found.",13,10,0 ;Meldung wenn kein Kernel gefunden wurde

Filename db "KERNEL  BIN" ;Dateiname des Kernels
Temp dw 0 ;Tempvariable

;DATABLOCK_END
;########################################################################
;FUNCTIONS_START

;------------------------------------------------------------------------
;Funktion um einen NULL-Terminierten String auszugebens
;1. Paramtere: Offset an dem sich der String befindet

func_PrintString:
push bp ;BP sichern
mov bp, sp ;Stackpointer in BP übertragen

pusha ;Alle Register sichern

mov si, [Param1] ;1. Parameter(Offset des Strings) nach SI kopieren
mov ah, 0x0E ;Funktion zur Zeichenausgabe
mov bx, 0x0007 ;Farbattribut des Zeichens
.1:
lodsb ;Zeichen von SI-Pointer nach AL kopieren und SI um 1 erhöhen
or al, al ;AL = 0? String zu Ende?
jz .2 ;Wenn JA -> Springe zum Ende
int 0x10 ;Zeichen ausgeben lassen
jmp .1 ;Wieder nach oben springen um nächstes Zeichen auszugeben

.2:
popa ;Register wiederherstellen

mov sp, bp ;Stackpointer wieder in SP übertragen
pop bp ;BP wiederherstellen
ret ;Return

;------------------------------------------------------------------------
;Funktion um den Startsektor der Kernel-Datei zu finden

func_FindFileSector:
push bp ;BP sichern
mov bp, sp ;Stackpointer in BP übertragen
sub sp, 2 ;Platz für eine lokale Variable auf dem Stack schaffen

pusha ;Alle Register sichern

mov ax, 0x9200 ;Segmentadresse festlegen an die ein Sektor zwischengespeichert wird
mov es, ax

mov ax, [FATSize] ;Startsektor des Root-Directorys errechnen
mov bl, [NumFATs]
mul bl
add ax, [ResvdSecCnt]
mov [Temp], ax ;Startsektor des Root-Directorys in Temp-Variable speichern

xor dx, dx ;DX auf 0 setzen (Braucht weniger Bytes als "mov dx, 0")

.E:
cmp dx, [RootEntCnt] ;Wurden schon alle Root-Dir-Einträge durchsucht?
je .A ;Wenn JA -> Datei nicht gefunden

test dx, 15 ;DX durch 16 ohne Rest teilbar?
jnz .B ;Wenn JA -> Nächsten Sektor lesen

push es ;Segmentadresse für zwischenspeichern eines Sektors auf Stack pushen
push ax ;Sektornummer auf Stack pushen
call func_ReadSector ;Sektor lesen lassen
add sp, 4 ;2 Parameter vom Stack löschen
inc ax ;AX um 1 erhöhen (Braucht weniger Bytes als "add ax, 1")
xor bx, bx ;BX auf 0 setzen (Braucht weniger Bytes als "mov bx, 0")

.B: ;Wenn DX NICHT durch 32 OHNE Rest teilbar ist, fahre HIER fort
cmp BYTE [es:bx], 0x0E ;Erstes Zeichen des Root-Dir-Eintrags = 0x0E?
je .D ;Wenn JA -> Nächsten Eintrag lesen
cmp BYTE [es:bx], 0 ;Erstes Zeichen des Root-Dir-Eintrags = 0?
je .A ;Wenn JA -> Keine weiteren Einträge mehr. Datei nicht gefunden


mov si, Filename ;Offset des Dateinamens nach SI kopieren
mov di, bx ;Offset des Root-Dir-Eintrags nach DI kopieren
mov cx, 11 ;11 Zeichen sollen verglichen werden
repe cmpsb ;Solange vergleichen bis CX = 0 oder ungleiche Zeichen
or cx, cx ;CX = 0?
jz .C ;Wenn JA -> Alle Zeichen stimmen überein. Datei gefunden

.D:
inc dx ;DX um 1 erhöhen
add bx, 32 ;BX um 32 erhöhen (Offset des nächsten Root-Dir-Eintrags)
jmp .E ;Wieder nach oben springen um nächsten Eintrag zu vergleichen

.A: ;Wenn die NICHT Datei gefunden wurde, HIER fortfahren
popa ;Alle Register wiederherstellen
xor ax, ax ;AX auf 0 setzen (Braucht weniger Bytes als "mov ax, 0")
jmp .Ende ;Zum Ende Springen

.C: ;Wenn die Datei gefunden wurde, HIER fortfahren
push WORD [es:bx+26] ;Startsektornummer der Datei auf den Stack pushen
pop WORD [Var1] ;Startsektornummer in lokale Variable popen
popa ;Alle Register wiederherstellen
mov ax, [Var1] ;Startsektornummer der Datei nach AX kopieren

.Ende:
mov sp, bp ;Stackpointer in SP übertragen
pop bp ;BP wiederherstellen
ret ;Return

;------------------------------------------------------------------------
;Funktion um einen Sektor zu lesen
;1. Parameter: Logische Sektornummer des Sektors welcher gelesen werden soll
;2. Parameter: Segmentadresse an die der Sektor gespeichert werden soll

func_ReadSector:
push bp ;BP sichern
mov bp, sp ;Stackpointer in BP übertragen
sub sp, 6 ;Platz für 3 lokale Variablen auf dem Stack schaffen

pusha ;Alle Register sichern

;Aus Logischer Sektornummer die CHS Adresse errechnen
mov ax, [Param1] ;Aus logischer Sektornummer den Cylinder errechnen
mov bx, 36
mov dx, 0
div bx
mov [Var1], ax

mov ax, dx ;Aus logischer Sektornummer den Head errechnen
push ax
mov bx, 18
mov dx, 0
div bx
mov [Var2], ax

pop ax ;Aus logischer Sektornummer den Sektor errechnen
mov dx, 0
div bx
mov ax, dx
add ax, 1
mov [Var3], ax


.1:
mov ax, [Param2] ;Segmentadresse zum speichern des Sektors festlegen
mov es, ax
mov bx, 0 ;Offset zum speichern des Sektors festlegen
mov ah, 2 ;Funktion zum Sektorlesen
mov al, 1 ;1 Sektor soll gelesen werden
mov ch, [Var1] ;Angabe des Cylinders an dem der Sektor gelesen werden soll
mov cl, [Var3] ;Angabe des Sektors an dem der Sektor gelesen werden soll
mov dh, [Var2] ;Angabe des Heads an dem der Sektor gelesen werden soll
mov dl, 0 ;Von Laufwerk A: lesen
int 0x13 ;Sektor lesen lassen
jc .1 ;Bei Fehler nochmal versuchen

popa ;Alle Register wiederherstellen

mov sp, bp ;Stackpointer in SP übertragen
pop bp ;BP wiederherstellen
ret ;Return

;------------------------------------------------------------------------
;Funktion um einen FAT-Eintrag zu lesen
;1. Parameter: Nummer des Eintrags der gelesen werden soll
;In AX wird der Wert des gelesenen FAT-Eintrag zurückgegeben

func_ReadFATEntry:
push bp ;BP sichern
mov bp, sp ;Stackpointer in BP übertragen
sub sp, 2 ;Platz für eine lokale Variable auf dem Stack schaffen

pusha ;Alle Register sichern

mov ax, [Param1] ;Offset errechnen an dem sich der FAT-Eintrag im Speicher befindet
mov bx, 3
mul bx
mov bx, 2
xor dx, dx
div bx

mov bx, 0x9200 ;Segmentadresse angeben an der die FAT-Tabelle im Speicher liegt
mov es, bx
mov bx, ax
mov ax, [es:bx]
mov [Var1], ax ;FAT-Eintrag (16 Bit) in lokale Variable speichern

mov cx, [Param1] ;Testen ob der zu lesende FAT-Eintrag gerade oder ungerade ist
test cx, 1
jz .Gerade ;Wenn GERDADE -> Springe

;Wenn der zu lesende FAT-Eintrag UNGERADE ist, HIER fortfahren
popa ;Alle Register wiederherstellen
mov ax, [Var1]
shr ax, 4 ;FAT-Eintrag(12 Bits) aus den 16 Bits extrahieren
jmp .Ende

.Gerade: ;Wenn der zu lesende FAT-Eintrag GERADE ist, HIER fortfahren
popa ;Alle Register wiederherstellen
mov ax, [Var1]
and ax, 0xFFF ;FAT-Eintrag(12 Bits) aus den 16 Bits extrahieren

.Ende:
mov sp, bp ;Stackpointer in SP übertragen
pop bp ;BP wiederherstellen
ret ;Return

;------------------------------------------------------------------------
;Funktion zum einlesen der FAT-Tabelle in den Speicher

func_ReadFATTable:
pusha ;Alle Register sichern

mov bx, 0x9200 ;Segmentadresse festelegen an welche die FAT-Tabelle gelesen werden soll
mov ax, [ResvdSecCnt] ;Startsektor der FAT-Tabelle eintragen
mov cx, [FATSize] ;Anzahl der FAT-Tabellen-Sektoren eintragen
.A:
push bx ;Segmentadresse auf den Stack pushen
push ax ;Sektornummer auf den Stack pushen
call func_ReadSector ;Sektor lesen lassen
add sp, 4 ;2 Parameter vom Stack löschen
inc ax ;Nächsten Sektor auswählen
add bx, 32 ;Segmentadresse um 32 erhöhen (Dort wird nächster Sektor gespeichert)
loop .A ;Solange wiederholen bis alle Sektoren gelesen wurden

popa ;Alle Register wiederherstellen

ret ;Return

;------------------------------------------------------------------------

;FUNCTIONS_END
;########################################################################


times 512-($-$$)-2 db 0 ;Den Rest des Bootsektors mit Nullen Füllen
dw 0AA55h ;0xAA55 am Ende des Bootsektors schreiben

;#######################################################
;Macros für den einfachen Zugriff auf die über den Stack übergebenen Parameter
;ACHTUNG! Diese Macros sind nur bei einem 16-Bit Stack korrekt!

%define Param1 bp+4
%define Param2 bp+6
%define Param3 bp+8
%define Param4 bp+10
%define Param5 bp+12

;#######################################################
;Macros für den einfachen Zugriff auf lokale Variablen innerhalb einer Funktion
;die auf dem Stack erstellt wurden
;ACHTUNG! Diese Macros sind nur bei einem 16-Bit Stack korrekt!

%define Var1 bp-2
%define Var2 bp-4
%define Var3 bp-6
%define Var4 bp-8
%define Var5 bp-10

;#######################################################

Meiner is:
org 0x7C00

starter:

jmp 07c0h:main_entry

main_entry:
mov ax,cs
mov ds,ax
mov es,ax
cli
mov ss,ax
mov sp,9000h
sti

mov ah,02h
mov al,1
mov cl,2
mov ch,0
mov dl,0
mov dh,0
lea bx,[kernel]
int 13h

times 510-($-$$) db 0 ;wichtig: Hier die Datei mit so vielen Bytes füllen, bis es genau 510 sind
dw 0aa55h ;Bootsignatur anhängen
kernel:

Gruss
PMTheQuick ;)
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: nooooooooos am 17. June 2007, 19:24
dann ersetz mal lea bx,[kernel] durch
mov es, 0x9000
mov bx,0x0

Dann geht die CPU aber nicht mehr direkt vom bootloader zum kernel und somit musst du ein sprung ein bauen: jmp 0x9000:0x0

Da jetzt aber alle Kernel-Dateien auf einem anderen Platz sind musst du halt überall sorgfältig schauen ob du was verändern musst... (Beim PM-umschalt-code musst du nur das jmp 0x8:0x10000+ PMODE2
durch jmp 0x8:0x9000+PMODE ersetzen...Wies bei C-Code geht weiss ich nicht...)


Gruss
Noooooooooooooooos
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: PMTheQuick am 17. June 2007, 19:44
Es geht leider nicht  :-(
org 0x7C00

starter:

jmp 07c0h:main_entry

main_entry:
mov ax,cs
mov ds,ax
mov es,ax
cli
mov ss,ax
mov sp,9000h
sti

mov ah,02h
mov al,1
mov cl,2
mov ch,0
mov dl,0
mov dh,0
mov es,0x9000
mov bx,0x0
int 13h

times 510-($-$$) db 0 ;wichtig: Hier die Datei mit so vielen Bytes füllen, bis es genau 510 sind
dw 0aa55h ;Bootsignatur anhängen
kernel:

Meine Make.bat sagt:
DJGPP setzen...
---
Bootloader erzeugen...
bootsec.asm:22: error: invalid combination of opcode and operands
---
Kernel16 kompilieren...
---
Kernel32 kompilieren...
---
C-Kernel kompilieren...
---
Zusammenlinken
---
Mergen
Finished.
3 Files Merged.
608 Bytes copied.
---
Unnoetige Files loeschen...
---
Drücken Sie eine beliebige Taste . . .

Gruss
PMTheQuick ;)

EDIT1: Halt mal! Wenn ich es so brauche, ist doch alles limitiert auf 512 Bytes oder? Sollte ich doch besser FAT12-Bootloader nehmen? Versuchte den gerade, aber der gibt ein CS-Limit knurr nichts geht von diesem tut ^^  :roll:
EDIT2: Jetzt gibets kein CS-Limit mehr, dafür jetzt dies:
00001256750i[CPU0 ] WARNING: Encountered an unknown instruction (signalling illegal instruction)
00001256751i[CPU0 ] BxError: instruction with opcode=0xdf
00001256751i[CPU0 ] mod was c0, nnn was 7, rm was 7
Langsam blick ich echt nicht mehr durch...
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: nooooooooos am 17. June 2007, 19:51
nenein...dein bootloader ist scho gut...hehe ja ich hab vergessen ein segmentregister kann man ja gar nicht direkt laden...also mov ax,0x9000; mov cx,ax

Gruss
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: PMTheQuick am 17. June 2007, 19:57
Ok. Verwende meinen Bootloader. Nur ^^ Jetzt ist das da:

00001292493i[CPU0 ] WARNING: Encountered an unknown instruction (signalling illegal instruction)
00001292494i[CPU0 ] BxError: instruction with opcode=0xde
00001292494i[CPU0 ] mod was c0, nnn was 3, rm was 6

Was heisst das schon wieder? Irgendwie gibets nur Errors ^^ Und hier steht nicht mal ne Adresse

Gruss
PMTheQuick ;)
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: FreakyPenguin am 17. June 2007, 20:05
Ich würde dir weiterhin zu grub raten ;-)

Nim am besten ein Image von LOST:
http://lost-os.ath.cx/nightly_builds/459/nightly.img

Darauf kannst du alle Dateien und Verzeichnisse bis auf "grub" löschen.
Danach brauchst du nur noch den 32-Bit teil von deinem Kernel. Im Linkerfile musst du danach die Adresse so anpassen, dass sie >=0x100000 (>=1mb) ist, und das Ausgabeformat auf elf32-i386 ändern. In deiner kernel32.asm musst du dann noch die Multibootsignatur einfügen. Aber bitte aufpassen, dass sie nicht ausgeführt wird ;-).
65 multiboot_header:
 66 align 4
 67   MULTIBOOT_MAGIC     equ 0x1BADB002
 68   MULTIBOOT_FLAGS     equ 0x03
 69   MULTIBOOT_CHECKSUM  equ -MULTIBOOT_MAGIC-MULTIBOOT_FLAGS
 70
 71   dd MULTIBOOT_MAGIC
 72   dd MULTIBOOT_FLAGS
 73   dd MULTIBOOT_CHECKSUM

Wenn du dann deinen gelinkten Kernel hast, kopierst du ihn auf die Diskette und passt grub/menu.lst an:
Zitat
1 timeout 1
 2 title QuickOS
 3 kernel kernel.bin
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: nooooooooos am 17. June 2007, 20:09
Hmm...hast du denn den Jmp im Bootloader eingefügt?
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: PMTheQuick am 17. June 2007, 20:15
@FreakyPenguin: Ja... Aber ich will es eigentlich so lassen ^^ Und mit Grub, naja, was meint ihr denn dazu? Was is besser? (Mit ihr mein ich die gesamte Community ;) ) Und wie öffnet man so eine .img?

@nooooooooos
Ja... Deinen neuen Code... Also nun:
org 0x7C00

starter:

jmp 07c0h:main_entry

main_entry:
mov ax,cs
mov ds,ax
mov es,ax
cli
mov ss,ax
mov sp,9000h
sti

mov ah,02h
mov al,1
mov cl,2
mov ch,0
mov dl,0
mov dh,0
mov ax,0x9000
mov cx,ax
mov bx,0x0
int 13h

times 510-($-$$) db 0 ;wichtig: Hier die Datei mit so vielen Bytes füllen, bis es genau 510 sind
dw 0aa55h ;Bootsignatur anhängen
kernel:

[OT]Kennst du deine vielen o's in deinem Nick auswendig? ^^ Ich nicht, muss ständig kopieren  :lol:

Gruss
PMTheQuick ;)
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: nooooooooos am 17. June 2007, 20:46
Hehe naja ich schreib einfach was...

Nach dem int-Aufruf solltest du noch ein jmp 0x9000:0x0 hinmachen, damit zum Kernel gesprungen wird.

Da aber der Stack scho n auf 0x9000 ist musst du den noch unbedingt auf irgendwas anderes setzen...z.B. 0x20000

Hast du das  jmp 0x8:0x910000+PMODE schon im Kernel schon zum:  jmp 0x8:0x9000+PMODE geändert?


Gruss
Noooooooooos
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: PMTheQuick am 18. June 2007, 16:21
Hab jetzt mal alles hinzugefügt. Mein aktueller Source is:

bootsec.asm
org 0x7C00

starter:

jmp 07c0h:main_entry

main_entry:
mov ax,cs
mov ds,ax
mov es,ax
cli
mov ss,ax
mov sp,9000h
sti

mov ah,02h
mov al,1
mov cl,2
mov ch,0
mov dl,0
mov dh,0
mov ax,0x9000
mov cs,ax
mov bx,0x0
int 13h
jmp 0x9000:0x0

times 510-($-$$) db 0 ;wichtig: Hier die Datei mit so vielen Bytes füllen, bis es genau 510 sind
dw 0aa55h ;Bootsignatur anhängen
kernel:

kernel16.asm
[BITS 16] ;16 Bit Code erstellen
jmp start ;GDT überspringen

NULL_Desc:
dd 0
dd 0

CODE_Desc:
dw 0xFFFF ;Segmentgröße Byte 0/1
dw 0 ;Segmentbasisadresse Byte 0/1
db 0 ;Segmentbasisadresse Byte 2
db 10011010b ;Zugriffsberechtigungen
db 11001111b ;Zusatz + Segmentgröße Bits 16 - 19
db 0 ;Segmentbasisadresse Byte 3


DATA_Desc:
dw 0xFFFF
dw 0
db 0
db 0x92
db 0xCF
db 0

gdt:
Limit dw 0 ;Größe der GDT (wird später eingetragen)
Base dd 0 ;Adresse der GDT (wird später eingetragen)


start:

cli ;Interrupts ausschalten

mov eax, cs ;EAX auf derzeitiges Codesegment setzen
mov ds, ax ;DS auf Codesegment setzen

shl eax, 4 ;EAX mit 16 multiplizieren (Lineare Adresse
;des Codesegments errechnen)
mov [CODE_Desc+2], ax ;Lineare Adresse des Codesegmentes als
mov [DATA_Desc+2], ax ;Startadresse des Code- und Datendeskriptors
shr eax, 16 ;eintragen
mov [CODE_Desc+4], al
mov [DATA_Desc+4], al

mov eax, cs ;Startadresse der GDT errechnen
shl eax, 4
add eax, NULL_Desc

mov [Base], eax ;Startadresse der GDT eintragen
mov [Limit], WORD gdt - NULL_Desc -1 ;Größe der GDT errechnen und eintragen

lgdt [gdt] ;GDT laden

mov eax, cr0 ;In den Protected Mode schalten,
or eax, 1 ;indem Bit 0 des CR0 Registers auf 1
mov cr0, eax ;gesetzt wird

db 0xea ;FAR-JUMP zum Codesegment
dw PMODE
dw 0x8


[BITS 32] ;32 Bit Code erstellen

PMODE:
mov WORD [CODE_Desc+2], 0 ;Code Segmentstartaddresse auf 0 setzen
mov WORD [DATA_Desc+2], 0 ;Daten Segmentstartadresse auf 0 setzen
mov BYTE [CODE_Desc+4], 0 ;Code Segmentstartaddresse auf 0 setzen
mov BYTE [DATA_Desc+4], 0 ;Daten Segmentstartadresse auf 0 setzen

mov eax, 2 ;Selektor für das Datensegment erstellen
shl eax, 3

mov ds, ax ;Daten- Stack- und Extrasegment mit
mov ss, ax ;Datensegmentdeskriptor laden
mov es, ax
mov eax, 0 ;FS und GS mit Null-Deskriptor laden
mov fs, ax
mov gs, ax
mov esp, 0x1FFFFF ;Stack auf unterhalb der 2 MB Grenze setzen

jmp 0x8:0x09000 + PMODE2 ;Sprung in das "neue" Codesegment

PMODE2:
jmp END ;Zum Ende Springen

times 512-($-$$) db 0; ;Da der Linker sich nicht mit ungeraden
;Dateigrößen verträgt, wird diese Datei auf 512
;gepaddet.

END:

kernel32.asm
[Bits 32]
extern _main
global start
global _EnableA20Gate

start:

call _main

STOP:
jmp STOP

;#######################################################################

Macros.asm
;#######################################################
;Macros für den einfachen Zugriff auf die über den Stack übergebenen Parameter
;ACHTUNG! Diese Macros sind nur bei einem 16-Bit Stack korrekt!

%define Param1 bp+4
%define Param2 bp+6
%define Param3 bp+8
%define Param4 bp+10
%define Param5 bp+12

;#######################################################
;Macros für den einfachen Zugriff auf lokale Variablen innerhalb einer Funktion
;die auf dem Stack erstellt wurden
;ACHTUNG! Diese Macros sind nur bei einem 16-Bit Stack korrekt!

%define Var1 bp-2
%define Var2 bp-4
%define Var3 bp-6
%define Var4 bp-8
%define Var5 bp-10

;#######################################################

link.txt
OUTPUT_FORMAT("binary")
INPUT(kernel32.obj ckernel.obj)
ENTRY(start)
SECTIONS
{
  .text  0x200 : {
    code = .; _code = .; __code = .;
    *(.text)
    . = ALIGN(1);
  }
  .data  : {
    data = .; _data = .; __data = .;
    *(.data)
    . = ALIGN(1);
  }
  .bss  :
  {
    bss = .; _bss = .; __bss = .;
    *(.bss)
    . = ALIGN(1);
  }
  end = .; _end = .; __end = .;
}

Und das geht nicht  :x Bochs:
00001292493i[CPU0 ] WARNING: Encountered an unknown instruction (signalling illegal instruction)
00001292494i[CPU0 ] BxError: instruction with opcode=0xde
00001292494i[CPU0 ] mod was c0, nnn was 3, rm was 6

Wieso nur?

Gruss
PMTheQuick ;)
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: nooooooooos am 18. June 2007, 16:27
Hehe weil du im Bootloader mov cX,ax statt mov cS,ax geschrieben hast...Dann seh ich noch, dass du jmp 0x8:0x9a000 + PMODE2 statt jmp 0x8:0x9000 + PMODE2 schreibst...

Gruss
Noooooooooos
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: PMTheQuick am 18. June 2007, 16:34
Das a hatte ich aufsversehen reingeschrieben ^^ Jetzt hab ich beides oben verbessert. Aber Fehler ist weiterhin da :(

Gruss
PMTheQuick ;)

EDIT: Zu cx statt cs ^^
nenein...dein bootloader ist scho gut...hehe ja ich hab vergessen ein segmentregister kann man ja gar nicht direkt laden...also mov ax,0x9000; mov cx,ax

Gruss
Aber egal ^^ Jeder macht nen Fehler.  :wink: (Nur ich mache mehrere irgendwie  :roll: )
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: nooooooooos am 18. June 2007, 16:43
Ok dann probier mal zu schauen ob der Code überhaupt bis zum Kernel kommt: Einfach dort mal ein JMP $ hinmachen. Wenn der Fehler nicht erscheint kommt er bis dahin...So kannst du schauen wo der Fehler auftritt...

Dann seh ich noch einen Fehler von Mir, bei jmp 0x8:0x9000 + PMODE2 muss dass 0x9000 eine Null mehr haben weil es hier physikalisch ist...


Gruss
Noooooooooos
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: PMTheQuick am 18. June 2007, 16:47
org 0x7C00

starter:

jmp 07c0h:main_entry

main_entry:
mov ax,cs
mov ds,ax
mov es,ax
cli
mov ss,ax
mov sp,9000h
sti

mov ah,02h
mov al,1
mov cl,2
mov ch,0
mov dl,0
mov dh,0
mov ax,0x9000
mov cs,ax
mov bx,0x0
int 13h
jmp $
jmp 0x9000:0x0

times 510-($-$$) db 0 ;wichtig: Hier die Datei mit so vielen Bytes füllen, bis es genau 510 sind
dw 0aa55h ;Bootsignatur anhängen
kernel:

Ergibt weiterhin den selben Fehler... Auch nach kernel: ein jmp $ ergibt weiterhin den selben fehler.. :( Das 9000 zu 90000 habe ich verbessert ;)

Gruss
PMTheQuick :)
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: nooooooooos am 18. June 2007, 16:59
Aumann...ich bin jetzt dann ruhig...auch mov cs,ax im Bootloader stimmt nicht!!! Es muss "ES" sein....

Gruss
Noooooooooos
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: PMTheQuick am 18. June 2007, 17:10
Und weiterhin:

org 0x7C00

starter:

jmp 07c0h:main_entry

main_entry:
mov ax,cs
mov ds,ax
mov es,ax
cli
mov ss,ax
mov sp,9000h
sti

mov ah,02h
mov al,1
mov cl,2
mov ch,0
mov dl,0
mov dh,0
mov ax,0x9000
mov es,ax
mov bx,0x0
int 13h
jmp 0x9000:0x0

times 510-($-$$) db 0 ;wichtig: Hier die Datei mit so vielen Bytes füllen, bis es genau 510 sind
dw 0aa55h ;Bootsignatur anhängen
kernel:

Und nein, sag ruhig weiter ^^ Auch wenn manchmal was nicht stimmt, du bist dafür da und hilfst mir auch gut ;)

Gruss
PMTheQuick :)
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: nooooooooos am 18. June 2007, 17:14
Geht der Code erst wieder, wenn du das jmp $ vor das jmp 0x9000:0x0 setzt?

Du darfst mich sonst auch gerne im MSN, IRQ ansprechen...das könnte noch ne weile dauern...

Gruss
Noooooooooos
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: MNemo am 18. June 2007, 17:57
ich hab hier mal schnell alles überflogen. (und hoffe das ich nichts wichtiges übersehen hab) mir ist nur schon gleich am Anfang aufgefallen das im BootSector ein JMP kernel gefehlt hat

naja

jetzt ist das ja nicht mehr stand der Dinge und mir fällt auf

org 0x7c00
starter:
jmp [b]0x07c0[/b]: main_entry
main_entry

Das ORG legt aber doch die Basis des Offsets fest, die nur bei 0x7c00 liegt,
wenn das segment 0x00 benutzt wird.

es muss also entweder zu 0x0000: main_enry gejumped werden und das org beibehalten oder der jump beibehalten und dafür org 0x0000 benutzt werden
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: PMTheQuick am 18. June 2007, 18:39
Ok. Ich bedanke mich hier mal bei dir M. Nemo, und ganz gross bei nooooooooos  :-) Das einzige Problem ist jetzt noch der C-Kernel, der nichts ausgibt ^^ 0xA8000,0xA0000 und 0xB000 geht nicht  :-( Welche Adresse ist das? Und nochmals viel viel mals Danke an nooooooooos mit seiner guten & netten Unterstützung in ICQ :)

Gruss
PMTheQuick :)
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: MNemo am 18. June 2007, 18:46
RM: 0xB800:0x000
PM Lineare Adresse: 0xb8000
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: PMTheQuick am 18. June 2007, 18:55
Das geht leider auch nicht... Kommt nur Booting from Floppy ^^ Sonst nichts ^^ Is irgendetwas falsch?

Gruss
PMTheQuick ;)
Titel: Re: Wieso rebootet bei diesem Code Bochs?
Beitrag von: Svenska am 19. June 2007, 02:16
Zum Code sage ich jetzt mal nichts, sondern zu den Disketten-Images.
Die sind ein sektorgenaues Abbild einer Diskette und enthalten somit alle Daten inklusive den Verwaltungsinformationen des Dateisystems.

VFD wurde dir ja schon gegeben, ich persönlich benutze WinImage (http://www.winimage.com/) (ist aber Shareware). Das ist jedenfalls sehr bequem und kann die Disketten beim Brennen gleich mitformatieren.

"Brennen" (also auf Disketten schreiben) tue ich die Images mit dem Linux-Tool dd , welches es auch für win32 (http://www.chrysocome.net/dd) gibt. Das ist jedenfalls schneller als WinImage, wenn die Diskette fehlerfrei ist und durch die variable Blockgröße auch anderweitig geeignet (ich erzeuge damit z.B. HDD-Images).

Mit TeeJays Bootloader habe ich noch nicht gearbeitet, aber gehört, dass er Fehler beinhaltet und nicht überall funktioniert. Grub mag ich persönlich nicht, aber das ist Ansichtssache. Nimm es trotzdem. :-)

Gruß,
Svenska